guiguitant théo / lorawan-master

Dependencies:   mbed

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 }
01122 
01123 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
01124 {
01125     LoRaMacHeader_t  macHdr;
01126     LoRaMacFrameCtrl_t  fCtrl;
01127     bool skipIndication = false;
01128 
01129     uint8_t pktHeaderLen = 0;
01130     uint32_t address = 0;
01131     uint8_t appPayloadStartIndex = 0;
01132     uint8_t port = 0xFF;
01133     uint8_t frameLen = 0;
01134     uint32_t mic = 0;
01135     uint32_t micRx = 0;
01136 
01137     uint16_t sequenceCounter = 0;
01138     uint16_t sequenceCounterPrev = 0;
01139     uint16_t sequenceCounterDiff = 0;
01140     uint32_t downLinkCounter = 0;
01141 
01142     MulticastParams_t  *curMulticastParams = NULL;
01143     uint8_t *nwkSKey = LoRaMacNwkSKey;
01144     uint8_t *appSKey = LoRaMacAppSKey;
01145 
01146     uint8_t multicast = 0;
01147 
01148     bool isMicOk = false;
01149 
01150     McpsConfirm.AckReceived  = false;
01151     McpsIndication.Rssi  = rssi;
01152     McpsIndication.Snr  = snr;
01153     McpsIndication.RxSlot  = RxSlot;
01154     McpsIndication.Port  = 0;
01155     McpsIndication.Multicast  = 0;
01156     McpsIndication.FramePending  = 0;
01157     McpsIndication.Buffer  = NULL;
01158     McpsIndication.BufferSize  = 0;
01159     McpsIndication.RxData  = false;
01160     McpsIndication.AckReceived  = false;
01161     McpsIndication.DownLinkCounter  = 0;
01162     McpsIndication.McpsIndication  = MCPS_UNCONFIRMED ;
01163 
01164     Radio .Sleep( );
01165     TimerStop( &RxWindowTimer2 );
01166 
01167     macHdr.Value  = payload[pktHeaderLen++];
01168 
01169     switch( macHdr.Bits.MType  )
01170     {
01171         case FRAME_TYPE_JOIN_ACCEPT :
01172             if( IsLoRaMacNetworkJoined == true )
01173             {
01174                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
01175                 PrepareRxDoneAbort( );
01176                 return;
01177             }
01178             LoRaMacJoinDecrypt ( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );
01179 
01180             LoRaMacRxPayload[0] = macHdr.Value ;
01181 
01182             LoRaMacJoinComputeMic ( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic );
01183 
01184             micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN];
01185             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 );
01186             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 );
01187             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 );
01188 
01189             if( micRx == mic )
01190             {
01191                 LoRaMacJoinComputeSKeys ( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );
01192 
01193                 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4];
01194                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 );
01195                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 );
01196 
01197                 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7];
01198                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 );
01199                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 );
01200                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
01201 
01202                 // DLSettings
01203                 LoRaMacParams.Rx1DrOffset  = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
01204                 LoRaMacParams.Rx2Channel .Datarate  = LoRaMacRxPayload[11] & 0x0F;
01205 
01206                 // RxDelay
01207                 LoRaMacParams.ReceiveDelay1  = ( LoRaMacRxPayload[12] & 0x0F );
01208                 if( LoRaMacParams.ReceiveDelay1  == 0 )
01209                 {
01210                     LoRaMacParams.ReceiveDelay1  = 1;
01211                 }
01212                 LoRaMacParams.ReceiveDelay1  *= 1e3;
01213                 LoRaMacParams.ReceiveDelay2  = LoRaMacParams.ReceiveDelay1  + 1e3;
01214 
01215 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
01216                 //CFList
01217                 if( ( size - 1 ) > 16 )
01218                 {
01219                     ChannelParams_t  param;
01220                     param.DrRange .Value  = ( DR_5 << 4 ) | DR_0;
01221 
01222                     LoRaMacState |= LORAMAC_TX_CONFIG;
01223                     for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
01224                     {
01225                         param.Frequency  = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
01226                         if( param.Frequency  != 0 )
01227                         {
01228                             LoRaMacChannelAdd( i, param );
01229                         }
01230                         else
01231                         {
01232                             LoRaMacChannelRemove( i );
01233                         }
01234                     }
01235                     LoRaMacState &= ~LORAMAC_TX_CONFIG;
01236                 }
01237 #endif
01238                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01239                 IsLoRaMacNetworkJoined = true;
01240                 LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
01241             }
01242             else
01243             {
01244                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL ;
01245             }
01246             break;
01247         case FRAME_TYPE_DATA_CONFIRMED_DOWN :
01248         case FRAME_TYPE_DATA_UNCONFIRMED_DOWN :
01249             {
01250                 address = payload[pktHeaderLen++];
01251                 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
01252                 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
01253                 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 );
01254 
01255                 if( address != LoRaMacDevAddr )
01256                 {
01257                     curMulticastParams = MulticastChannels;
01258                     while( curMulticastParams != NULL )
01259                     {
01260                         if( address == curMulticastParams->Address  )
01261                         {
01262                             multicast = 1;
01263                             nwkSKey = curMulticastParams->NwkSKey ;
01264                             appSKey = curMulticastParams->AppSKey ;
01265                             downLinkCounter = curMulticastParams->DownLinkCounter ;
01266                             break;
01267                         }
01268                         curMulticastParams = curMulticastParams->Next ;
01269                     }
01270                     if( multicast == 0 )
01271                     {
01272                         // We are not the destination of this frame.
01273                         McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ;
01274                         PrepareRxDoneAbort( );
01275                         return;
01276                     }
01277                 }
01278                 else
01279                 {
01280                     multicast = 0;
01281                     nwkSKey = LoRaMacNwkSKey;
01282                     appSKey = LoRaMacAppSKey;
01283                     downLinkCounter = DownLinkCounter;
01284                 }
01285 
01286                 fCtrl.Value  = payload[pktHeaderLen++];
01287 
01288                 sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
01289                 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
01290 
01291                 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen ;
01292 
01293                 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN];
01294                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 );
01295                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 );
01296                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 );
01297 
01298                 sequenceCounterPrev = ( uint16_t )downLinkCounter;
01299                 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
01300 
01301                 if( sequenceCounterDiff < ( 1 << 15 ) )
01302                 {
01303                     downLinkCounter += sequenceCounterDiff;
01304                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
01305                     if( micRx == mic )
01306                     {
01307                         isMicOk = true;
01308                     }
01309                 }
01310                 else
01311                 {
01312                     // check for sequence roll-over
01313                     uint32_t  downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
01314                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
01315                     if( micRx == mic )
01316                     {
01317                         isMicOk = true;
01318                         downLinkCounter = downLinkCounterTmp;
01319                     }
01320                 }
01321 
01322                 // Check for a the maximum allowed counter difference
01323                 if( sequenceCounterDiff >= MAX_FCNT_GAP )
01324                 {
01325                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS ;
01326                     McpsIndication.DownLinkCounter  = downLinkCounter;
01327                     PrepareRxDoneAbort( );
01328                     return;
01329                 }
01330 
01331                 if( isMicOk == true )
01332                 {
01333                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01334                     McpsIndication.Multicast  = multicast;
01335                     McpsIndication.FramePending  = fCtrl.Bits.FPending ;
01336                     McpsIndication.Buffer  = NULL;
01337                     McpsIndication.BufferSize  = 0;
01338                     McpsIndication.DownLinkCounter  = downLinkCounter;
01339 
01340                     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01341 
01342                     AdrAckCounter = 0;
01343                     MacCommandsBufferToRepeatIndex = 0;
01344 
01345                     // Update 32 bits downlink counter
01346                     if( multicast == 1 )
01347                     {
01348                         McpsIndication.McpsIndication  = MCPS_MULTICAST ;
01349 
01350                         if( ( curMulticastParams->DownLinkCounter  == downLinkCounter ) &&
01351                             ( curMulticastParams->DownLinkCounter  != 0 ) )
01352                         {
01353                             McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ;
01354                             McpsIndication.DownLinkCounter  = downLinkCounter;
01355                             PrepareRxDoneAbort( );
01356                             return;
01357                         }
01358                         curMulticastParams->DownLinkCounter  = downLinkCounter;
01359                     }
01360                     else
01361                     {
01362                         if( macHdr.Bits.MType  == FRAME_TYPE_DATA_CONFIRMED_DOWN  )
01363                         {
01364                             SrvAckRequested = true;
01365                             McpsIndication.McpsIndication  = MCPS_CONFIRMED ;
01366 
01367                             if( ( DownLinkCounter == downLinkCounter ) &&
01368                                 ( DownLinkCounter != 0 ) )
01369                             {
01370                                 // Duplicated confirmed downlink. Skip indication.
01371                                 // In this case, the MAC layer shall accept the MAC commands
01372                                 // which are included in the downlink retransmission.
01373                                 // It should not provide the same frame to the application
01374                                 // layer again.
01375                                 skipIndication = true;
01376                             }
01377                         }
01378                         else
01379                         {
01380                             SrvAckRequested = false;
01381                             McpsIndication.McpsIndication  = MCPS_UNCONFIRMED ;
01382 
01383                             if( ( DownLinkCounter == downLinkCounter ) &&
01384                                 ( DownLinkCounter != 0 ) )
01385                             {
01386                                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ;
01387                                 McpsIndication.DownLinkCounter  = downLinkCounter;
01388                                 PrepareRxDoneAbort( );
01389                                 return;
01390                             }
01391                         }
01392                         DownLinkCounter = downLinkCounter;
01393                     }
01394 
01395                     // This must be done before parsing the payload and the MAC commands.
01396                     // We need to reset the MacCommandsBufferIndex here, since we need
01397                     // to take retransmissions and repititions into account. Error cases
01398                     // will be handled in function OnMacStateCheckTimerEvent.
01399                     if( McpsConfirm.McpsRequest  == MCPS_CONFIRMED  )
01400                     {
01401                         if( fCtrl.Bits.Ack  == 1 )
01402                         {// Reset MacCommandsBufferIndex when we have received an ACK.
01403                             MacCommandsBufferIndex = 0;
01404                         }
01405                     }
01406                     else
01407                     {// Reset the variable if we have received any valid frame.
01408                         MacCommandsBufferIndex = 0;
01409                     }
01410 
01411                     // Process payload and MAC commands
01412                     if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
01413                     {
01414                         port = payload[appPayloadStartIndex++];
01415                         frameLen = ( size - 4 ) - appPayloadStartIndex;
01416 
01417                         McpsIndication.Port  = port;
01418 
01419                         if( port == 0 )
01420                         {
01421                             // Only allow frames which do not have fOpts
01422                             if( fCtrl.Bits.FOptsLen  == 0 )
01423                             {
01424                                 LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex,
01425                                                        frameLen,
01426                                                        nwkSKey,
01427                                                        address,
01428                                                        DOWN_LINK,
01429                                                        downLinkCounter,
01430                                                        LoRaMacRxPayload );
01431 
01432                                 // Decode frame payload MAC commands
01433                                 ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
01434                             }
01435                             else
01436                             {
01437                                 skipIndication = true;
01438                             }
01439                         }
01440                         else
01441                         {
01442                             if( fCtrl.Bits.FOptsLen  > 0 )
01443                             {
01444                                 // Decode Options field MAC commands. Omit the fPort.
01445                                 ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr );
01446                             }
01447 
01448                             LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex,
01449                                                    frameLen,
01450                                                    appSKey,
01451                                                    address,
01452                                                    DOWN_LINK,
01453                                                    downLinkCounter,
01454                                                    LoRaMacRxPayload );
01455 
01456                             if( skipIndication == false )
01457                             {
01458                                 McpsIndication.Buffer  = LoRaMacRxPayload;
01459                                 McpsIndication.BufferSize  = frameLen;
01460                                 McpsIndication.RxData  = true;
01461                             }
01462                         }
01463                     }
01464                     else
01465                     {
01466                         if( fCtrl.Bits.FOptsLen  > 0 )
01467                         {
01468                             // Decode Options field MAC commands
01469                             ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
01470                         }
01471                     }
01472 
01473                     if( skipIndication == false )
01474                     {
01475                         // Check if the frame is an acknowledgement
01476                         if( fCtrl.Bits.Ack  == 1 )
01477                         {
01478                             McpsConfirm.AckReceived  = true;
01479                             McpsIndication.AckReceived  = true;
01480 
01481                             // Stop the AckTimeout timer as no more retransmissions
01482                             // are needed.
01483                             TimerStop( &AckTimeoutTimer );
01484                         }
01485                         else
01486                         {
01487                             McpsConfirm.AckReceived  = false;
01488 
01489                             if( AckTimeoutRetriesCounter > AckTimeoutRetries )
01490                             {
01491                                 // Stop the AckTimeout timer as no more retransmissions
01492                                 // are needed.
01493                                 TimerStop( &AckTimeoutTimer );
01494                             }
01495                         }
01496                     }
01497                     // Provide always an indication, skip the callback to the user application,
01498                     // in case of a confirmed downlink retransmission.
01499                     LoRaMacFlags.Bits.McpsInd  = 1;
01500                     LoRaMacFlags.Bits.McpsIndSkip  = skipIndication;
01501                 }
01502                 else
01503                 {
01504                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ;
01505 
01506                     PrepareRxDoneAbort( );
01507                     return;
01508                 }
01509             }
01510             break;
01511         case FRAME_TYPE_PROPRIETARY :
01512             {
01513                 memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size );
01514 
01515                 McpsIndication.McpsIndication  = MCPS_PROPRIETARY ;
01516                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01517                 McpsIndication.Buffer  = LoRaMacRxPayload;
01518                 McpsIndication.BufferSize  = size - pktHeaderLen;
01519 
01520                 LoRaMacFlags.Bits.McpsInd  = 1;
01521                 break;
01522             }
01523         default:
01524             McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
01525             PrepareRxDoneAbort( );
01526             break;
01527     }
01528     LoRaMacFlags.Bits.MacDone  = 1;
01529 
01530     // Trig OnMacCheckTimerEvent call as soon as possible
01531     TimerSetValue( &MacStateCheckTimer, 1 );
01532     TimerStart( &MacStateCheckTimer );
01533 }
01534 
01535 static void OnRadioTxTimeout( void )
01536 {
01537     if( LoRaMacDeviceClass != CLASS_C  )
01538     {
01539         Radio .Sleep( );
01540     }
01541     else
01542     {
01543         OnRxWindow2TimerEvent( );
01544     }
01545 
01546     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ;
01547     MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ;
01548     LoRaMacFlags.Bits.MacDone  = 1;
01549 }
01550 
01551 static void OnRadioRxError( void )
01552 {
01553     if( LoRaMacDeviceClass != CLASS_C  )
01554     {
01555         Radio .Sleep( );
01556     }
01557     else
01558     {
01559         OnRxWindow2TimerEvent( );
01560     }
01561 
01562     if( RxSlot == 0 )
01563     {
01564         if( NodeAckRequested == true )
01565         {
01566             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ;
01567         }
01568         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ;
01569 
01570         if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay )
01571         {
01572             LoRaMacFlags.Bits.MacDone  = 1;
01573         }
01574     }
01575     else
01576     {
01577         if( NodeAckRequested == true )
01578         {
01579             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ;
01580         }
01581         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ;
01582         LoRaMacFlags.Bits.MacDone  = 1;
01583     }
01584 }
01585 
01586 static void OnRadioRxTimeout( void )
01587 {
01588     if( LoRaMacDeviceClass != CLASS_C  )
01589     {
01590         Radio .Sleep( );
01591     }
01592     else
01593     {
01594         OnRxWindow2TimerEvent( );
01595     }
01596 
01597     if( RxSlot == 1 )
01598     {
01599         if( NodeAckRequested == true )
01600         {
01601             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ;
01602         }
01603         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ;
01604         LoRaMacFlags.Bits.MacDone  = 1;
01605     }
01606 }
01607 
01608 static void OnMacStateCheckTimerEvent( void )
01609 {
01610     TimerStop( &MacStateCheckTimer );
01611     bool txTimeout = false;
01612 
01613     if( LoRaMacFlags.Bits.MacDone  == 1 )
01614     {
01615         if( ( LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT )
01616         {
01617             LoRaMacState &= ~LORAMAC_RX_ABORT;
01618             LoRaMacState &= ~LORAMAC_TX_RUNNING;
01619         }
01620 
01621         if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq  == 1 ) ) )
01622         {
01623             if( ( McpsConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT  ) ||
01624                 ( MlmeConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT  ) )
01625             {
01626                 // Stop transmit cycle due to tx timeout.
01627                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01628                 MacCommandsBufferIndex = 0;
01629                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01630                 McpsConfirm.AckReceived  = false;
01631                 McpsConfirm.TxTimeOnAir  = 0;
01632                 txTimeout = true;
01633             }
01634         }
01635 
01636         if( ( NodeAckRequested == false ) && ( txTimeout == false ) )
01637         {
01638             if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq  == 1 ) ) )
01639             {
01640                 if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) && ( MlmeConfirm.MlmeRequest  == MLME_JOIN  ) )
01641                 {// Procedure for the join request
01642                     MlmeConfirm.NbRetries  = JoinRequestTrials;
01643 
01644                     if( MlmeConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_OK  )
01645                     {// Node joined successfully
01646                         UpLinkCounter = 0;
01647                         ChannelsNbRepCounter = 0;
01648                         LoRaMacState &= ~LORAMAC_TX_RUNNING;
01649                     }
01650                     else
01651                     {
01652                         if( JoinRequestTrials >= MaxJoinRequestTrials )
01653                         {
01654                             LoRaMacState &= ~LORAMAC_TX_RUNNING;
01655                         }
01656                         else
01657                         {
01658                             LoRaMacFlags.Bits.MacDone  = 0;
01659                             // Sends the same frame again
01660                             OnTxDelayedTimerEvent( );
01661                         }
01662                     }
01663                 }
01664                 else
01665                 {// Procedure for all other frames
01666                     if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep  ) || ( LoRaMacFlags.Bits.McpsInd  == 1 ) )
01667                     {
01668                         if( LoRaMacFlags.Bits.McpsInd  == 0 )
01669                         {   // Maximum repititions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter.
01670                             // Only process the case when the MAC did not receive a downlink.
01671                             MacCommandsBufferIndex = 0;
01672                             AdrAckCounter++;
01673                         }
01674 
01675                         ChannelsNbRepCounter = 0;
01676 
01677                         if( IsUpLinkCounterFixed == false )
01678                         {
01679                             UpLinkCounter++;
01680                         }
01681 
01682                         LoRaMacState &= ~LORAMAC_TX_RUNNING;
01683                     }
01684                     else
01685                     {
01686                         LoRaMacFlags.Bits.MacDone  = 0;
01687                         // Sends the same frame again
01688                         OnTxDelayedTimerEvent( );
01689                     }
01690                 }
01691             }
01692         }
01693 
01694         if( LoRaMacFlags.Bits.McpsInd  == 1 )
01695         {// Procedure if we received a frame
01696             if( ( McpsConfirm.AckReceived  == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
01697             {
01698                 AckTimeoutRetry = false;
01699                 NodeAckRequested = false;
01700                 if( IsUpLinkCounterFixed == false )
01701                 {
01702                     UpLinkCounter++;
01703                 }
01704                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01705 
01706                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01707             }
01708         }
01709 
01710         if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) )
01711         {// Retransmissions procedure for confirmed uplinks
01712             AckTimeoutRetry = false;
01713             if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) )
01714             {
01715                 AckTimeoutRetriesCounter++;
01716 
01717                 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
01718                 {
01719                     LoRaMacParams.ChannelsDatarate  = MAX( LoRaMacParams.ChannelsDatarate  - 1, LORAMAC_TX_MIN_DATARATE );
01720                 }
01721                 // Try to send the frame again
01722                 if( ScheduleTx( ) == LORAMAC_STATUS_OK  )
01723                 {
01724                     LoRaMacFlags.Bits.MacDone  = 0;
01725                 }
01726                 else
01727                 {
01728                     // The DR is not applicable for the payload size
01729                     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ;
01730 
01731                     MacCommandsBufferIndex = 0;
01732                     LoRaMacState &= ~LORAMAC_TX_RUNNING;
01733                     NodeAckRequested = false;
01734                     McpsConfirm.AckReceived  = false;
01735                     McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01736                     McpsConfirm.Datarate  = LoRaMacParams.ChannelsDatarate ;
01737                     if( IsUpLinkCounterFixed == false )
01738                     {
01739                         UpLinkCounter++;
01740                     }
01741                 }
01742             }
01743             else
01744             {
01745 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01746                 // Re-enable default channels LC1, LC2, LC3
01747                 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
01748 #elif defined( USE_BAND_470 )
01749                 // Re-enable default channels
01750                 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01751 #elif defined( USE_BAND_915 )
01752                 // Re-enable default channels
01753                 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01754 #elif defined( USE_BAND_915_HYBRID )
01755                 // Re-enable default channels
01756                 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
01757 #else
01758     #error "Please define a frequency band in the compiler options."
01759 #endif
01760                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01761 
01762                 MacCommandsBufferIndex = 0;
01763                 NodeAckRequested = false;
01764                 McpsConfirm.AckReceived  = false;
01765                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01766                 if( IsUpLinkCounterFixed == false )
01767                 {
01768                     UpLinkCounter++;
01769                 }
01770             }
01771         }
01772     }
01773     // Handle reception for Class B and Class C
01774     if( ( LoRaMacState & LORAMAC_RX ) == LORAMAC_RX )
01775     {
01776         LoRaMacState &= ~LORAMAC_RX;
01777     }
01778     if( LoRaMacState == LORAMAC_IDLE )
01779     {
01780         if( LoRaMacFlags.Bits.McpsReq  == 1 )
01781         {
01782             LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm );
01783             LoRaMacFlags.Bits.McpsReq  = 0;
01784         }
01785 
01786         if( LoRaMacFlags.Bits.MlmeReq  == 1 )
01787         {
01788             LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm );
01789             LoRaMacFlags.Bits.MlmeReq  = 0;
01790         }
01791 
01792         // Procedure done. Reset variables.
01793         LoRaMacFlags.Bits.MacDone  = 0;
01794     }
01795     else
01796     {
01797         // Operation not finished restart timer
01798         TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
01799         TimerStart( &MacStateCheckTimer );
01800     }
01801 
01802     if( LoRaMacFlags.Bits.McpsInd  == 1 )
01803     {
01804         if( LoRaMacDeviceClass == CLASS_C  )
01805         {// Activate RX2 window for Class C
01806             OnRxWindow2TimerEvent( );
01807         }
01808         if( LoRaMacFlags.Bits.McpsIndSkip  == 0 )
01809         {
01810             LoRaMacPrimitives->MacMcpsIndication( &McpsIndication );
01811         }
01812         LoRaMacFlags.Bits.McpsIndSkip  = 0;
01813         LoRaMacFlags.Bits.McpsInd  = 0;
01814     }
01815 }
01816 
01817 static void OnTxDelayedTimerEvent( void )
01818 {
01819     LoRaMacHeader_t  macHdr;
01820     LoRaMacFrameCtrl_t  fCtrl;
01821 
01822     TimerStop( &TxDelayedTimer );
01823     LoRaMacState &= ~LORAMAC_TX_DELAYED;
01824 
01825     if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) && ( MlmeConfirm.MlmeRequest  == MLME_JOIN  ) )
01826     {
01827         ResetMacParameters( );
01828         // Add a +1, since we start to count from 0
01829         LoRaMacParams.ChannelsDatarate  = AlternateDatarate( JoinRequestTrials + 1 );
01830 
01831         macHdr.Value  = 0;
01832         macHdr.Bits.MType  = FRAME_TYPE_JOIN_REQ ;
01833 
01834         fCtrl.Value  = 0;
01835         fCtrl.Bits.Adr  = AdrCtrlOn;
01836 
01837         /* In case of join request retransmissions, the stack must prepare
01838          * the frame again, because the network server keeps track of the random
01839          * LoRaMacDevNonce values to prevent reply attacks. */
01840         PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 );
01841     }
01842 
01843     ScheduleTx( );
01844 }
01845 
01846 static void OnRxWindow1TimerEvent( void )
01847 {
01848     TimerStop( &RxWindowTimer1 );
01849     RxSlot = 0;
01850 
01851     if( LoRaMacDeviceClass == CLASS_C  )
01852     {
01853         Radio .Standby( );
01854     }
01855 
01856 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01857     RxWindowSetup( Channels[Channel].Frequency, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01858 #elif defined( USE_BAND_470 )
01859     RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 48 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01860 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
01861     RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 8 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01862 #else
01863     #error "Please define a frequency band in the compiler options."
01864 #endif
01865 }
01866 
01867 static void OnRxWindow2TimerEvent( void )
01868 {
01869     bool rxContinuousMode = false;
01870 
01871     TimerStop( &RxWindowTimer2 );
01872 
01873     if( LoRaMacDeviceClass == CLASS_C  )
01874     {
01875         rxContinuousMode = true;
01876     }
01877     if( RxWindowSetup( LoRaMacParams.Rx2Channel .Frequency , RxWindowsParams[1].Datarate, RxWindowsParams[1].Bandwidth, RxWindowsParams[1].RxWindowTimeout, rxContinuousMode ) == true )
01878     {
01879         RxSlot = 1;
01880     }
01881 }
01882 
01883 static void OnAckTimeoutTimerEvent( void )
01884 {
01885     TimerStop( &AckTimeoutTimer );
01886 
01887     if( NodeAckRequested == true )
01888     {
01889         AckTimeoutRetry = true;
01890         LoRaMacState &= ~LORAMAC_ACK_REQ;
01891     }
01892     if( LoRaMacDeviceClass == CLASS_C  )
01893     {
01894         LoRaMacFlags.Bits.MacDone  = 1;
01895     }
01896 }
01897 
01898 static bool SetNextChannel( TimerTime_t* time )
01899 {
01900     uint8_t nbEnabledChannels = 0;
01901     uint8_t delayTx = 0;
01902     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
01903     TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
01904 
01905     memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
01906 
01907 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01908     if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
01909     { // Restore default channels
01910         memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask , 8 );
01911     }
01912     if( ( LoRaMacParams.ChannelsDatarate  >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
01913     { // Make sure, that the channels are activated
01914         ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask [4];
01915     }
01916 #elif defined( USE_BAND_470 )
01917     if( ( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 ) &&
01918         ( CountBits( LoRaMacParams.ChannelsMask [1], 16 ) == 0 ) &&
01919         ( CountBits( LoRaMacParams.ChannelsMask [2], 16 ) == 0 ) &&
01920         ( CountBits( LoRaMacParams.ChannelsMask [3], 16 ) == 0 ) &&
01921         ( CountBits( LoRaMacParams.ChannelsMask [4], 16 ) == 0 ) &&
01922         ( CountBits( LoRaMacParams.ChannelsMask [5], 16 ) == 0 ) )
01923     {
01924         memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01925     }
01926 #else
01927     if( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 )
01928     {
01929         // Re-enable default channels, if no channel is enabled
01930         LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
01931     }
01932 #endif
01933 
01934     // Update Aggregated duty cycle
01935     if( AggregatedTimeOff <= TimerGetElapsedTime( AggregatedLastTxDoneTime ) )
01936     {
01937         AggregatedTimeOff = 0;
01938 
01939         // Update bands Time OFF
01940         for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ )
01941         {
01942             if( ( IsLoRaMacNetworkJoined == false ) || ( DutyCycleOn == true ) )
01943             {
01944                 if( Bands[i].TimeOff <= TimerGetElapsedTime( Bands[i].LastTxDoneTime ) )
01945                 {
01946                     Bands[i].TimeOff  = 0;
01947                 }
01948                 if( Bands[i].TimeOff != 0 )
01949                 {
01950                     nextTxDelay = MIN( Bands[i].TimeOff - TimerGetElapsedTime( Bands[i].LastTxDoneTime ), nextTxDelay );
01951                 }
01952             }
01953             else
01954             {
01955                 if( DutyCycleOn == false )
01956                 {
01957                     Bands[i].TimeOff  = 0;
01958                 }
01959             }
01960         }
01961 
01962         // Search how many channels are enabled
01963         for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
01964         {
01965             for( uint8_t j = 0; j < 16; j++ )
01966             {
01967 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01968                 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 )
01969 #else
01970                 if( ( LoRaMacParams.ChannelsMask [k] & ( 1 << j ) ) != 0 )
01971 #endif
01972                 {
01973                     if( Channels[i + j].Frequency == 0 )
01974                     { // Check if the channel is enabled
01975                         continue;
01976                     }
01977 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 )
01978                     if( IsLoRaMacNetworkJoined == false )
01979                     {
01980                         if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 )
01981                         {
01982                             continue;
01983                         }
01984                     }
01985 #endif
01986                     if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate  ) &&
01987                           ( LoRaMacParams.ChannelsDatarate  <= Channels[i + j].DrRange .Fields.Max  ) ) == false )
01988                     { // Check if the current channel selection supports the given datarate
01989                         continue;
01990                     }
01991                     if( Bands[Channels[i + j].Band].TimeOff > 0 )
01992                     { // Check if the band is available for transmission
01993                         delayTx++;
01994                         continue;
01995                     }
01996                     enabledChannels[nbEnabledChannels++] = i + j;
01997                 }
01998             }
01999         }
02000     }
02001     else
02002     {
02003         delayTx++;
02004         nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime( AggregatedLastTxDoneTime );
02005     }
02006 
02007     if( nbEnabledChannels > 0 )
02008     {
02009         Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
02010 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02011         if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) )
02012         {
02013             DisableChannelInMask( Channel, ChannelsMaskRemaining );
02014         }
02015 #endif
02016         *time = 0;
02017         return true;
02018     }
02019     else
02020     {
02021         if( delayTx > 0 )
02022         {
02023             // Delay transmission due to AggregatedTimeOff or to a band time off
02024             *time = nextTxDelay;
02025             return true;
02026         }
02027         // Datarate not supported by any channel
02028         *time = 0;
02029         return false;
02030     }
02031 }
02032 
02033 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
02034 {
02035     uint8_t downlinkDatarate = Datarates[datarate];
02036     RadioModems_t modem;
02037 
02038     if( Radio .GetStatus( ) == RF_IDLE )
02039     {
02040         Radio .SetChannel( freq );
02041 
02042         // Store downlink datarate
02043         McpsIndication.RxDatarate  = ( uint8_t ) datarate;
02044 
02045 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02046         if( datarate == DR_7 )
02047         {
02048             modem = MODEM_FSK;
02049             Radio .SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, timeout, false, 0, true, 0, 0, false, rxContinuous );
02050         }
02051         else
02052         {
02053             modem = MODEM_LORA;
02054             Radio .SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02055         }
02056 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02057         modem = MODEM_LORA;
02058         Radio .SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02059 #endif
02060 
02061         if( RepeaterSupport == true )
02062         {
02063             Radio .SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
02064         }
02065         else
02066         {
02067             Radio .SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
02068         }
02069 
02070         if( rxContinuous == false )
02071         {
02072             Radio .Rx( LoRaMacParams.MaxRxWindow  );
02073         }
02074         else
02075         {
02076             Radio .Rx( 0 ); // Continuous mode
02077         }
02078         return true;
02079     }
02080     return false;
02081 }
02082 
02083 static bool Rx2FreqInRange( uint32_t freq )
02084 {
02085 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02086     if( Radio .CheckRfFrequency( freq ) == true )
02087 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02088     if( ( Radio .CheckRfFrequency( freq ) == true ) &&
02089         ( freq >= LORAMAC_FIRST_RX1_CHANNEL ) &&
02090         ( freq <= LORAMAC_LAST_RX1_CHANNEL ) &&
02091         ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX1_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX1_CHANNEL ) == 0 ) )
02092 #endif
02093     {
02094         return true;
02095     }
02096     return false;
02097 }
02098 
02099 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
02100 {
02101     uint16_t maxN = 0;
02102     uint16_t payloadSize = 0;
02103 
02104     // Get the maximum payload length
02105     if( RepeaterSupport == true )
02106     {
02107         maxN = MaxPayloadOfDatarateRepeater[datarate];
02108     }
02109     else
02110     {
02111         maxN = MaxPayloadOfDatarate[datarate];
02112     }
02113 
02114     // Calculate the resulting payload size
02115     payloadSize = ( lenN + fOptsLen );
02116 
02117     // Validation of the application payload size
02118     if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) )
02119     {
02120         return true;
02121     }
02122     return false;
02123 }
02124 
02125 static uint8_t CountBits( uint16_t mask, uint8_t nbBits )
02126 {
02127     uint8_t nbActiveBits = 0;
02128 
02129     for( uint8_t j = 0; j < nbBits; j++ )
02130     {
02131         if( ( mask & ( 1 << j ) ) == ( 1 << j ) )
02132         {
02133             nbActiveBits++;
02134         }
02135     }
02136     return nbActiveBits;
02137 }
02138 
02139 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02140 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask )
02141 {
02142     uint8_t nb125kHzChannels = 0;
02143 
02144     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
02145     {
02146         nb125kHzChannels += CountBits( channelsMask[k], 16 );
02147     }
02148 
02149     return nb125kHzChannels;
02150 }
02151 
02152 #if defined( USE_BAND_915_HYBRID )
02153 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask )
02154 {
02155     uint16_t blockMask = mask;
02156 
02157     for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 )
02158     {
02159         channelsMask[i] = 0;
02160         if( ( blockMask & ( 1 << j ) ) != 0 )
02161         {
02162             channelsMask[i] |= 0x00FF;
02163         }
02164         if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 )
02165         {
02166             channelsMask[i] |= 0xFF00;
02167         }
02168     }
02169     channelsMask[4] = blockMask;
02170     channelsMask[5] = 0x0000;
02171 }
02172 
02173 static bool ValidateChannelMask( uint16_t* channelsMask )
02174 {
02175     bool chanMaskState = false;
02176     uint16_t block1 = 0;
02177     uint16_t block2 = 0;
02178     uint8_t index = 0;
02179 
02180     for( uint8_t i = 0; i < 4; i++ )
02181     {
02182         block1 = channelsMask[i] & 0x00FF;
02183         block2 = channelsMask[i] & 0xFF00;
02184 
02185         if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) )
02186         {
02187             channelsMask[i] &= block1;
02188             channelsMask[4] = 1 << ( i * 2 );
02189             chanMaskState = true;
02190             index = i;
02191         }
02192         else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) )
02193         {
02194             channelsMask[i] &= block2;
02195             channelsMask[4] = 1 << ( i * 2 + 1 );
02196             chanMaskState = true;
02197             index = i;
02198         }
02199     }
02200 
02201     // Do only change the channel mask, if we have found a valid block.
02202     if( chanMaskState == true )
02203     {
02204         for( uint8_t i = 0; i < 4; i++ )
02205         {
02206             if( i != index )
02207             {
02208                 channelsMask[i] = 0;
02209             }
02210         }
02211     }
02212     return chanMaskState;
02213 }
02214 #endif
02215 #endif
02216 
02217 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask )
02218 {
02219     if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
02220     {
02221         return false;
02222     }
02223     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
02224     {
02225         for( uint8_t j = 0; j < 16; j++ )
02226         {
02227             if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) )
02228             {// Check datarate validity for enabled channels
02229                 if( ValueInRange( datarate, Channels[i + j].DrRange.Fields.Min, Channels[i + j].DrRange .Fields.Max  ) == true )
02230                 {
02231                     // At least 1 channel has been found we can return OK.
02232                     return true;
02233                 }
02234             }
02235         }
02236     }
02237     return false;
02238 }
02239 
02240 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower )
02241 {
02242     int8_t resultTxPower = txPower;
02243 
02244     // Limit tx power to the band max
02245     resultTxPower =  MAX( txPower, maxBandTxPower );
02246 
02247 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02248     if( ( LoRaMacParams.ChannelsDatarate  == DR_4 ) ||
02249         ( ( LoRaMacParams.ChannelsDatarate  >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate  <= DR_13 ) ) )
02250     {// Limit tx power to max 26dBm
02251         resultTxPower =  MAX( txPower, TX_POWER_26_DBM );
02252     }
02253     else
02254     {
02255         if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask  ) < 50 )
02256         {// Limit tx power to max 21dBm
02257             resultTxPower = MAX( txPower, TX_POWER_20_DBM );
02258         }
02259     }
02260 #endif
02261     return resultTxPower;
02262 }
02263 
02264 static bool ValueInRange( int8_t value, int8_t min, int8_t max )
02265 {
02266     if( ( value >= min ) && ( value <= max ) )
02267     {
02268         return true;
02269     }
02270     return false;
02271 }
02272 
02273 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
02274 {
02275     uint8_t index = 0;
02276     index = id / 16;
02277 
02278     if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
02279     {
02280         return false;
02281     }
02282 
02283     // Deactivate channel
02284     mask[index] &= ~( 1 << ( id % 16 ) );
02285 
02286     return true;
02287 }
02288 
02289 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut )
02290 {
02291     bool adrAckReq = false;
02292     int8_t datarate = LoRaMacParams.ChannelsDatarate ;
02293 
02294     if( adrEnabled == true )
02295     {
02296         if( datarate == LORAMAC_TX_MIN_DATARATE )
02297         {
02298             AdrAckCounter = 0;
02299             adrAckReq = false;
02300         }
02301         else
02302         {
02303             if( AdrAckCounter >= ADR_ACK_LIMIT )
02304             {
02305                 adrAckReq = true;
02306                 LoRaMacParams.ChannelsTxPower  = LORAMAC_MAX_TX_POWER;
02307             }
02308             else
02309             {
02310                 adrAckReq = false;
02311             }
02312             if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
02313             {
02314                 if( ( AdrAckCounter % ADR_ACK_DELAY ) == 1 )
02315                 {
02316 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02317                     if( datarate > LORAMAC_TX_MIN_DATARATE )
02318                     {
02319                         datarate--;
02320                     }
02321                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02322                     {
02323                         if( updateChannelMask == true )
02324                         {
02325                             // Re-enable default channels LC1, LC2, LC3
02326                             LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
02327                         }
02328                     }
02329 #elif defined( USE_BAND_470 )
02330                     if( datarate > LORAMAC_TX_MIN_DATARATE )
02331                     {
02332                         datarate--;
02333                     }
02334                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02335                     {
02336                         if( updateChannelMask == true )
02337                         {
02338                             // Re-enable default channels
02339                             memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
02340                         }
02341                     }
02342 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02343                     if( ( datarate > LORAMAC_TX_MIN_DATARATE ) && ( datarate == DR_8 ) )
02344                     {
02345                         datarate = DR_4;
02346                     }
02347                     else if( datarate > LORAMAC_TX_MIN_DATARATE )
02348                     {
02349                         datarate--;
02350                     }
02351                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02352                     {
02353                         if( updateChannelMask == true )
02354                         {
02355 #if defined( USE_BAND_915 )
02356                             // Re-enable default channels
02357                             memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
02358 #else // defined( USE_BAND_915_HYBRID )
02359                             // Re-enable default channels
02360                             ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
02361 #endif
02362                         }
02363                     }
02364 #else
02365 #error "Please define a frequency band in the compiler options."
02366 #endif
02367                 }
02368             }
02369         }
02370     }
02371 
02372     *datarateOut = datarate;
02373 
02374     return adrAckReq;
02375 }
02376 
02377 static LoRaMacStatus_t  AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
02378 {
02379     LoRaMacStatus_t  status = LORAMAC_STATUS_BUSY ;
02380     // The maximum buffer length must take MAC commands to re-send into account.
02381     uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
02382 
02383     switch( cmd )
02384     {
02385         case MOTE_MAC_LINK_CHECK_REQ :
02386             if( MacCommandsBufferIndex < bufLen )
02387             {
02388                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02389                 // No payload for this command
02390                 status = LORAMAC_STATUS_OK ;
02391             }
02392             break;
02393         case MOTE_MAC_LINK_ADR_ANS :
02394             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02395             {
02396                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02397                 // Margin
02398                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02399                 status = LORAMAC_STATUS_OK ;
02400             }
02401             break;
02402         case MOTE_MAC_DUTY_CYCLE_ANS :
02403             if( MacCommandsBufferIndex < bufLen )
02404             {
02405                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02406                 // No payload for this answer
02407                 status = LORAMAC_STATUS_OK ;
02408             }
02409             break;
02410         case MOTE_MAC_RX_PARAM_SETUP_ANS :
02411             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02412             {
02413                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02414                 // Status: Datarate ACK, Channel ACK
02415                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02416                 status = LORAMAC_STATUS_OK ;
02417             }
02418             break;
02419         case MOTE_MAC_DEV_STATUS_ANS :
02420             if( MacCommandsBufferIndex < ( bufLen - 2 ) )
02421             {
02422                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02423                 // 1st byte Battery
02424                 // 2nd byte Margin
02425                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02426                 MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
02427                 status = LORAMAC_STATUS_OK ;
02428             }
02429             break;
02430         case MOTE_MAC_NEW_CHANNEL_ANS :
02431             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02432             {
02433                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02434                 // Status: Datarate range OK, Channel frequency OK
02435                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02436                 status = LORAMAC_STATUS_OK ;
02437             }
02438             break;
02439         case MOTE_MAC_RX_TIMING_SETUP_ANS :
02440             if( MacCommandsBufferIndex < bufLen )
02441             {
02442                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02443                 // No payload for this answer
02444                 status = LORAMAC_STATUS_OK ;
02445             }
02446             break;
02447         default:
02448             return LORAMAC_STATUS_SERVICE_UNKNOWN ;
02449     }
02450     if( status == LORAMAC_STATUS_OK  )
02451     {
02452         MacCommandsInNextTx = true;
02453     }
02454     return status;
02455 }
02456 
02457 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut )
02458 {
02459     uint8_t i = 0;
02460     uint8_t cmdCount = 0;
02461 
02462     if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) )
02463     {
02464         return 0;
02465     }
02466 
02467     for( i = 0; i < length; i++ )
02468     {
02469         switch( cmdBufIn[i] )
02470         {
02471             // STICKY
02472             case MOTE_MAC_RX_PARAM_SETUP_ANS :
02473             {
02474                 cmdBufOut[cmdCount++] = cmdBufIn[i++];
02475                 cmdBufOut[cmdCount++] = cmdBufIn[i];
02476                 break;
02477             }
02478             case MOTE_MAC_RX_TIMING_SETUP_ANS :
02479             {
02480                 cmdBufOut[cmdCount++] = cmdBufIn[i];
02481                 break;
02482             }
02483             // NON-STICKY
02484             case MOTE_MAC_DEV_STATUS_ANS :
02485             { // 2 bytes payload
02486                 i += 2;
02487                 break;
02488             }
02489             case MOTE_MAC_LINK_ADR_ANS :
02490             case MOTE_MAC_NEW_CHANNEL_ANS :
02491             { // 1 byte payload
02492                 i++;
02493                 break;
02494             }
02495             case MOTE_MAC_DUTY_CYCLE_ANS :
02496             case MOTE_MAC_LINK_CHECK_REQ :
02497             { // 0 byte payload
02498                 break;
02499             }
02500             default:
02501                 break;
02502         }
02503     }
02504 
02505     return cmdCount;
02506 }
02507 
02508 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
02509 {
02510     while( macIndex < commandsSize )
02511     {
02512         // Decode Frame MAC commands
02513         switch( payload[macIndex++] )
02514         {
02515             case SRV_MAC_LINK_CHECK_ANS :
02516                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
02517                 MlmeConfirm.DemodMargin  = payload[macIndex++];
02518                 MlmeConfirm.NbGateways  = payload[macIndex++];
02519                 break;
02520             case SRV_MAC_LINK_ADR_REQ :
02521                 {
02522                     uint8_t i;
02523                     uint8_t status = 0x07;
02524                     uint16_t chMask;
02525                     int8_t txPower = 0;
02526                     int8_t datarate = 0;
02527                     uint8_t nbRep = 0;
02528                     uint8_t chMaskCntl = 0;
02529                     uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
02530 
02531                     // Initialize local copy of the channels mask array
02532                     for( i = 0; i < 6; i++ )
02533                     {
02534                         channelsMask[i] = LoRaMacParams.ChannelsMask [i];
02535                     }
02536                     datarate = payload[macIndex++];
02537                     txPower = datarate & 0x0F;
02538                     datarate = ( datarate >> 4 ) & 0x0F;
02539 
02540                     if( ( AdrCtrlOn == false ) &&
02541                         ( ( LoRaMacParams.ChannelsDatarate  != datarate ) || ( LoRaMacParams.ChannelsTxPower  != txPower ) ) )
02542                     { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
02543                         // Answer the server with fail status
02544                         // Power ACK     = 0
02545                         // Data rate ACK = 0
02546                         // Channel mask  = 0
02547                         AddMacCommand( MOTE_MAC_LINK_ADR_ANS , 0, 0 );
02548                         macIndex += 3;  // Skip over the remaining bytes of the request
02549                         break;
02550                     }
02551                     chMask = ( uint16_t )payload[macIndex++];
02552                     chMask |= ( uint16_t )payload[macIndex++] << 8;
02553 
02554                     nbRep = payload[macIndex++];
02555                     chMaskCntl = ( nbRep >> 4 ) & 0x07;
02556                     nbRep &= 0x0F;
02557                     if( nbRep == 0 )
02558                     {
02559                         nbRep = 1;
02560                     }
02561 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02562                     if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
02563                     {
02564                         status &= 0xFE; // Channel mask KO
02565                     }
02566                     else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) ||
02567                              ( chMaskCntl >= 7 ) )
02568                     {
02569                         // RFU
02570                         status &= 0xFE; // Channel mask KO
02571                     }
02572                     else
02573                     {
02574                         for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
02575                         {
02576                             if( chMaskCntl == 6 )
02577                             {
02578                                 if( Channels[i].Frequency != 0 )
02579                                 {
02580                                     chMask |= 1 << i;
02581                                 }
02582                             }
02583                             else
02584                             {
02585                                 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
02586                                     ( Channels[i].Frequency  == 0 ) )
02587                                 {// Trying to enable an undefined channel
02588                                     status &= 0xFE; // Channel mask KO
02589                                 }
02590                             }
02591                         }
02592                         channelsMask[0] = chMask;
02593                     }
02594 #elif defined( USE_BAND_470 )
02595                     if( chMaskCntl == 6 )
02596                     {
02597                         // Enable all 125 kHz channels
02598                         for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
02599                         {
02600                             for( uint8_t j = 0; j < 16; j++ )
02601                             {
02602                                 if( Channels[i + j].Frequency != 0 )
02603                                 {
02604                                     channelsMask[k] |= 1 << j;
02605                                 }
02606                             }
02607                         }
02608                     }
02609                     else if( chMaskCntl == 7 )
02610                     {
02611                         status &= 0xFE; // Channel mask KO
02612                     }
02613                     else
02614                     {
02615                         for( uint8_t i = 0; i < 16; i++ )
02616                         {
02617                             if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
02618                                 ( Channels[chMaskCntl * 16 + i].Frequency  == 0 ) )
02619                             {// Trying to enable an undefined channel
02620                                 status &= 0xFE; // Channel mask KO
02621                             }
02622                         }
02623                         channelsMask[chMaskCntl] = chMask;
02624                     }
02625 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02626                     if( chMaskCntl == 6 )
02627                     {
02628                         // Enable all 125 kHz channels
02629                         channelsMask[0] = 0xFFFF;
02630                         channelsMask[1] = 0xFFFF;
02631                         channelsMask[2] = 0xFFFF;
02632                         channelsMask[3] = 0xFFFF;
02633                         // Apply chMask to channels 64 to 71
02634                         channelsMask[4] = chMask;
02635                     }
02636                     else if( chMaskCntl == 7 )
02637                     {
02638                         // Disable all 125 kHz channels
02639                         channelsMask[0] = 0x0000;
02640                         channelsMask[1] = 0x0000;
02641                         channelsMask[2] = 0x0000;
02642                         channelsMask[3] = 0x0000;
02643                         // Apply chMask to channels 64 to 71
02644                         channelsMask[4] = chMask;
02645                     }
02646                     else if( chMaskCntl == 5 )
02647                     {
02648                         // RFU
02649                         status &= 0xFE; // Channel mask KO
02650                     }
02651                     else
02652                     {
02653                         channelsMask[chMaskCntl] = chMask;
02654 
02655                         // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
02656                         if( ( datarate < DR_4 ) && ( CountNbEnabled125kHzChannels( channelsMask ) < 2 ) )
02657                         {
02658                             status &= 0xFE; // Channel mask KO
02659                         }
02660 
02661 #if defined( USE_BAND_915_HYBRID )
02662                         if( ValidateChannelMask( channelsMask ) == false )
02663                         {
02664                             status &= 0xFE; // Channel mask KO
02665                         }
02666 #endif
02667                     }
02668 #else
02669     #error "Please define a frequency band in the compiler options."
02670 #endif
02671                     if( ValidateDatarate( datarate, channelsMask ) == false )
02672                     {
02673                         status &= 0xFD; // Datarate KO
02674                     }
02675 
02676                     //
02677                     // Remark MaxTxPower = 0 and MinTxPower = 5
02678                     //
02679                     if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
02680                     {
02681                         status &= 0xFB; // TxPower KO
02682                     }
02683                     if( ( status & 0x07 ) == 0x07 )
02684                     {
02685                         LoRaMacParams.ChannelsDatarate  = datarate;
02686                         LoRaMacParams.ChannelsTxPower  = txPower;
02687 
02688                         memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )channelsMask, sizeof( LoRaMacParams.ChannelsMask  ) );
02689 
02690                         LoRaMacParams.ChannelsNbRep  = nbRep;
02691 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02692                         // Reset ChannelsMaskRemaining to the new ChannelsMask
02693                         ChannelsMaskRemaining[0] &= channelsMask[0];
02694                         ChannelsMaskRemaining[1] &= channelsMask[1];
02695                         ChannelsMaskRemaining[2] &= channelsMask[2];
02696                         ChannelsMaskRemaining[3] &= channelsMask[3];
02697                         ChannelsMaskRemaining[4] = channelsMask[4];
02698                         ChannelsMaskRemaining[5] = channelsMask[5];
02699 #endif
02700                     }
02701                     AddMacCommand( MOTE_MAC_LINK_ADR_ANS , status, 0 );
02702                 }
02703                 break;
02704             case SRV_MAC_DUTY_CYCLE_REQ :
02705                 MaxDCycle = payload[macIndex++];
02706                 AggregatedDCycle = 1 << MaxDCycle;
02707                 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS , 0, 0 );
02708                 break;
02709             case SRV_MAC_RX_PARAM_SETUP_REQ :
02710                 {
02711                     uint8_t status = 0x07;
02712                     int8_t datarate = 0;
02713                     int8_t drOffset = 0;
02714                     uint32_t freq = 0;
02715 
02716                     drOffset = ( payload[macIndex] >> 4 ) & 0x07;
02717                     datarate = payload[macIndex] & 0x0F;
02718                     macIndex++;
02719 
02720                     freq =  ( uint32_t )payload[macIndex++];
02721                     freq |= ( uint32_t )payload[macIndex++] << 8;
02722                     freq |= ( uint32_t )payload[macIndex++] << 16;
02723                     freq *= 100;
02724 
02725                     if( Rx2FreqInRange( freq ) == false )
02726                     {
02727                         status &= 0xFE; // Channel frequency KO
02728                     }
02729 
02730                     if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false )
02731                     {
02732                         status &= 0xFD; // Datarate KO
02733                     }
02734 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02735                     if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) ||
02736                         ( datarate > DR_13 ) )
02737                     {
02738                         status &= 0xFD; // Datarate KO
02739                     }
02740 #endif
02741                     if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false )
02742                     {
02743                         status &= 0xFB; // Rx1DrOffset range KO
02744                     }
02745 
02746                     if( ( status & 0x07 ) == 0x07 )
02747                     {
02748                         LoRaMacParams.Rx2Channel .Datarate  = datarate;
02749                         LoRaMacParams.Rx2Channel .Frequency  = freq;
02750                         LoRaMacParams.Rx1DrOffset  = drOffset;
02751                     }
02752                     AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS , status, 0 );
02753                 }
02754                 break;
02755             case SRV_MAC_DEV_STATUS_REQ :
02756                 {
02757                     uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE ;
02758                     if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
02759                     {
02760                         batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
02761                     }
02762                     AddMacCommand( MOTE_MAC_DEV_STATUS_ANS , batteryLevel, snr );
02763                     break;
02764                 }
02765             case SRV_MAC_NEW_CHANNEL_REQ :
02766                 {
02767                     uint8_t status = 0x03;
02768 
02769 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02770                     status &= 0xFC; // Channel frequency and datarate KO
02771                     macIndex += 5;
02772 #else
02773                     int8_t channelIndex = 0;
02774                     ChannelParams_t  chParam;
02775 
02776                     channelIndex = payload[macIndex++];
02777                     chParam.Frequency  = ( uint32_t )payload[macIndex++];
02778                     chParam.Frequency  |= ( uint32_t )payload[macIndex++] << 8;
02779                     chParam.Frequency  |= ( uint32_t )payload[macIndex++] << 16;
02780                     chParam.Frequency  *= 100;
02781                     chParam.DrRange .Value  = payload[macIndex++];
02782 
02783                     LoRaMacState |= LORAMAC_TX_CONFIG;
02784                     if( chParam.Frequency  == 0 )
02785                     {
02786                         if( channelIndex < 3 )
02787                         {
02788                             status &= 0xFC;
02789                         }
02790                         else
02791                         {
02792                             if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK  )
02793                             {
02794                                 status &= 0xFC;
02795                             }
02796                         }
02797                     }
02798                     else
02799                     {
02800                         switch( LoRaMacChannelAdd( channelIndex, chParam ) )
02801                         {
02802                             case LORAMAC_STATUS_OK :
02803                             {
02804                                 break;
02805                             }
02806                             case LORAMAC_STATUS_FREQUENCY_INVALID :
02807                             {
02808                                 status &= 0xFE;
02809                                 break;
02810                             }
02811                             case LORAMAC_STATUS_DATARATE_INVALID :
02812                             {
02813                                 status &= 0xFD;
02814                                 break;
02815                             }
02816                             case LORAMAC_STATUS_FREQ_AND_DR_INVALID :
02817                             {
02818                                 status &= 0xFC;
02819                                 break;
02820                             }
02821                             default:
02822                             {
02823                                 status &= 0xFC;
02824                                 break;
02825                             }
02826                         }
02827                     }
02828                     LoRaMacState &= ~LORAMAC_TX_CONFIG;
02829 #endif
02830                     AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS , status, 0 );
02831                 }
02832                 break;
02833             case SRV_MAC_RX_TIMING_SETUP_REQ :
02834                 {
02835                     uint8_t delay = payload[macIndex++] & 0x0F;
02836 
02837                     if( delay == 0 )
02838                     {
02839                         delay++;
02840                     }
02841                     LoRaMacParams.ReceiveDelay1  = delay * 1e3;
02842                     LoRaMacParams.ReceiveDelay2  = LoRaMacParams.ReceiveDelay1  + 1e3;
02843                     AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS , 0, 0 );
02844                 }
02845                 break;
02846             default:
02847                 // Unknown command. ABORT MAC commands processing
02848                 return;
02849         }
02850     }
02851 }
02852 
02853 LoRaMacStatus_t  Send( LoRaMacHeader_t  *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
02854 {
02855     LoRaMacFrameCtrl_t  fCtrl;
02856     LoRaMacStatus_t  status = LORAMAC_STATUS_PARAMETER_INVALID ;
02857 
02858     fCtrl.Value  = 0;
02859     fCtrl.Bits.FOptsLen       = 0;
02860     fCtrl.Bits.FPending       = 0;
02861     fCtrl.Bits.Ack            = false;
02862     fCtrl.Bits.AdrAckReq      = false;
02863     fCtrl.Bits.Adr            = AdrCtrlOn;
02864 
02865     // Prepare the frame
02866     status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize );
02867 
02868     // Validate status
02869     if( status != LORAMAC_STATUS_OK  )
02870     {
02871         return status;
02872     }
02873 
02874     // Reset confirm parameters
02875     McpsConfirm.NbRetries  = 0;
02876     McpsConfirm.AckReceived  = false;
02877     McpsConfirm.UpLinkCounter  = UpLinkCounter;
02878 
02879     status = ScheduleTx( );
02880 
02881     return status;
02882 }
02883 
02884 static LoRaMacStatus_t  ScheduleTx( void )
02885 {
02886     TimerTime_t dutyCycleTimeOff = 0;
02887 
02888     // Check if the device is off
02889     if( MaxDCycle == 255 )
02890     {
02891         return LORAMAC_STATUS_DEVICE_OFF ;
02892     }
02893     if( MaxDCycle == 0 )
02894     {
02895         AggregatedTimeOff = 0;
02896     }
02897 
02898     // Select channel
02899     while( SetNextChannel( &dutyCycleTimeOff ) == false )
02900     {
02901         // Set the default datarate
02902         LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
02903 
02904 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02905         // Re-enable default channels LC1, LC2, LC3
02906         LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
02907 #endif
02908     }
02909 
02910     // Compute Rx1 windows parameters
02911 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02912     RxWindowsParams[0] = ComputeRxWindowParameters( DatarateOffsets[LoRaMacParams.ChannelsDatarate ][LoRaMacParams.Rx1DrOffset ], LoRaMacParams.SystemMaxRxError  );
02913 #else
02914     RxWindowsParams[0] = ComputeRxWindowParameters( MAX( DR_0, LoRaMacParams.ChannelsDatarate  - LoRaMacParams.Rx1DrOffset  ), LoRaMacParams.SystemMaxRxError  );
02915 #endif
02916     // Compute Rx2 windows parameters
02917     RxWindowsParams[1] = ComputeRxWindowParameters( LoRaMacParams.Rx2Channel .Datarate , LoRaMacParams.SystemMaxRxError  );
02918 
02919     if( IsLoRaMacNetworkJoined == false )
02920     {
02921         RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1  + RxWindowsParams[0].RxOffset;
02922         RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2  + RxWindowsParams[1].RxOffset;
02923     }
02924     else
02925     {
02926         if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate , MacCommandsBufferIndex ) == false )
02927         {
02928             return LORAMAC_STATUS_LENGTH_ERROR ;
02929         }
02930         RxWindow1Delay = LoRaMacParams.ReceiveDelay1  + RxWindowsParams[0].RxOffset;
02931         RxWindow2Delay = LoRaMacParams.ReceiveDelay2  + RxWindowsParams[1].RxOffset;
02932     }
02933 
02934     // Schedule transmission of frame
02935     if( dutyCycleTimeOff == 0 )
02936     {
02937         // Try to send now
02938         return SendFrameOnChannel( Channels[Channel] );
02939     }
02940     else
02941     {
02942         // Send later - prepare timer
02943         LoRaMacState |= LORAMAC_TX_DELAYED;
02944         TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff );
02945         TimerStart( &TxDelayedTimer );
02946 
02947         return LORAMAC_STATUS_OK ;
02948     }
02949 }
02950 
02951 static uint16_t JoinDutyCycle( void )
02952 {
02953     uint16_t dutyCycle = 0;
02954     TimerTime_t timeElapsed = TimerGetElapsedTime( LoRaMacInitializationTime );
02955 
02956     if( timeElapsed < 3600e3 )
02957     {
02958         dutyCycle = BACKOFF_DC_1_HOUR;
02959     }
02960     else if( timeElapsed < ( 3600e3 + 36000e3 ) )
02961     {
02962         dutyCycle = BACKOFF_DC_10_HOURS;
02963     }
02964     else
02965     {
02966         dutyCycle = BACKOFF_DC_24_HOURS;
02967     }
02968     return dutyCycle;
02969 }
02970 
02971 static void CalculateBackOff( uint8_t channel )
02972 {
02973     uint16_t dutyCycle = Bands[Channels[channel].Band ].DCycle ;
02974     uint16_t joinDutyCycle = 0;
02975 
02976     // Reset time-off to initial value.
02977     Bands[Channels[channel].Band ].TimeOff  = 0;
02978 
02979     if( IsLoRaMacNetworkJoined == false )
02980     {
02981         // The node has not joined yet. Apply join duty cycle to all regions.
02982         joinDutyCycle = JoinDutyCycle( );
02983         dutyCycle = MAX( dutyCycle, joinDutyCycle );
02984 
02985         // Update Band time-off.
02986         Bands[Channels[channel].Band ].TimeOff  = TxTimeOnAir * dutyCycle - TxTimeOnAir;
02987     }
02988     else
02989     {
02990         if( DutyCycleOn == true )
02991         {
02992             Bands[Channels[channel].Band ].TimeOff  = TxTimeOnAir * dutyCycle - TxTimeOnAir;
02993         }
02994     }
02995 
02996     // Update Aggregated Time OFF
02997     AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
02998 }
02999 
03000 static int8_t AlternateDatarate( uint16_t nbTrials )
03001 {
03002     int8_t datarate = LORAMAC_TX_MIN_DATARATE;
03003 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03004 #if defined( USE_BAND_915 )
03005     // Re-enable 500 kHz default channels
03006     LoRaMacParams.ChannelsMask [4] = 0x00FF;
03007 #else // defined( USE_BAND_915_HYBRID )
03008     // Re-enable 500 kHz default channels
03009     ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
03010 #endif
03011 
03012     if( ( nbTrials & 0x01 ) == 0x01 )
03013     {
03014         datarate = DR_4;
03015     }
03016     else
03017     {
03018         datarate = DR_0;
03019     }
03020 #else
03021     if( ( nbTrials % 48 ) == 0 )
03022     {
03023         datarate = DR_0;
03024     }
03025     else if( ( nbTrials % 32 ) == 0 )
03026     {
03027         datarate = DR_1;
03028     }
03029     else if( ( nbTrials % 24 ) == 0 )
03030     {
03031         datarate = DR_2;
03032     }
03033     else if( ( nbTrials % 16 ) == 0 )
03034     {
03035         datarate = DR_3;
03036     }
03037     else if( ( nbTrials % 8 ) == 0 )
03038     {
03039         datarate = DR_4;
03040     }
03041     else
03042     {
03043         datarate = DR_5;
03044     }
03045 #endif
03046     return datarate;
03047 }
03048 
03049 static void ResetMacParameters( void )
03050 {
03051     IsLoRaMacNetworkJoined = false;
03052 
03053     // Counters
03054     UpLinkCounter = 0;
03055     DownLinkCounter = 0;
03056     AdrAckCounter = 0;
03057 
03058     ChannelsNbRepCounter = 0;
03059 
03060     AckTimeoutRetries = 1;
03061     AckTimeoutRetriesCounter = 1;
03062     AckTimeoutRetry = false;
03063 
03064     MaxDCycle = 0;
03065     AggregatedDCycle = 1;
03066 
03067     MacCommandsBufferIndex = 0;
03068     MacCommandsBufferToRepeatIndex = 0;
03069 
03070     IsRxWindowsEnabled = true;
03071 
03072     LoRaMacParams.ChannelsTxPower  = LoRaMacParamsDefaults.ChannelsTxPower ;
03073     LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
03074 
03075     LoRaMacParams.Rx1DrOffset  = LoRaMacParamsDefaults.Rx1DrOffset ;
03076     LoRaMacParams.Rx2Channel  = LoRaMacParamsDefaults.Rx2Channel ;
03077 
03078     memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03079 
03080 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03081     memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03082 #endif
03083 
03084 
03085     NodeAckRequested = false;
03086     SrvAckRequested = false;
03087     MacCommandsInNextTx = false;
03088 
03089     // Reset Multicast downlink counters
03090     MulticastParams_t  *cur = MulticastChannels;
03091     while( cur != NULL )
03092     {
03093         cur->DownLinkCounter  = 0;
03094         cur = cur->Next ;
03095     }
03096 
03097     // Initialize channel index.
03098     Channel = LORA_MAX_NB_CHANNELS;
03099 }
03100 
03101 LoRaMacStatus_t  PrepareFrame( LoRaMacHeader_t  *macHdr, LoRaMacFrameCtrl_t  *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
03102 {
03103     uint16_t i;
03104     uint8_t pktHeaderLen = 0;
03105     uint32_t mic = 0;
03106     const void* payload = fBuffer;
03107     uint8_t framePort = fPort;
03108 
03109     LoRaMacBufferPktLen = 0;
03110 
03111     NodeAckRequested = false;
03112 
03113     if( fBuffer == NULL )
03114     {
03115         fBufferSize = 0;
03116     }
03117 
03118     LoRaMacTxPayloadLen = fBufferSize;
03119 
03120     LoRaMacBuffer[pktHeaderLen++] = macHdr->Value ;
03121 
03122     switch( macHdr->Bits.MType  )
03123     {
03124         case FRAME_TYPE_JOIN_REQ :
03125             LoRaMacBufferPktLen = pktHeaderLen;
03126 
03127             memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 );
03128             LoRaMacBufferPktLen += 8;
03129             memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 );
03130             LoRaMacBufferPktLen += 8;
03131 
03132             LoRaMacDevNonce = Radio .Random( );
03133 
03134             LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
03135             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
03136 
03137             LoRaMacJoinComputeMic ( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
03138 
03139             LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
03140             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
03141             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
03142             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
03143 
03144             break;
03145         case FRAME_TYPE_DATA_CONFIRMED_UP :
03146             NodeAckRequested = true;
03147             //Intentional fallthrough
03148         case FRAME_TYPE_DATA_UNCONFIRMED_UP :
03149             if( IsLoRaMacNetworkJoined == false )
03150             {
03151                 return LORAMAC_STATUS_NO_NETWORK_JOINED ; // No network has been joined yet
03152             }
03153 
03154             fCtrl->Bits.AdrAckReq  = AdrNextDr( fCtrl->Bits.Adr , true, &LoRaMacParams.ChannelsDatarate  );
03155 
03156             if( SrvAckRequested == true )
03157             {
03158                 SrvAckRequested = false;
03159                 fCtrl->Bits.Ack  = 1;
03160             }
03161 
03162             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
03163             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
03164             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
03165             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
03166 
03167             LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value ;
03168 
03169             LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
03170             LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
03171 
03172             // Copy the MAC commands which must be re-send into the MAC command buffer
03173             memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );
03174             MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
03175 
03176             if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03177             {
03178                 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) )
03179                 {
03180                     fCtrl->Bits.FOptsLen  += MacCommandsBufferIndex;
03181 
03182                     // Update FCtrl field with new value of OptionsLength
03183                     LoRaMacBuffer[0x05] = fCtrl->Value ;
03184                     for( i = 0; i < MacCommandsBufferIndex; i++ )
03185                     {
03186                         LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
03187                     }
03188                 }
03189             }
03190             else
03191             {
03192                 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) )
03193                 {
03194                     LoRaMacTxPayloadLen = MacCommandsBufferIndex;
03195                     payload = MacCommandsBuffer;
03196                     framePort = 0;
03197                 }
03198             }
03199             MacCommandsInNextTx = false;
03200             // Store MAC commands which must be re-send in case the device does not receive a downlink anymore
03201             MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );
03202             if( MacCommandsBufferToRepeatIndex > 0 )
03203             {
03204                 MacCommandsInNextTx = true;
03205             }
03206 
03207             if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03208             {
03209                 LoRaMacBuffer[pktHeaderLen++] = framePort;
03210 
03211                 if( framePort == 0 )
03212                 {
03213                     LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
03214                 }
03215                 else
03216                 {
03217                     LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
03218                 }
03219             }
03220             LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
03221 
03222             LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
03223 
03224             LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
03225             LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
03226             LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
03227             LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
03228 
03229             LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
03230 
03231             break;
03232         case FRAME_TYPE_PROPRIETARY :
03233             if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03234             {
03235                 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen );
03236                 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
03237             }
03238             break;
03239         default:
03240             return LORAMAC_STATUS_SERVICE_UNKNOWN ;
03241     }
03242 
03243     return LORAMAC_STATUS_OK ;
03244 }
03245 
03246 LoRaMacStatus_t  SendFrameOnChannel( ChannelParams_t  channel )
03247 {
03248     int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate ];
03249     int8_t txPowerIndex = 0;
03250     int8_t txPower = 0;
03251 
03252     txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[channel.Band ].TxMaxPower  );
03253     txPower = TxPowers[txPowerIndex];
03254 
03255     MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
03256     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
03257     McpsConfirm.Datarate  = LoRaMacParams.ChannelsDatarate ;
03258     McpsConfirm.TxPower  = txPowerIndex;
03259     McpsConfirm.UpLinkFrequency  = channel.Frequency ;
03260 
03261     Radio .SetChannel( channel.Frequency  );
03262 
03263 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
03264     if( LoRaMacParams.ChannelsDatarate  == DR_7 )
03265     { // High Speed FSK channel
03266         Radio .SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen );
03267         Radio .SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e3 );
03268         TxTimeOnAir = Radio .TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
03269 
03270     }
03271     else if( LoRaMacParams.ChannelsDatarate  == DR_6 )
03272     { // High speed LoRa channel
03273         Radio .SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03274         Radio .SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03275         TxTimeOnAir = Radio .TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03276     }
03277     else
03278     { // Normal LoRa channel
03279         Radio .SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03280         Radio .SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03281         TxTimeOnAir = Radio .TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03282     }
03283 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03284     Radio .SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03285     if( LoRaMacParams.ChannelsDatarate  >= DR_4 )
03286     { // High speed LoRa channel BW500 kHz
03287         Radio .SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03288         TxTimeOnAir = Radio .TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03289     }
03290     else
03291     { // Normal LoRa channel
03292         Radio .SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03293         TxTimeOnAir = Radio .TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03294     }
03295 #elif defined( USE_BAND_470 )
03296     Radio .SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03297     Radio .SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03298     TxTimeOnAir = Radio .TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03299 #else
03300     #error "Please define a frequency band in the compiler options."
03301 #endif
03302 
03303     // Store the time on air
03304     McpsConfirm.TxTimeOnAir  = TxTimeOnAir;
03305     MlmeConfirm.TxTimeOnAir  = TxTimeOnAir;
03306 
03307     // Starts the MAC layer status check timer
03308     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03309     TimerStart( &MacStateCheckTimer );
03310 
03311     if( IsLoRaMacNetworkJoined == false )
03312     {
03313         JoinRequestTrials++;
03314     }
03315 
03316     // Send now
03317     Radio .Send( LoRaMacBuffer, LoRaMacBufferPktLen );
03318 
03319     LoRaMacState |= LORAMAC_TX_RUNNING;
03320 
03321     return LORAMAC_STATUS_OK ;
03322 }
03323 
03324 LoRaMacStatus_t  SetTxContinuousWave( uint16_t timeout )
03325 {
03326     int8_t txPowerIndex = 0;
03327     int8_t txPower = 0;
03328 
03329     txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[Channels[Channel].Band ].TxMaxPower  );
03330     txPower = TxPowers[txPowerIndex];
03331 
03332     // Starts the MAC layer status check timer
03333     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03334     TimerStart( &MacStateCheckTimer );
03335 
03336     Radio .SetTxContinuousWave( Channels[Channel].Frequency, txPower, timeout );
03337 
03338     LoRaMacState |= LORAMAC_TX_RUNNING;
03339 
03340     return LORAMAC_STATUS_OK ;
03341 }
03342 
03343 LoRaMacStatus_t  SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power )
03344 {
03345     Radio .SetTxContinuousWave( frequency, power, timeout );
03346 
03347     // Starts the MAC layer status check timer
03348     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03349     TimerStart( &MacStateCheckTimer );
03350 
03351     LoRaMacState |= LORAMAC_TX_RUNNING;
03352 
03353     return LORAMAC_STATUS_OK ;
03354 }
03355 
03356 LoRaMacStatus_t  LoRaMacInitialization( LoRaMacPrimitives_t  *primitives, LoRaMacCallback_t *callbacks )
03357 {
03358     if( primitives == NULL )
03359     {
03360         return LORAMAC_STATUS_PARAMETER_INVALID ;
03361     }
03362 
03363     if( ( primitives->MacMcpsConfirm == NULL ) ||
03364         ( primitives->MacMcpsIndication == NULL ) ||
03365         ( primitives->MacMlmeConfirm == NULL ) )
03366     {
03367         return LORAMAC_STATUS_PARAMETER_INVALID ;
03368     }
03369 
03370     LoRaMacPrimitives = primitives;
03371     LoRaMacCallbacks = callbacks;
03372 
03373     LoRaMacFlags.Value  = 0;
03374 
03375     LoRaMacDeviceClass = CLASS_A ;
03376     LoRaMacState = LORAMAC_IDLE;
03377 
03378     JoinRequestTrials = 0;
03379     MaxJoinRequestTrials = 1;
03380     RepeaterSupport = false;
03381 
03382     // Reset duty cycle times
03383     AggregatedLastTxDoneTime = 0;
03384     AggregatedTimeOff = 0;
03385 
03386     // Duty cycle
03387 #if defined( USE_BAND_433 )
03388     DutyCycleOn = true;
03389 #elif defined( USE_BAND_470 )
03390     DutyCycleOn = false;
03391 #elif defined( USE_BAND_780 )
03392     DutyCycleOn = true;
03393 #elif defined( USE_BAND_868 )
03394     DutyCycleOn = true;
03395 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03396     DutyCycleOn = false;
03397 #else
03398     #error "Please define a frequency band in the compiler options."
03399 #endif
03400 
03401     // Reset to defaults
03402     LoRaMacParamsDefaults.ChannelsTxPower  = LORAMAC_DEFAULT_TX_POWER;
03403     LoRaMacParamsDefaults.ChannelsDatarate  = LORAMAC_DEFAULT_DATARATE;
03404 
03405     LoRaMacParamsDefaults.SystemMaxRxError  = 10;
03406     LoRaMacParamsDefaults.MinRxSymbols  = 6;
03407     LoRaMacParamsDefaults.MaxRxWindow  = MAX_RX_WINDOW;
03408     LoRaMacParamsDefaults.ReceiveDelay1  = RECEIVE_DELAY1;
03409     LoRaMacParamsDefaults.ReceiveDelay2  = RECEIVE_DELAY2;
03410     LoRaMacParamsDefaults.JoinAcceptDelay1  = JOIN_ACCEPT_DELAY1;
03411     LoRaMacParamsDefaults.JoinAcceptDelay2  = JOIN_ACCEPT_DELAY2;
03412 
03413     LoRaMacParamsDefaults.ChannelsNbRep  = 1;
03414     LoRaMacParamsDefaults.Rx1DrOffset  = 0;
03415 
03416     LoRaMacParamsDefaults.Rx2Channel  = ( Rx2ChannelParams_t  )RX_WND_2_CHANNEL;
03417 
03418     // Channel mask
03419 #if defined( USE_BAND_433 )
03420     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03421 #elif defined ( USE_BAND_470 )
03422     LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF;
03423     LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF;
03424     LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF;
03425     LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF;
03426     LoRaMacParamsDefaults.ChannelsMask [4] = 0xFFFF;
03427     LoRaMacParamsDefaults.ChannelsMask [5] = 0xFFFF;
03428 #elif defined( USE_BAND_780 )
03429     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03430 #elif defined( USE_BAND_868 )
03431     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03432 #elif defined( USE_BAND_915 )
03433     LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF;
03434     LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF;
03435     LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF;
03436     LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF;
03437     LoRaMacParamsDefaults.ChannelsMask [4] = 0x00FF;
03438     LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000;
03439 #elif defined( USE_BAND_915_HYBRID )
03440     LoRaMacParamsDefaults.ChannelsMask [0] = 0x00FF;
03441     LoRaMacParamsDefaults.ChannelsMask [1] = 0x0000;
03442     LoRaMacParamsDefaults.ChannelsMask [2] = 0x0000;
03443     LoRaMacParamsDefaults.ChannelsMask [3] = 0x0000;
03444     LoRaMacParamsDefaults.ChannelsMask [4] = 0x0001;
03445     LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000;
03446 #else
03447     #error "Please define a frequency band in the compiler options."
03448 #endif
03449 
03450 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03451     // 125 kHz channels
03452     for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
03453     {
03454         Channels[i].Frequency  = 902.3e6 + i * 200e3;
03455         Channels[i].DrRange .Value  = ( DR_3 << 4 ) | DR_0;
03456         Channels[i].Band  = 0;
03457     }
03458     // 500 kHz channels
03459     for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
03460     {
03461         Channels[i].Frequency  = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
03462         Channels[i].DrRange .Value  = ( DR_4 << 4 ) | DR_4;
03463         Channels[i].Band  = 0;
03464     }
03465 #elif defined( USE_BAND_470 )
03466     // 125 kHz channels
03467     for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
03468     {
03469         Channels[i].Frequency  = 470.3e6 + i * 200e3;
03470         Channels[i].DrRange .Value  = ( DR_5 << 4 ) | DR_0;
03471         Channels[i].Band  = 0;
03472     }
03473 #endif
03474 
03475     // Init parameters which are not set in function ResetMacParameters
03476     LoRaMacParams.SystemMaxRxError  = LoRaMacParamsDefaults.SystemMaxRxError ;
03477     LoRaMacParams.MinRxSymbols  = LoRaMacParamsDefaults.MinRxSymbols ;
03478     LoRaMacParams.MaxRxWindow  = LoRaMacParamsDefaults.MaxRxWindow ;
03479     LoRaMacParams.ReceiveDelay1  = LoRaMacParamsDefaults.ReceiveDelay1 ;
03480     LoRaMacParams.ReceiveDelay2  = LoRaMacParamsDefaults.ReceiveDelay2 ;
03481     LoRaMacParams.JoinAcceptDelay1  = LoRaMacParamsDefaults.JoinAcceptDelay1 ;
03482     LoRaMacParams.JoinAcceptDelay2  = LoRaMacParamsDefaults.JoinAcceptDelay2 ;
03483     LoRaMacParams.ChannelsNbRep  = LoRaMacParamsDefaults.ChannelsNbRep ;
03484 
03485     ResetMacParameters( );
03486 
03487     // Initialize timers
03488     TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
03489     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03490 
03491     TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
03492     TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
03493     TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
03494     TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
03495 
03496     // Store the current initialization time
03497     LoRaMacInitializationTime = TimerGetCurrentTime( );
03498 
03499     // Initialize Radio driver
03500     RadioEvents.TxDone = OnRadioTxDone;
03501     RadioEvents.RxDone = OnRadioRxDone;
03502     RadioEvents.RxError = OnRadioRxError;
03503     RadioEvents.TxTimeout = OnRadioTxTimeout;
03504     RadioEvents.RxTimeout = OnRadioRxTimeout;
03505     Radio .Init( &RadioEvents );
03506 
03507     // Random seed initialization
03508     srand1( Radio .Random( ) );
03509 
03510     PublicNetwork = true;
03511     Radio .SetPublicNetwork( PublicNetwork );
03512     Radio .Sleep( );
03513 
03514     return LORAMAC_STATUS_OK ;
03515 }
03516 
03517 LoRaMacStatus_t  LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t * txInfo )
03518 {
03519     int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate ;
03520     uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex;
03521 
03522     if( txInfo == NULL )
03523     {
03524         return LORAMAC_STATUS_PARAMETER_INVALID ;
03525     }
03526 
03527     AdrNextDr( AdrCtrlOn, false, &datarate );
03528 
03529     if( RepeaterSupport == true )
03530     {
03531         txInfo->CurrentPayloadSize  = MaxPayloadOfDatarateRepeater[datarate];
03532     }
03533     else
03534     {
03535         txInfo->CurrentPayloadSize  = MaxPayloadOfDatarate[datarate];
03536     }
03537 
03538     if( txInfo->CurrentPayloadSize  >= fOptLen )
03539     {
03540         txInfo->MaxPossiblePayload  = txInfo->CurrentPayloadSize  - fOptLen;
03541     }
03542     else
03543     {
03544         return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ;
03545     }
03546 
03547     if( ValidatePayloadLength( size, datarate, 0 ) == false )
03548     {
03549         return LORAMAC_STATUS_LENGTH_ERROR ;
03550     }
03551 
03552     if( ValidatePayloadLength( size, datarate, fOptLen ) == false )
03553     {
03554         return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ;
03555     }
03556 
03557     return LORAMAC_STATUS_OK ;
03558 }
03559 
03560 LoRaMacStatus_t  LoRaMacMibGetRequestConfirm( MibRequestConfirm_t  *mibGet )
03561 {
03562     LoRaMacStatus_t  status = LORAMAC_STATUS_OK ;
03563 
03564     if( mibGet == NULL )
03565     {
03566         return LORAMAC_STATUS_PARAMETER_INVALID ;
03567     }
03568 
03569     switch( mibGet->Type  )
03570     {
03571         case MIB_DEVICE_CLASS :
03572         {
03573             mibGet->Param .Class  = LoRaMacDeviceClass;
03574             break;
03575         }
03576         case MIB_NETWORK_JOINED :
03577         {
03578             mibGet->Param .IsNetworkJoined  = IsLoRaMacNetworkJoined;
03579             break;
03580         }
03581         case MIB_ADR :
03582         {
03583             mibGet->Param .AdrEnable  = AdrCtrlOn;
03584             break;
03585         }
03586         case MIB_NET_ID :
03587         {
03588             mibGet->Param .NetID  = LoRaMacNetID;
03589             break;
03590         }
03591         case MIB_DEV_ADDR :
03592         {
03593             mibGet->Param .DevAddr  = LoRaMacDevAddr;
03594             break;
03595         }
03596         case MIB_NWK_SKEY :
03597         {
03598             mibGet->Param .NwkSKey  = LoRaMacNwkSKey;
03599             break;
03600         }
03601         case MIB_APP_SKEY :
03602         {
03603             mibGet->Param .AppSKey  = LoRaMacAppSKey;
03604             break;
03605         }
03606         case MIB_PUBLIC_NETWORK :
03607         {
03608             mibGet->Param .EnablePublicNetwork  = PublicNetwork;
03609             break;
03610         }
03611         case MIB_REPEATER_SUPPORT :
03612         {
03613             mibGet->Param .EnableRepeaterSupport  = RepeaterSupport;
03614             break;
03615         }
03616         case MIB_CHANNELS :
03617         {
03618             mibGet->Param .ChannelList  = Channels;
03619             break;
03620         }
03621         case MIB_RX2_CHANNEL :
03622         {
03623             mibGet->Param .Rx2Channel  = LoRaMacParams.Rx2Channel ;
03624             break;
03625         }
03626         case MIB_RX2_DEFAULT_CHANNEL :
03627         {
03628             mibGet->Param .Rx2Channel  = LoRaMacParamsDefaults.Rx2Channel ;
03629             break;
03630         }
03631         case MIB_CHANNELS_DEFAULT_MASK :
03632         {
03633             mibGet->Param .ChannelsDefaultMask  = LoRaMacParamsDefaults.ChannelsMask ;
03634             break;
03635         }
03636         case MIB_CHANNELS_MASK :
03637         {
03638             mibGet->Param .ChannelsMask  = LoRaMacParams.ChannelsMask ;
03639             break;
03640         }
03641         case MIB_CHANNELS_NB_REP :
03642         {
03643             mibGet->Param .ChannelNbRep  = LoRaMacParams.ChannelsNbRep ;
03644             break;
03645         }
03646         case MIB_MAX_RX_WINDOW_DURATION :
03647         {
03648             mibGet->Param .MaxRxWindow  = LoRaMacParams.MaxRxWindow ;
03649             break;
03650         }
03651         case MIB_RECEIVE_DELAY_1 :
03652         {
03653             mibGet->Param .ReceiveDelay1  = LoRaMacParams.ReceiveDelay1 ;
03654             break;
03655         }
03656         case MIB_RECEIVE_DELAY_2 :
03657         {
03658             mibGet->Param .ReceiveDelay2  = LoRaMacParams.ReceiveDelay2 ;
03659             break;
03660         }
03661         case MIB_JOIN_ACCEPT_DELAY_1 :
03662         {
03663             mibGet->Param .JoinAcceptDelay1  = LoRaMacParams.JoinAcceptDelay1 ;
03664             break;
03665         }
03666         case MIB_JOIN_ACCEPT_DELAY_2 :
03667         {
03668             mibGet->Param .JoinAcceptDelay2  = LoRaMacParams.JoinAcceptDelay2 ;
03669             break;
03670         }
03671         case MIB_CHANNELS_DEFAULT_DATARATE :
03672         {
03673             mibGet->Param .ChannelsDefaultDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
03674             break;
03675         }
03676         case MIB_CHANNELS_DATARATE :
03677         {
03678             mibGet->Param .ChannelsDatarate  = LoRaMacParams.ChannelsDatarate ;
03679             break;
03680         }
03681         case MIB_CHANNELS_DEFAULT_TX_POWER :
03682         {
03683             mibGet->Param .ChannelsDefaultTxPower  = LoRaMacParamsDefaults.ChannelsTxPower ;
03684             break;
03685         }
03686         case MIB_CHANNELS_TX_POWER :
03687         {
03688             mibGet->Param .ChannelsTxPower  = LoRaMacParams.ChannelsTxPower ;
03689             break;
03690         }
03691         case MIB_UPLINK_COUNTER :
03692         {
03693             mibGet->Param .UpLinkCounter  = UpLinkCounter;
03694             break;
03695         }
03696         case MIB_DOWNLINK_COUNTER :
03697         {
03698             mibGet->Param .DownLinkCounter  = DownLinkCounter;
03699             break;
03700         }
03701         case MIB_MULTICAST_CHANNEL :
03702         {
03703             mibGet->Param .MulticastList  = MulticastChannels;
03704             break;
03705         }
03706         case MIB_SYSTEM_MAX_RX_ERROR :
03707         {
03708             mibGet->Param .SystemMaxRxError  = LoRaMacParams.SystemMaxRxError ;
03709             break;
03710         }
03711         case MIB_MIN_RX_SYMBOLS :
03712         {
03713             mibGet->Param .MinRxSymbols  = LoRaMacParams.MinRxSymbols ;
03714             break;
03715         }
03716         default:
03717             status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
03718             break;
03719     }
03720 
03721     return status;
03722 }
03723 
03724 LoRaMacStatus_t  LoRaMacMibSetRequestConfirm( MibRequestConfirm_t  *mibSet )
03725 {
03726     LoRaMacStatus_t  status = LORAMAC_STATUS_OK ;
03727 
03728     if( mibSet == NULL )
03729     {
03730         return LORAMAC_STATUS_PARAMETER_INVALID ;
03731     }
03732     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
03733     {
03734         return LORAMAC_STATUS_BUSY ;
03735     }
03736 
03737     switch( mibSet->Type  )
03738     {
03739         case MIB_DEVICE_CLASS :
03740         {
03741             LoRaMacDeviceClass = mibSet->Param .Class ;
03742             switch( LoRaMacDeviceClass )
03743             {
03744                 case CLASS_A :
03745                 {
03746                     // Set the radio into sleep to setup a defined state
03747                     Radio .Sleep( );
03748                     break;
03749                 }
03750                 case CLASS_B :
03751                 {
03752                     break;
03753                 }
03754                 case CLASS_C :
03755                 {
03756                     // Set the NodeAckRequested indicator to default
03757                     NodeAckRequested = false;
03758                     OnRxWindow2TimerEvent( );
03759                     break;
03760                 }
03761             }
03762             break;
03763         }
03764         case MIB_NETWORK_JOINED :
03765         {
03766             IsLoRaMacNetworkJoined = mibSet->Param .IsNetworkJoined ;
03767             break;
03768         }
03769         case MIB_ADR :
03770         {
03771             AdrCtrlOn = mibSet->Param .AdrEnable ;
03772             break;
03773         }
03774         case MIB_NET_ID :
03775         {
03776             LoRaMacNetID = mibSet->Param .NetID ;
03777             break;
03778         }
03779         case MIB_DEV_ADDR :
03780         {
03781             LoRaMacDevAddr = mibSet->Param .DevAddr ;
03782             break;
03783         }
03784         case MIB_NWK_SKEY :
03785         {
03786             if( mibSet->Param .NwkSKey  != NULL )
03787             {
03788                 memcpy1( LoRaMacNwkSKey, mibSet->Param .NwkSKey ,
03789                                sizeof( LoRaMacNwkSKey ) );
03790             }
03791             else
03792             {
03793                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03794             }
03795             break;
03796         }
03797         case MIB_APP_SKEY :
03798         {
03799             if( mibSet->Param .AppSKey  != NULL )
03800             {
03801                 memcpy1( LoRaMacAppSKey, mibSet->Param .AppSKey ,
03802                                sizeof( LoRaMacAppSKey ) );
03803             }
03804             else
03805             {
03806                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03807             }
03808             break;
03809         }
03810         case MIB_PUBLIC_NETWORK :
03811         {
03812             PublicNetwork = mibSet->Param .EnablePublicNetwork ;
03813             Radio .SetPublicNetwork( PublicNetwork );
03814             break;
03815         }
03816         case MIB_REPEATER_SUPPORT :
03817         {
03818              RepeaterSupport = mibSet->Param .EnableRepeaterSupport ;
03819             break;
03820         }
03821         case MIB_RX2_CHANNEL :
03822         {
03823             LoRaMacParams.Rx2Channel  = mibSet->Param .Rx2Channel ;
03824             break;
03825         }
03826         case MIB_RX2_DEFAULT_CHANNEL :
03827         {
03828             LoRaMacParamsDefaults.Rx2Channel  = mibSet->Param .Rx2DefaultChannel ;
03829             break;
03830         }
03831         case MIB_CHANNELS_DEFAULT_MASK :
03832         {
03833             if( mibSet->Param .ChannelsDefaultMask  )
03834             {
03835 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03836                 bool chanMaskState = true;
03837 
03838 #if defined( USE_BAND_915_HYBRID )
03839                 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsDefaultMask  );
03840 #endif
03841                 if( chanMaskState == true )
03842                 {
03843                     if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) < 2 ) &&
03844                         ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) > 0 ) )
03845                     {
03846                         status = LORAMAC_STATUS_PARAMETER_INVALID ;
03847                     }
03848                     else
03849                     {
03850                         memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03851                                  ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask  ) );
03852                         for ( uint8_t i = 0; i < sizeof( LoRaMacParamsDefaults.ChannelsMask  ) / 2; i++ )
03853                         {
03854                             // Disable channels which are no longer available
03855                             ChannelsMaskRemaining[i] &= LoRaMacParamsDefaults.ChannelsMask [i];
03856                         }
03857                     }
03858                 }
03859                 else
03860                 {
03861                     status = LORAMAC_STATUS_PARAMETER_INVALID ;
03862                 }
03863 #elif defined( USE_BAND_470 )
03864                 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03865                          ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask  ) );
03866 #else
03867                 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03868                          ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , 2 );
03869 #endif
03870             }
03871             else
03872             {
03873                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03874             }
03875             break;
03876         }
03877         case MIB_CHANNELS_MASK :
03878         {
03879             if( mibSet->Param .ChannelsMask  )
03880             {
03881 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03882                 bool chanMaskState = true;
03883 
03884 #if defined( USE_BAND_915_HYBRID )
03885                 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsMask  );
03886 #endif
03887                 if( chanMaskState == true )
03888                 {
03889                     if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) < 2 ) &&
03890                         ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) > 0 ) )
03891                     {
03892                         status = LORAMAC_STATUS_PARAMETER_INVALID ;
03893                     }
03894                     else
03895                     {
03896                         memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03897                                  ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03898                         for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask  ) / 2; i++ )
03899                         {
03900                             // Disable channels which are no longer available
03901                             ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask [i];
03902                         }
03903                     }
03904                 }
03905                 else
03906                 {
03907                     status = LORAMAC_STATUS_PARAMETER_INVALID ;
03908                 }
03909 #elif defined( USE_BAND_470 )
03910                 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03911                          ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03912 #else
03913                 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03914                          ( uint8_t* ) mibSet->Param .ChannelsMask , 2 );
03915 #endif
03916             }
03917             else
03918             {
03919                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03920             }
03921             break;
03922         }
03923         case MIB_CHANNELS_NB_REP :
03924         {
03925             if( ( mibSet->Param .ChannelNbRep  >= 1 ) &&
03926                 ( mibSet->Param .ChannelNbRep  <= 15 ) )
03927             {
03928                 LoRaMacParams.ChannelsNbRep  = mibSet->Param .ChannelNbRep ;
03929             }
03930             else
03931             {
03932                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03933             }
03934             break;
03935         }
03936         case MIB_MAX_RX_WINDOW_DURATION :
03937         {
03938             LoRaMacParams.MaxRxWindow  = mibSet->Param .MaxRxWindow ;
03939             break;
03940         }
03941         case MIB_RECEIVE_DELAY_1 :
03942         {
03943             LoRaMacParams.ReceiveDelay1  = mibSet->Param .ReceiveDelay1 ;
03944             break;
03945         }
03946         case MIB_RECEIVE_DELAY_2 :
03947         {
03948             LoRaMacParams.ReceiveDelay2  = mibSet->Param .ReceiveDelay2 ;
03949             break;
03950         }
03951         case MIB_JOIN_ACCEPT_DELAY_1 :
03952         {
03953             LoRaMacParams.JoinAcceptDelay1  = mibSet->Param .JoinAcceptDelay1 ;
03954             break;
03955         }
03956         case MIB_JOIN_ACCEPT_DELAY_2 :
03957         {
03958             LoRaMacParams.JoinAcceptDelay2  = mibSet->Param .JoinAcceptDelay2 ;
03959             break;
03960         }
03961         case MIB_CHANNELS_DEFAULT_DATARATE :
03962         {
03963 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
03964             if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate ,
03965                               DR_0, DR_5 ) )
03966             {
03967                 LoRaMacParamsDefaults.ChannelsDatarate  = mibSet->Param .ChannelsDefaultDatarate ;
03968             }
03969 #else
03970             if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate ,
03971                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
03972             {
03973                 LoRaMacParamsDefaults.ChannelsDatarate  = mibSet->Param .ChannelsDefaultDatarate ;
03974             }
03975 #endif
03976             else
03977             {
03978                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03979             }
03980             break;
03981         }
03982         case MIB_CHANNELS_DATARATE :
03983         {
03984             if( ValueInRange( mibSet->Param .ChannelsDatarate ,
03985                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
03986             {
03987                 LoRaMacParams.ChannelsDatarate  = mibSet->Param .ChannelsDatarate ;
03988             }
03989             else
03990             {
03991                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03992             }
03993             break;
03994         }
03995         case MIB_CHANNELS_DEFAULT_TX_POWER :
03996         {
03997             if( ValueInRange( mibSet->Param .ChannelsDefaultTxPower ,
03998                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
03999             {
04000                 LoRaMacParamsDefaults.ChannelsTxPower  = mibSet->Param .ChannelsDefaultTxPower ;
04001             }
04002             else
04003             {
04004                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
04005             }
04006             break;
04007         }
04008         case MIB_CHANNELS_TX_POWER :
04009         {
04010             if( ValueInRange( mibSet->Param .ChannelsTxPower ,
04011                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
04012             {
04013                 LoRaMacParams.ChannelsTxPower  = mibSet->Param .ChannelsTxPower ;
04014             }
04015             else
04016             {
04017                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
04018             }
04019             break;
04020         }
04021         case MIB_UPLINK_COUNTER :
04022         {
04023             UpLinkCounter = mibSet->Param .UpLinkCounter ;
04024             break;
04025         }
04026         case MIB_DOWNLINK_COUNTER :
04027         {
04028             DownLinkCounter = mibSet->Param .DownLinkCounter ;
04029             break;
04030         }
04031         case MIB_SYSTEM_MAX_RX_ERROR :
04032         {
04033             LoRaMacParams.SystemMaxRxError  = LoRaMacParamsDefaults.SystemMaxRxError  = mibSet->Param .SystemMaxRxError ;
04034             break;
04035         }
04036         case MIB_MIN_RX_SYMBOLS :
04037         {
04038             LoRaMacParams.MinRxSymbols  = LoRaMacParamsDefaults.MinRxSymbols  = mibSet->Param .MinRxSymbols ;
04039             break;
04040         }
04041         default:
04042             status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04043             break;
04044     }
04045 
04046     return status;
04047 }
04048 
04049 LoRaMacStatus_t  LoRaMacChannelAdd( uint8_t id, ChannelParams_t  params )
04050 {
04051 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
04052     return LORAMAC_STATUS_PARAMETER_INVALID ;
04053 #else
04054     bool datarateInvalid = false;
04055     bool frequencyInvalid = false;
04056     uint8_t band = 0;
04057 
04058     // The id must not exceed LORA_MAX_NB_CHANNELS
04059     if( id >= LORA_MAX_NB_CHANNELS )
04060     {
04061         return LORAMAC_STATUS_PARAMETER_INVALID ;
04062     }
04063     // Validate if the MAC is in a correct state
04064     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04065     {
04066         if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
04067         {
04068             return LORAMAC_STATUS_BUSY ;
04069         }
04070     }
04071     // Validate the datarate
04072     if( ( params.DrRange .Fields.Min  > params.DrRange .Fields.Max  ) ||
04073         ( ValueInRange( params.DrRange .Fields.Min , LORAMAC_TX_MIN_DATARATE,
04074                         LORAMAC_TX_MAX_DATARATE ) == false ) ||
04075         ( ValueInRange( params.DrRange .Fields.Max , LORAMAC_TX_MIN_DATARATE,
04076                         LORAMAC_TX_MAX_DATARATE ) == false ) )
04077     {
04078         datarateInvalid = true;
04079     }
04080 
04081 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04082     if( id < 3 )
04083     {
04084         if( params.Frequency  != Channels[id].Frequency  )
04085         {
04086             frequencyInvalid = true;
04087         }
04088 
04089         if( params.DrRange .Fields.Min  > DR_0 )
04090         {
04091             datarateInvalid = true;
04092         }
04093         if( ValueInRange( params.DrRange .Fields.Max , DR_5, LORAMAC_TX_MAX_DATARATE ) == false )
04094         {
04095             datarateInvalid = true;
04096         }
04097     }
04098 #endif
04099 
04100     // Validate the frequency
04101     if( ( Radio .CheckRfFrequency( params.Frequency  ) == true ) && ( params.Frequency  > 0 ) && ( frequencyInvalid == false ) )
04102     {
04103 #if defined( USE_BAND_868 )
04104         if( ( params.Frequency  >= 863000000 ) && ( params.Frequency  < 865000000 ) )
04105         {
04106             band = BAND_G1_2;
04107         }
04108         else if( ( params.Frequency  >= 865000000 ) && ( params.Frequency  <= 868000000 ) )
04109         {
04110             band = BAND_G1_0;
04111         }
04112         else if( ( params.Frequency  > 868000000 ) && ( params.Frequency  <= 868600000 ) )
04113         {
04114             band = BAND_G1_1;
04115         }
04116         else if( ( params.Frequency  >= 868700000 ) && ( params.Frequency  <= 869200000 ) )
04117         {
04118             band = BAND_G1_2;
04119         }
04120         else if( ( params.Frequency  >= 869400000 ) && ( params.Frequency  <= 869650000 ) )
04121         {
04122             band = BAND_G1_3;
04123         }
04124         else if( ( params.Frequency  >= 869700000 ) && ( params.Frequency  <= 870000000 ) )
04125         {
04126             band = BAND_G1_4;
04127         }
04128         else
04129         {
04130             frequencyInvalid = true;
04131         }
04132 #endif
04133     }
04134     else
04135     {
04136         frequencyInvalid = true;
04137     }
04138 
04139     if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
04140     {
04141         return LORAMAC_STATUS_FREQ_AND_DR_INVALID ;
04142     }
04143     if( datarateInvalid == true )
04144     {
04145         return LORAMAC_STATUS_DATARATE_INVALID ;
04146     }
04147     if( frequencyInvalid == true )
04148     {
04149         return LORAMAC_STATUS_FREQUENCY_INVALID ;
04150     }
04151 
04152     // Every parameter is valid, activate the channel
04153     Channels[id] = params;
04154     Channels[id].Band  = band;
04155     LoRaMacParams.ChannelsMask [0] |= ( 1 << id );
04156 
04157     return LORAMAC_STATUS_OK ;
04158 #endif
04159 }
04160 
04161 LoRaMacStatus_t  LoRaMacChannelRemove( uint8_t id )
04162 {
04163 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04164     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04165     {
04166         if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
04167         {
04168             return LORAMAC_STATUS_BUSY ;
04169         }
04170     }
04171 
04172     if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
04173     {
04174         return LORAMAC_STATUS_PARAMETER_INVALID ;
04175     }
04176     else
04177     {
04178         // Remove the channel from the list of channels
04179         Channels[id] = ( ChannelParams_t  ){ 0, { 0 }, 0 };
04180 
04181         // Disable the channel as it doesn't exist anymore
04182         if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask  ) == false )
04183         {
04184             return LORAMAC_STATUS_PARAMETER_INVALID ;
04185         }
04186     }
04187     return LORAMAC_STATUS_OK ;
04188 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) || defined( USE_BAND_470 ) )
04189     return LORAMAC_STATUS_PARAMETER_INVALID ;
04190 #endif
04191 }
04192 
04193 LoRaMacStatus_t  LoRaMacMulticastChannelLink( MulticastParams_t  *channelParam )
04194 {
04195     if( channelParam == NULL )
04196     {
04197         return LORAMAC_STATUS_PARAMETER_INVALID ;
04198     }
04199     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04200     {
04201         return LORAMAC_STATUS_BUSY ;
04202     }
04203 
04204     // Reset downlink counter
04205     channelParam->DownLinkCounter  = 0;
04206 
04207     if( MulticastChannels == NULL )
04208     {
04209         // New node is the fist element
04210         MulticastChannels = channelParam;
04211     }
04212     else
04213     {
04214         MulticastParams_t  *cur = MulticastChannels;
04215 
04216         // Search the last node in the list
04217         while( cur->Next  != NULL )
04218         {
04219             cur = cur->Next ;
04220         }
04221         // This function always finds the last node
04222         cur->Next  = channelParam;
04223     }
04224 
04225     return LORAMAC_STATUS_OK ;
04226 }
04227 
04228 LoRaMacStatus_t  LoRaMacMulticastChannelUnlink( MulticastParams_t  *channelParam )
04229 {
04230     if( channelParam == NULL )
04231     {
04232         return LORAMAC_STATUS_PARAMETER_INVALID ;
04233     }
04234     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04235     {
04236         return LORAMAC_STATUS_BUSY ;
04237     }
04238 
04239     if( MulticastChannels != NULL )
04240     {
04241         if( MulticastChannels == channelParam )
04242         {
04243           // First element
04244           MulticastChannels = channelParam->Next ;
04245         }
04246         else
04247         {
04248             MulticastParams_t  *cur = MulticastChannels;
04249 
04250             // Search the node in the list
04251             while( cur->Next  && cur->Next  != channelParam )
04252             {
04253                 cur = cur->Next ;
04254             }
04255             // If we found the node, remove it
04256             if( cur->Next  )
04257             {
04258                 cur->Next  = channelParam->Next ;
04259             }
04260         }
04261         channelParam->Next  = NULL;
04262     }
04263 
04264     return LORAMAC_STATUS_OK ;
04265 }
04266 
04267 LoRaMacStatus_t  LoRaMacMlmeRequest( MlmeReq_t  *mlmeRequest )
04268 {
04269     LoRaMacStatus_t  status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04270     LoRaMacHeader_t  macHdr;
04271 
04272     if( mlmeRequest == NULL )
04273     {
04274         return LORAMAC_STATUS_PARAMETER_INVALID ;
04275     }
04276     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04277     {
04278         return LORAMAC_STATUS_BUSY ;
04279     }
04280 
04281     memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) );
04282 
04283     MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ;
04284 
04285     switch( mlmeRequest->Type  )
04286     {
04287         case MLME_JOIN :
04288         {
04289             if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED )
04290             {
04291                 return LORAMAC_STATUS_BUSY ;
04292             }
04293 
04294             if( ( mlmeRequest->Req.Join .DevEui  == NULL ) ||
04295                 ( mlmeRequest->Req.Join .AppEui  == NULL ) ||
04296                 ( mlmeRequest->Req.Join .AppKey  == NULL ) ||
04297                 ( mlmeRequest->Req.Join .NbTrials  == 0 ) )
04298             {
04299                 return LORAMAC_STATUS_PARAMETER_INVALID ;
04300             }
04301 
04302 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
04303             // Enables at least the usage of the 2 datarates.
04304             if( mlmeRequest->Req.Join .NbTrials  < 2 )
04305             {
04306                 mlmeRequest->Req.Join .NbTrials  = 2;
04307             }
04308 #else
04309             // Enables at least the usage of all datarates.
04310             if( mlmeRequest->Req.Join .NbTrials  < 48 )
04311             {
04312                 mlmeRequest->Req.Join .NbTrials  = 48;
04313             }
04314 #endif
04315 
04316             LoRaMacFlags.Bits.MlmeReq  = 1;
04317             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04318 
04319             LoRaMacDevEui = mlmeRequest->Req.Join .DevEui ;
04320             LoRaMacAppEui = mlmeRequest->Req.Join .AppEui ;
04321             LoRaMacAppKey = mlmeRequest->Req.Join .AppKey ;
04322             MaxJoinRequestTrials = mlmeRequest->Req.Join .NbTrials ;
04323 
04324             // Reset variable JoinRequestTrials
04325             JoinRequestTrials = 0;
04326 
04327             // Setup header information
04328             macHdr.Value  = 0;
04329             macHdr.Bits.MType   = FRAME_TYPE_JOIN_REQ ;
04330 
04331             ResetMacParameters( );
04332 
04333             // Add a +1, since we start to count from 0
04334             LoRaMacParams.ChannelsDatarate  = AlternateDatarate( JoinRequestTrials + 1 );
04335 
04336             status = Send( &macHdr, 0, NULL, 0 );
04337             break;
04338         }
04339         case MLME_LINK_CHECK :
04340         {
04341             LoRaMacFlags.Bits.MlmeReq  = 1;
04342             // LoRaMac will send this command piggy-pack
04343             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04344 
04345             status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ , 0, 0 );
04346             break;
04347         }
04348         case MLME_TXCW :
04349         {
04350             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04351             LoRaMacFlags.Bits.MlmeReq  = 1;
04352             status = SetTxContinuousWave( mlmeRequest->Req.TxCw .Timeout  );
04353             break;
04354         }
04355         case MLME_TXCW_1 :
04356         {
04357             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04358             LoRaMacFlags.Bits.MlmeReq  = 1;
04359             status = SetTxContinuousWave1( mlmeRequest->Req.TxCw .Timeout , mlmeRequest->Req.TxCw .Frequency , mlmeRequest->Req.TxCw .Power  );
04360             break;
04361         }
04362         default:
04363             break;
04364     }
04365 
04366     if( status != LORAMAC_STATUS_OK  )
04367     {
04368         NodeAckRequested = false;
04369         LoRaMacFlags.Bits.MlmeReq  = 0;
04370     }
04371 
04372     return status;
04373 }
04374 
04375 LoRaMacStatus_t  LoRaMacMcpsRequest( McpsReq_t  *mcpsRequest )
04376 {
04377     LoRaMacStatus_t  status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04378     LoRaMacHeader_t  macHdr;
04379     uint8_t fPort = 0;
04380     void *fBuffer;
04381     uint16_t fBufferSize;
04382     int8_t datarate;
04383     bool readyToSend = false;
04384 
04385     if( mcpsRequest == NULL )
04386     {
04387         return LORAMAC_STATUS_PARAMETER_INVALID ;
04388     }
04389     if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) ||
04390         ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) )
04391     {
04392         return LORAMAC_STATUS_BUSY ;
04393     }
04394 
04395     macHdr.Value  = 0;
04396     memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) );
04397     McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ;
04398 
04399     switch( mcpsRequest->Type  )
04400     {
04401         case MCPS_UNCONFIRMED :
04402         {
04403             readyToSend = true;
04404             AckTimeoutRetries = 1;
04405 
04406             macHdr.Bits.MType  = FRAME_TYPE_DATA_UNCONFIRMED_UP ;
04407             fPort = mcpsRequest->Req.Unconfirmed .fPort ;
04408             fBuffer = mcpsRequest->Req.Unconfirmed .fBuffer ;
04409             fBufferSize = mcpsRequest->Req.Unconfirmed .fBufferSize ;
04410             datarate = mcpsRequest->Req.Unconfirmed .Datarate ;
04411             break;
04412         }
04413         case MCPS_CONFIRMED :
04414         {
04415             readyToSend = true;
04416             AckTimeoutRetriesCounter = 1;
04417             AckTimeoutRetries = mcpsRequest->Req.Confirmed .NbTrials ;
04418 
04419             macHdr.Bits.MType  = FRAME_TYPE_DATA_CONFIRMED_UP ;
04420             fPort = mcpsRequest->Req.Confirmed .fPort ;
04421             fBuffer = mcpsRequest->Req.Confirmed .fBuffer ;
04422             fBufferSize = mcpsRequest->Req.Confirmed .fBufferSize ;
04423             datarate = mcpsRequest->Req.Confirmed .Datarate ;
04424             break;
04425         }
04426         case MCPS_PROPRIETARY :
04427         {
04428             readyToSend = true;
04429             AckTimeoutRetries = 1;
04430 
04431             macHdr.Bits.MType  = FRAME_TYPE_PROPRIETARY ;
04432             fBuffer = mcpsRequest->Req.Proprietary .fBuffer ;
04433             fBufferSize = mcpsRequest->Req.Proprietary .fBufferSize ;
04434             datarate = mcpsRequest->Req.Proprietary .Datarate ;
04435             break;
04436         }
04437         default:
04438             break;
04439     }
04440 
04441     if( readyToSend == true )
04442     {
04443         if( AdrCtrlOn == false )
04444         {
04445             if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true )
04446             {
04447                 LoRaMacParams.ChannelsDatarate  = datarate;
04448             }
04449             else
04450             {
04451                 return LORAMAC_STATUS_PARAMETER_INVALID ;
04452             }
04453         }
04454 
04455         status = Send( &macHdr, fPort, fBuffer, fBufferSize );
04456         if( status == LORAMAC_STATUS_OK  )
04457         {
04458             McpsConfirm.McpsRequest = mcpsRequest->Type ;
04459             LoRaMacFlags.Bits.McpsReq  = 1;
04460         }
04461         else
04462         {
04463             NodeAckRequested = false;
04464         }
04465     }
04466 
04467     return status;
04468 }
04469 
04470 void LoRaMacTestRxWindowsOn( bool enable )
04471 {
04472     IsRxWindowsEnabled = enable;
04473 }
04474 
04475 void LoRaMacTestSetMic( uint16_t txPacketCounter )
04476 {
04477     UpLinkCounter = txPacketCounter;
04478     IsUpLinkCounterFixed = true;
04479 }
04480 
04481 void LoRaMacTestSetDutyCycleOn( bool enable )
04482 {
04483 #if ( defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) )
04484     DutyCycleOn = enable;
04485 #else
04486     DutyCycleOn = false;
04487 #endif
04488 }
04489 
04490 void LoRaMacTestSetChannel( uint8_t channel )
04491 {
04492     Channel = channel;
04493 }
04494 
04495 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError )
04496 {
04497     RxConfigParams_t rxConfigParams = { 0, 0, 0, 0 };
04498     double tSymbol = 0.0;
04499 
04500     rxConfigParams.Datarate = datarate;
04501     switch( Bandwidths[datarate] )
04502     {
04503         default:
04504         case 125000:
04505             rxConfigParams.Bandwidth = 0;
04506             break;
04507         case 250000:
04508             rxConfigParams.Bandwidth = 1;
04509             break;
04510         case 500000:
04511             rxConfigParams.Bandwidth = 2;
04512             break;
04513     }
04514 
04515 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04516     if( datarate == DR_7 )
04517     { // FSK
04518         tSymbol = ( 1.0 / ( double )Datarates[datarate] ) * 8.0; // 1 symbol equals 1 byte
04519     }
04520     else
04521 #endif
04522     { // LoRa
04523         tSymbol = ( ( double )( 1 << Datarates[datarate] ) / ( double )Bandwidths[datarate] ) * 1e3;
04524     }
04525 
04526     rxConfigParams.RxWindowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * LoRaMacParams.MinRxSymbols  - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), LoRaMacParams.MinRxSymbols  ); // Computed number of symbols
04527 
04528     rxConfigParams.RxOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( rxConfigParams.RxWindowTimeout * tSymbol ) / 2.0 ) - RADIO_WAKEUP_TIME );
04529 
04530     return rxConfigParams;
04531 }