Espotel / Mbed 2 deprecated LoRaWAN_ELMO_TxRx_Template

Dependencies:   SX1272lib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMac.cpp Source File

LoRaMac.cpp

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