Bill VerSteeg / LoRaWAN-lib

Fork of LoRaWAN-lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMac.cpp Source File

LoRaMac.cpp

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