Espotel / Mbed 2 deprecated LoRaWAN_Semtech_stack

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 Description: LoRa MAC layer implementation
00009 License: Revised BSD License, see LICENSE.TXT file include in the project
00010 Maintainer: Miguel Luis and Gregory Cristian
00011 */
00012 
00013 #include "mbed.h"
00014 #include "LoRaMacCrypto.h"
00015 #include "LoRaMac.h"
00016 #include "sx1272.h"
00017 #include "sx1272Regs-LoRa.h"
00018 #include "utilities.h"
00019 #include "sx1272-hal.h"
00020 #define USE_BAND_868
00021 /*!
00022  * Maximum PHY layer payload size
00023  */
00024 #define LORAMAC_PHY_MAXPAYLOAD                      255
00025 
00026 typedef uint64_t TimerTime_t;
00027 
00028 /*!
00029  * Device IEEE EUI
00030  */
00031 static uint8_t *LoRaMacDevEui;
00032 
00033 /*!
00034  * Application IEEE EUI
00035  */
00036 static uint8_t *LoRaMacAppEui;
00037 
00038 /*!
00039  * AES encryption/decryption cipher application key
00040  */
00041 static uint8_t *LoRaMacAppKey;
00042 
00043 /*!
00044  * AES encryption/decryption cipher network session key
00045  */
00046 static uint8_t LoRaMacNwkSKey[] =
00047 {
00048     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00049     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00050 };
00051 
00052 /*!
00053  * AES encryption/decryption cipher application session key
00054  */
00055 static uint8_t LoRaMacAppSKey[] =
00056 {
00057     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00058     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00059 };
00060 
00061 /*!
00062  * Device nonce is a random value extracted by issuing a sequence of RSSI
00063  * measurements
00064  */
00065 static uint16_t LoRaMacDevNonce;
00066 
00067 /*!
00068  * Network ID ( 3 bytes )
00069  */
00070 static uint32_t LoRaMacNetID;
00071 
00072 /*!
00073  * Mote Address
00074  */
00075 static uint32_t LoRaMacDevAddr;
00076 
00077 /*!
00078  * Mutlicast channels linked list
00079  */
00080 static MulticastParams_t *MulticastChannels = NULL;
00081 
00082 /*!
00083  * Actual device class
00084  */
00085 static DeviceClass_t LoRaMacDeviceClass;
00086 
00087 /*!
00088  * Indicates if the node is connected to a private or public network
00089  */
00090 static bool PublicNetwork;
00091 
00092 /*!
00093  * Indicates if the node supports repeaters
00094  */
00095 static bool RepeaterSupport;
00096 
00097 /*!
00098  * Buffer containing the data to be sent or received.
00099  */
00100 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD];
00101 
00102 /*!
00103  * Length of packet in LoRaMacBuffer
00104  */
00105 static uint16_t LoRaMacBufferPktLen = 0;
00106 
00107 /*!
00108  * Buffer containing the upper layer data.
00109  */
00110 static uint8_t LoRaMacPayload[LORAMAC_PHY_MAXPAYLOAD];
00111 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD];
00112 
00113 /*!
00114  * LoRaMAC frame counter. Each time a packet is sent the counter is incremented.
00115  * Only the 16 LSB bits are sent
00116  */
00117 static uint32_t UpLinkCounter = 1;
00118 
00119 /*!
00120  * LoRaMAC frame counter. Each time a packet is received the counter is incremented.
00121  * Only the 16 LSB bits are received
00122  */
00123 static uint32_t DownLinkCounter = 0;
00124 
00125 /*!
00126  * IsPacketCounterFixed enables the MIC field tests by fixing the
00127  * UpLinkCounter value
00128  */
00129 static bool IsUpLinkCounterFixed = false;
00130 
00131 /*!
00132  * Used for test purposes. Disables the opening of the reception windows.
00133  */
00134 static bool IsRxWindowsEnabled = true;
00135 
00136 /*!
00137  * Indicates if the MAC layer has already joined a network.
00138  */
00139 static bool IsLoRaMacNetworkJoined = false;
00140 
00141 /*!
00142  * LoRaMac ADR control status
00143  */
00144 static bool AdrCtrlOn = false;
00145 
00146 /*!
00147  * Counts the number of missed ADR acknowledgements
00148  */
00149 static uint32_t AdrAckCounter = 0;
00150 
00151 /*!
00152  * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates
00153  * if the nodes needs to manage the server acknowledgement.
00154  */
00155 static bool NodeAckRequested = false;
00156 
00157 /*!
00158  * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates
00159  * if the ACK bit must be set for the next transmission
00160  */
00161 static bool SrvAckRequested = false;
00162 
00163 /*!
00164  * Indicates if the MAC layer wants to send MAC commands
00165  */
00166 static bool MacCommandsInNextTx = false;
00167 
00168 /*!
00169  * Contains the current MacCommandsBuffer index
00170  */
00171 static uint8_t MacCommandsBufferIndex = 0;
00172 
00173 /*!
00174  * Buffer containing the MAC layer commands
00175  */
00176 static uint8_t MacCommandsBuffer[15];
00177 
00178 #if defined( USE_BAND_433 )
00179 /*!
00180  * Data rates table definition
00181  */
00182 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00183 
00184 /*!
00185  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00186  */
00187 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 };
00188 
00189 /*!
00190  * Maximum payload with respect to the datarate index. Can operate with repeater.
00191  */
00192 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 };
00193 
00194 /*!
00195  * Tx output powers table definition
00196  */
00197 const int8_t TxPowers[]    = { 20, 14, 11,  8,  5,  2 };
00198 
00199 /*!
00200  * LoRaMac bands
00201  */
00202 static Band_t Bands[LORA_MAX_NB_BANDS] =
00203 {
00204     BAND0,
00205 };
00206 
00207 /*!
00208  * LoRaMAC channels
00209  */
00210 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
00211 {
00212     LC1,
00213     LC2,
00214     LC3,
00215 };
00216 #elif defined( USE_BAND_780 )
00217 /*!
00218  * Data rates table definition
00219  */
00220 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00221 
00222 /*!
00223  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00224  */
00225 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 };
00226 
00227 /*!
00228  * Maximum payload with respect to the datarate index. Can operate with repeater.
00229  */
00230 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 };
00231 
00232 /*!
00233  * Tx output powers table definition
00234  */
00235 const int8_t TxPowers[]    = { 20, 14, 11,  8,  5,  2 };
00236 
00237 /*!
00238  * LoRaMac bands
00239  */
00240 static Band_t Bands[LORA_MAX_NB_BANDS] =
00241 {
00242     BAND0,
00243 };
00244 
00245 /*!
00246  * LoRaMAC channels
00247  */
00248 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
00249 {
00250     LC1,
00251     LC2,
00252     LC3,
00253 };
00254 #elif defined( USE_BAND_868 )
00255 /*!
00256  * Data rates table definition
00257  */
00258 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00259 
00260 /*!
00261  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00262  */
00263 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
00264 
00265 /*!
00266  * Maximum payload with respect to the datarate index. Can operate with repeater.
00267  */
00268 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
00269 
00270 /*!
00271  * Tx output powers table definition
00272  */
00273 const int8_t TxPowers[]    = { 20, 14, 11,  8,  5,  2 };
00274 
00275 /*!
00276  * LoRaMac bands
00277  */
00278 static Band_t Bands[LORA_MAX_NB_BANDS] =
00279 {
00280     BAND0,
00281     BAND1,
00282     BAND2,
00283     BAND3,
00284     BAND4,
00285 };
00286 
00287 /*!
00288  * LoRaMAC channels
00289  */
00290 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
00291 {
00292     LC1,
00293     LC2,
00294     LC3,
00295     LC4,
00296     LC5,
00297     LC6,
00298     LC7,
00299     LC8,
00300     LC9,
00301 };
00302 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00303 /*!
00304  * Data rates table definition
00305  */
00306 const uint8_t Datarates[]  = { 10, 9, 8,  7,  8,  0,  0, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
00307 
00308 /*!
00309  * Up/Down link data rates offset definition
00310  */
00311 const int8_t datarateOffsets[16][4] = 
00312 {
00313     { DR_10, DR_9 , DR_8 , DR_8  }, // DR_0
00314     { DR_11, DR_10, DR_9 , DR_8  }, // DR_1
00315     { DR_12, DR_11, DR_10, DR_9  }, // DR_2
00316     { DR_13, DR_12, DR_11, DR_10 }, // DR_3
00317     { DR_13, DR_13, DR_12, DR_11 }, // DR_4
00318     { 0xFF , 0xFF , 0xFF , 0xFF  },
00319     { 0xFF , 0xFF , 0xFF , 0xFF  },
00320     { 0xFF , 0xFF , 0xFF , 0xFF  },
00321     { DR_8 , DR_8 , DR_8 , DR_8  },
00322     { DR_9 , DR_8 , DR_8 , DR_8  },
00323     { DR_10, DR_9 , DR_8 , DR_8  },
00324     { DR_11, DR_10, DR_9 , DR_8  },
00325     { DR_12, DR_11, DR_10, DR_9  },
00326     { DR_13, DR_12, DR_11, DR_10 },
00327     { 0xFF , 0xFF , 0xFF , 0xFF  },
00328     { 0xFF , 0xFF , 0xFF , 0xFF  },
00329 };
00330 
00331 /*!
00332  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00333  */
00334 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 129, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
00335 
00336 /*!
00337  * Maximum payload with respect to the datarate index. Can operate with repeater.
00338  */
00339 const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 129, 242, 242, 0, 0, 0, 33, 103, 222, 222, 222, 222, 0, 0 };
00340 
00341 /*!
00342  * Tx output powers table definition
00343  */
00344 const int8_t TxPowers[]    = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 };
00345 
00346 /*!
00347  * LoRaMac bands
00348  */
00349 static Band_t Bands[LORA_MAX_NB_BANDS] =
00350 {
00351     BAND0,
00352 };
00353 
00354 /*!
00355  * LoRaMAC channels
00356  */
00357 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS];
00358 
00359 #else
00360     #error "Please define a frequency band in the compiler options."
00361 #endif
00362 
00363 /*!
00364  * LoRaMAC 2nd reception window settings
00365  */
00366 static Rx2ChannelParams_t Rx2Channel = RX_WND_2_CHANNEL;
00367 
00368 /*!
00369  * Datarate offset between uplink and downlink on first window
00370  */
00371 static uint8_t Rx1DrOffset = 0;
00372 
00373 /*!
00374  * Mask indicating which channels are enabled
00375  */
00376 static uint16_t ChannelsMask[6];
00377 
00378 /*!
00379  * Channels Tx output power
00380  */
00381 static int8_t ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
00382 
00383 /*!
00384  * Channels datarate
00385  */
00386 static int8_t ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
00387 
00388 /*!
00389  * Channels default datarate
00390  */
00391 static int8_t ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE;
00392 
00393 /*!
00394  * Number of uplink messages repetitions [1:15] (unconfirmed messages only)
00395  */
00396 static uint8_t ChannelsNbRep = 1;
00397 
00398 /*!
00399  * Uplink messages repetitions counter
00400  */
00401 static uint8_t ChannelsNbRepCounter = 0;
00402 
00403 /*!
00404  * Maximum duty cycle
00405  * \remark Possibility to shutdown the device.
00406  */
00407 static uint8_t MaxDCycle = 0;
00408 
00409 /*!
00410  * Agregated duty cycle management
00411  */
00412 static uint16_t AggregatedDCycle;
00413 static TimerTime_t AggregatedLastTxDoneTime;
00414 static TimerTime_t AggregatedTimeOff;
00415 
00416 /*!
00417  * Enables/Disables duty cycle management (Test only)
00418  */
00419 static bool DutyCycleOn;
00420 
00421 /*!
00422  * Current channel index
00423  */
00424 static uint8_t Channel;
00425 
00426 /*!
00427  * LoRaMac internal states
00428  */
00429 enum LoRaMacState_e
00430 {
00431     MAC_IDLE          = 0x00000000,
00432     MAC_TX_RUNNING    = 0x00000001,
00433     MAC_RX            = 0x00000002,
00434     MAC_ACK_REQ       = 0x00000004,
00435     MAC_ACK_RETRY     = 0x00000008,
00436     MAC_CHANNEL_CHECK = 0x00000010,
00437 };
00438 
00439 /*!
00440  * LoRaMac internal state
00441  */
00442 uint32_t LoRaMacState = MAC_IDLE;
00443 
00444 /*!
00445  * LoRaMac upper layer event functions
00446  */
00447 static LoRaMacCallbacks_t  *LoRaMacCallbacks;
00448 
00449 /*!
00450  * LoRaMac notification event flags
00451  */
00452 LoRaMacEventFlags_t  LoRaMacEventFlags;
00453 
00454 /*!
00455  * LoRaMac notification event info
00456  */
00457 LoRaMacEventInfo_t  LoRaMacEventInfo;
00458 
00459 /*!
00460  * LoRaMac channel check timer
00461  */
00462 //static Timeout ChannelCheckTimer;
00463 
00464 /*!
00465  * LoRaMac duty cycle delayed Tx timer
00466  */
00467 //static Timeout TxDelayedTimer;
00468 
00469 /*!
00470  * LoRaMac reception windows timers
00471  */
00472 //static RtosTimer RxWindowTimer1;
00473 //static RtosTimer RxWindowTimer2;
00474 
00475 /*!
00476  * LoRaMac reception windows delay from end of Tx
00477  */
00478 static uint32_t ReceiveDelay1;
00479 static uint32_t ReceiveDelay2;
00480 static uint32_t JoinAcceptDelay1;
00481 static uint32_t JoinAcceptDelay2;
00482 
00483 /*!
00484  * LoRaMac reception windows delay
00485  * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME
00486  *         join frame  : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME
00487  */
00488 static uint32_t RxWindow1Delay;
00489 static uint32_t RxWindow2Delay;
00490 
00491 /*!
00492  * LoRaMac maximum time a reception window stays open
00493  */
00494 static uint32_t MaxRxWindow;
00495 
00496 /*!
00497  * Acknowledge timeout timer. Used for packet retransmissions.
00498  */
00499 
00500 
00501 /*!
00502  * Number of trials to get a frame acknowledged
00503  */
00504 static uint8_t AckTimeoutRetries = 1;
00505 
00506 /*!
00507  * Number of trials to get a frame acknowledged
00508  */
00509 static uint8_t AckTimeoutRetriesCounter = 1;
00510 
00511 /*!
00512  * Indicates if the AckTimeout timer has expired or not
00513  */
00514 static bool AckTimeoutRetry = false;
00515 
00516 /*!
00517  * Last transmission time on air
00518  */
00519 TimerTime_t TxTimeOnAir = 0;
00520 
00521 /*!
00522  * Function to be executed on Radio Tx Done event
00523  */
00524 static void OnRadioTxDone( void );
00525 
00526 /*!
00527  * Function to be executed on Radio Rx Done event
00528  */
00529 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
00530 
00531 /*!
00532  * Function executed on Radio Tx Timeout event
00533  */
00534 static void OnRadioTxTimeout( void );
00535 
00536 /*!
00537  * Function executed on Radio Rx error event
00538  */
00539 static void OnRadioRxError( void );
00540 
00541 /*!
00542  * Function executed on Radio Rx Timeout event
00543  */
00544 static void OnRadioRxTimeout( void );
00545 
00546 /*!
00547  * Function executed on Resend Frame timer event.
00548  */
00549 static void OnMacStateCheckTimerEvent(void);
00550 
00551 /*!
00552  * Function executed on duty cycle delayed Tx  timer event
00553  */
00554 static void OnTxDelayedTimerEvent( void );
00555 
00556 /*!
00557  * Function executed on channel check timer event
00558  */
00559 static void OnChannelCheckTimerEvent( void );
00560 
00561 /*!
00562  * Function executed on first Rx window timer event
00563  */
00564 static void OnRxWindow1TimerEvent(void);
00565 
00566 /*!
00567  * Function executed on second Rx window timer event
00568  */
00569 static void OnRxWindow2TimerEvent(void);
00570 
00571 /*!
00572  * Function executed on AckTimeout timer event
00573  */
00574 static void OnAckTimeoutTimerEvent(void);
00575 
00576 /*!
00577  * Radio events function pointer
00578  */
00579 //RadioEvents_t RadioEvents;
00580 
00581 //Radio *radio;
00582 
00583 SX1272BRD radio( OnRadioTxDone, OnRadioTxTimeout, OnRadioRxDone, OnRadioRxTimeout, OnRadioRxError, NULL, NULL,
00584                RF_SPI_MOSI, RF_SPI_MISO, RF_SPI_SCK, RF_SPI_CS,
00585                RF_RESET, RF_DIO0, RF_DIO1, RF_DIO2, RF_DIO3, RF_DIO4, RF_DIO5, RF_RXTX_SW );
00586 
00587 static Timeout AckTimeoutTimer;
00588 static Timeout MacStateCheckTimer;
00589 static Timeout TxDelayedTimer;
00590 static Timeout ChannelCheckTimer;
00591 static Timeout RxWindowTimer1;
00592 static Timeout RxWindowTimer2;
00593 
00594 //static RtosTimer AckTimeoutTimer(OnAckTimeoutTimerEvent, osTimerOnce);
00595 /*!
00596  * LoRaMac timer used to check the LoRaMacState (runs every second)
00597  */
00598 //static RtosTimer MacStateCheckTimer(OnMacStateCheckTimerEvent, osTimerPeriodic);
00599 
00600 /*!
00601  * LoRaMac channel check timer
00602  */
00603 //static RtosTimer TxDelayedTimer(OnTxDelayedTimerEvent, osTimerOnce);
00604 
00605 /*!
00606  * LoRaMac duty cycle delayed Tx timer
00607  */
00608 //static RtosTimer ChannelCheckTimer(OnChannelCheckTimerEvent, osTimerOnce);
00609 
00610 /*!
00611  * LoRaMac reception windows timers
00612  */
00613 //static RtosTimer RxWindowTimer1(OnRxWindow1TimerEvent, osTimerOnce);
00614 //static RtosTimer RxWindowTimer2(OnRxWindow2TimerEvent, osTimerOnce);
00615 
00616 /*
00617 * General purpose timer - time since startup
00618 */
00619 static Timer timerGeneralPurpose;
00620 
00621 /*!
00622  * \brief Validates if the payload fits into the frame, taking the datarate
00623  *        into account.
00624  *
00625  * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0
00626  *
00627  * \param lenN Length of the application payload. The length depends on the
00628  *             datarate and is region specific
00629  *
00630  * \param datarate Current datarate
00631  *
00632  * \retval [false: payload does not fit into the frame, true: payload fits into
00633  *          the frame]
00634  */
00635 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate );
00636 
00637 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00638 /*!
00639  * \brief Counts the number of enabled 125 kHz channels in the channel mask.
00640  *        This function can only be applied to US915 band.
00641  *
00642  * \param channelsMask Pointer to the first element of the channel mask
00643  *
00644  * \retval Number of enabled channels in the channel mask
00645  */
00646 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask );
00647 #endif
00648 
00649 /*!
00650  * \brief Limits the Tx power according to the number of enabled channels
00651  *
00652  * \retval Returns the maximum valid tx power
00653  */
00654 static int8_t LimitTxPower( int8_t txPower );
00655 
00656 
00657 /*!
00658  * Searches and set the next random available channel
00659  *
00660  * \retval status  Function status [0: OK, 1: Unable to find a free channel]
00661  */
00662 static uint8_t LoRaMacSetNextChannel( void )
00663 {
00664     uint8_t i = 0;
00665     uint8_t j = 0;
00666     uint8_t k = 0;
00667     uint8_t nbEnabledChannels = 0;
00668     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
00669     //TimerTime_t curTime = TimerGetCurrentTime( );
00670     TimerTime_t curTime = timerGeneralPurpose.read_us();
00671 
00672     //printf("LoRaMacSetNextChannel %llu \r\n", curTime);
00673 
00674     memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
00675 
00676     // Update Aggregated duty cycle
00677     if( AggregatedTimeOff < ( curTime - AggregatedLastTxDoneTime ) )
00678     {
00679         AggregatedTimeOff = 0;
00680     }
00681 
00682     // Update bands Time OFF
00683     TimerTime_t minTime = ( TimerTime_t )( -1 );
00684     for( i = 0; i < LORA_MAX_NB_BANDS; i++ )
00685     {
00686         if( DutyCycleOn == true )
00687         {
00688             if( Bands[i].TimeOff < ( curTime - Bands[i].LastTxDoneTime ) )
00689             {
00690                 //printf("DutyCycleOn 1\r\n");
00691                 Bands[i].TimeOff = 0;
00692             }
00693             if( Bands[i].TimeOff != 0 )
00694             {
00695                 minTime = MIN( Bands[i].TimeOff, minTime );
00696                 //printf("DutyCycleOn 2 %llu\r\n", minTime);
00697             }
00698         }
00699         else
00700         {
00701             printf("DutyCycleOn off\r\n");
00702             minTime = 0;
00703             Bands[i].TimeOff = 0;
00704         }
00705     }
00706 
00707     // Search how many channels are enabled
00708     for( i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
00709     {
00710         for( j = 0; j < 16; j++ )
00711         {
00712             if( ( ChannelsMask[k] & ( 1 << j ) ) != 0 )
00713             {
00714                 if( Channels[i + j].Frequency == 0 )
00715                 { // Check if the channel is enabled
00716                     //printf("DutyCycleOn Check if the channel is enabled\r\n");
00717                     continue;
00718                 }
00719                 if( ( ( Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate ) &&
00720                       ( ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
00721                 { // Check if the current channel selection supports the given datarate
00722                     //printf("DutyCycleOn Check if the current channel selection supports the given datarate\r\n");
00723                     continue;
00724                 }
00725                 if( Bands[Channels[i + j].Band].TimeOff > 0 )
00726                 { // Check if the band is available for transmission
00727                     //printf("DutyCycleOn CCheck if the band is available for transmission\r\n");
00728                     continue;
00729                 }
00730                 if( AggregatedTimeOff > 0 )
00731                 { // Check if there is time available for transmission
00732                     //printf("DutyCycleOn Check if there is time available for transmission\r\n");
00733                     continue;
00734                 }
00735                 enabledChannels[nbEnabledChannels++] = i + j;
00736                 printf("Enabled channels %i\r\n", enabledChannels[nbEnabledChannels-1]);
00737             }
00738         }
00739     }
00740     if( nbEnabledChannels > 0 )
00741     {
00742         Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
00743         LoRaMacState &= ~MAC_CHANNEL_CHECK;
00744         //TimerStop( &ChannelCheckTimer );
00745         //ChannelCheckTimer.stop();
00746         ChannelCheckTimer.detach();
00747 //        printf("LoRaMacSetNextChannel return 0, channel %i \r\n", Channel);
00748         return 0;
00749     }
00750     // No free channel found. 
00751     // Check again
00752     if( ( LoRaMacState & MAC_CHANNEL_CHECK ) == 0 )
00753     {
00754         //TimerSetValue( &ChannelCheckTimer, minTime );
00755         //TimerStart( &ChannelCheckTimer );
00756         //ChannelCheckTimer.start(minTime/1000);
00757         ChannelCheckTimer.attach_us(OnChannelCheckTimerEvent, minTime);
00758         LoRaMacState |= MAC_CHANNEL_CHECK;
00759     }
00760     //printf("LoRaMacSetNextChannel return 1 \r\n");
00761     return 1;
00762 }
00763 
00764 /*
00765  * TODO: Add documentation
00766  */
00767 void OnChannelCheckTimerEvent( void )
00768 {
00769     //TimerStop( &ChannelCheckTimer );
00770     //ChannelCheckTimer.stop();
00771     ChannelCheckTimer.detach();
00772     
00773     LoRaMacState &= ~MAC_CHANNEL_CHECK;
00774     if( LoRaMacSetNextChannel( ) == 0 )
00775     {
00776         if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
00777         {
00778            LoRaMacSendFrameOnChannel( Channels[Channel] );
00779         }
00780     }
00781 }
00782 
00783 /*!
00784  * Adds a new MAC command to be sent.
00785  *
00786  * \Remark MAC layer internal function
00787  *
00788  * \param [in] cmd MAC command to be added
00789  *                 [MOTE_MAC_LINK_CHECK_REQ,
00790  *                  MOTE_MAC_LINK_ADR_ANS,
00791  *                  MOTE_MAC_DUTY_CYCLE_ANS,
00792  *                  MOTE_MAC_RX2_PARAM_SET_ANS,
00793  *                  MOTE_MAC_DEV_STATUS_ANS
00794  *                  MOTE_MAC_NEW_CHANNEL_ANS]
00795  * \param [in] p1  1st parameter ( optional depends on the command )
00796  * \param [in] p2  2nd parameter ( optional depends on the command )
00797  *
00798  * \retval status  Function status [0: OK, 1: Unknown command, 2: Buffer full]
00799  */
00800 static uint8_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
00801 {
00802     if( MacCommandsBufferIndex > 15 )
00803     {
00804         return 2;
00805     }
00806 
00807     MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
00808     switch( cmd )
00809     {
00810         case MOTE_MAC_LINK_CHECK_REQ:
00811             // No payload for this command
00812             break;
00813         case MOTE_MAC_LINK_ADR_ANS:
00814             // Margin
00815             MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
00816             break;
00817         case MOTE_MAC_DUTY_CYCLE_ANS:
00818             // No payload for this answer
00819             break;
00820         case MOTE_MAC_RX_PARAM_SETUP_ANS:
00821             // Status: Datarate ACK, Channel ACK
00822             MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
00823             break;
00824         case MOTE_MAC_DEV_STATUS_ANS:
00825             // 1st byte Battery
00826             // 2nd byte Margin
00827             MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
00828             MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
00829             break;
00830         case MOTE_MAC_NEW_CHANNEL_ANS:
00831             // Status: Datarate range OK, Channel frequency OK
00832             MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
00833             break;
00834         case MOTE_MAC_RX_TIMING_SETUP_ANS:
00835             // No payload for this answer
00836             break;
00837         default:
00838             return 1;
00839     }
00840     if( MacCommandsBufferIndex <= 15 )
00841     {
00842         MacCommandsInNextTx = true;
00843         return 0;
00844     }
00845     else
00846     {
00847         return 2;
00848     }
00849 }
00850 
00851 // TODO: Add Documentation
00852 static void LoRaMacNotify( LoRaMacEventFlags_t  *flags, LoRaMacEventInfo_t  *info )
00853 {
00854     if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->MacEvent  != NULL ) )
00855     {
00856         LoRaMacCallbacks->MacEvent ( flags, info );
00857     }
00858     flags->Value = 0;
00859 }
00860 static unsigned char randbuf[16];
00861 
00862 // get random seed from wideband noise rssi
00863 void radio_init( void ) 
00864 {
00865     //hal_disableIRQs( );
00866     __disable_irq();
00867     
00868     // seed 15-byte randomness via noise rssi
00869     // Set LoRa modem ON
00870     radio.SetModem( MODEM_LORA );
00871     // Disable LoRa modem interrupts
00872     radio.Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00873                   RFLR_IRQFLAGS_RXDONE |
00874                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00875                   RFLR_IRQFLAGS_VALIDHEADER |
00876                   RFLR_IRQFLAGS_TXDONE |
00877                   RFLR_IRQFLAGS_CADDONE |
00878                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00879                   RFLR_IRQFLAGS_CADDETECTED );
00880 
00881     // Set radio in continuous reception
00882     radio.Rx( 0 );
00883 
00884     for( int i = 1; i < 16; i++ )
00885     {
00886         for( int j = 0; j < 8; j++ )
00887         {
00888             unsigned char b; // wait for two non-identical subsequent least-significant bits
00889             while( ( b = radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) == ( radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) );
00890             randbuf[i] = ( randbuf[i] << 1 ) | b;
00891         }
00892     }
00893     randbuf[0] = 16; // set initial index
00894 
00895     // Change LoRa modem SyncWord
00896     radio.Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
00897     
00898     radio.Sleep( );
00899     
00900     //hal_enableIRQs( );
00901     __enable_irq();
00902 }
00903 
00904 void LoRaMacInit( LoRaMacCallbacks_t  *callbacks )
00905 {
00906     // start general purpose timer
00907     timerGeneralPurpose.start();
00908     
00909     LoRaMacCallbacks = callbacks;
00910 
00911     LoRaMacEventFlags.Value = 0;
00912     
00913     LoRaMacEventInfo.TxAckReceived = false;
00914     LoRaMacEventInfo.TxNbRetries = 0;
00915     LoRaMacEventInfo.TxDatarate = 7;
00916     LoRaMacEventInfo.RxPort = 1;
00917     LoRaMacEventInfo.RxBuffer = NULL;
00918     LoRaMacEventInfo.RxBufferSize = 0;
00919     LoRaMacEventInfo.RxRssi = 0;
00920     LoRaMacEventInfo.RxSnr = 0;
00921     LoRaMacEventInfo.Energy = 0;
00922     LoRaMacEventInfo.DemodMargin = 0;
00923     LoRaMacEventInfo.NbGateways = 0;
00924     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00925    
00926     LoRaMacDeviceClass = CLASS_A;
00927     
00928     UpLinkCounter = 1;
00929     DownLinkCounter = 0;
00930     
00931     IsLoRaMacNetworkJoined = false;
00932     LoRaMacState = MAC_IDLE;
00933 
00934 #if defined( USE_BAND_433 )
00935     ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
00936 #elif defined( USE_BAND_780 )
00937     ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
00938 #elif defined( USE_BAND_868 )
00939     ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
00940 #elif defined( USE_BAND_915 )
00941     ChannelsMask[0] = 0xFFFF;
00942     ChannelsMask[1] = 0xFFFF;
00943     ChannelsMask[2] = 0xFFFF;
00944     ChannelsMask[3] = 0xFFFF;
00945     ChannelsMask[4] = 0x00FF;
00946     ChannelsMask[5] = 0x0000;
00947 #elif defined( USE_BAND_915_HYBRID )
00948     ChannelsMask[0] = 0x00FF;
00949     ChannelsMask[1] = 0x0000;
00950     ChannelsMask[2] = 0x0000;
00951     ChannelsMask[3] = 0x0000;
00952     ChannelsMask[4] = 0x0001;
00953     ChannelsMask[5] = 0x0000;
00954 #else
00955     #error "Please define a frequency band in the compiler options."
00956 #endif
00957 
00958 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00959     // 125 kHz channels
00960     for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
00961     {
00962         Channels[i].Frequency = 902.3e6 + i * 200e3;
00963         Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0;
00964         Channels[i].Band = 0;
00965     }
00966     // 500 kHz channels
00967     for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
00968     {
00969         Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
00970         Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
00971         Channels[i].Band = 0;
00972     }
00973 #endif
00974 
00975     ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
00976     ChannelsDefaultDatarate = ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
00977     ChannelsNbRep = 1;
00978     ChannelsNbRepCounter = 0;
00979     
00980     MaxDCycle = 0;
00981     AggregatedDCycle = 1;
00982     AggregatedLastTxDoneTime = 0;
00983     AggregatedTimeOff = 0;
00984 
00985 #if defined( USE_BAND_433 )
00986     DutyCycleOn = false;
00987 #elif defined( USE_BAND_780 )
00988     DutyCycleOn = false;
00989 #elif defined( USE_BAND_868 )
00990     DutyCycleOn = true;
00991 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00992     DutyCycleOn = false;
00993 #else
00994     #error "Please define a frequency band in the compiler options."
00995 #endif
00996 
00997     MaxRxWindow = MAX_RX_WINDOW;
00998     ReceiveDelay1 = RECEIVE_DELAY1;
00999     ReceiveDelay2 = RECEIVE_DELAY2;
01000     JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1;
01001     JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2;
01002 
01003     //TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
01004     //TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
01005 
01006     //TimerInit( &ChannelCheckTimer, OnChannelCheckTimerEvent );
01007     //TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
01008     //TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
01009     //TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
01010     //TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
01011   
01012     
01013     // Initialize Radio driver
01014     /*RadioEvents.TxDone = OnRadioTxDone;
01015     RadioEvents.RxDone = OnRadioRxDone;
01016     RadioEvents.RxError = OnRadioRxError;
01017     RadioEvents.TxTimeout = OnRadioTxTimeout;
01018     RadioEvents.RxTimeout = OnRadioRxTimeout;
01019     */
01020     /*
01021     oid ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
01022                 void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool channelActivityDetected ),
01023                 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
01024                 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 )*/
01025     
01026     // initialize radio driver
01027     //radio = new SX1276MB1xAS( &RadioEvents, RF_SPI_MOSI, RF_SPI_MISO, RF_SPI_SCK, RF_SPI_CS, RF_RESET, RF_DIO0, RF_DIO1, RF_DIO2, RF_DIO3, RF_DIO4, RF_DIO5, RF_RXTX_SW );
01028     #warning check if this should be somewhere removed...
01029     
01030     radio_init();
01031     //radio.Init( &RadioEvents );
01032 
01033     // Random seed initialization
01034     srand1( radio.Random( ) );
01035 
01036     // Initialize channel index.
01037     Channel = LORA_MAX_NB_CHANNELS;
01038 
01039     PublicNetwork = true;
01040     LoRaMacSetPublicNetwork( PublicNetwork );
01041     radio.Sleep( );
01042 }
01043 
01044 void LoRaMacSetAdrOn( bool enable )
01045 {
01046     AdrCtrlOn = enable;
01047 }
01048 
01049 void LoRaMacInitNwkIds( uint32_t netID, uint32_t devAddr, uint8_t *nwkSKey, uint8_t *appSKey )
01050 {
01051     LoRaMacNetID = netID;
01052     LoRaMacDevAddr = devAddr;
01053     LoRaMacMemCpy( nwkSKey, LoRaMacNwkSKey, 16 );
01054     LoRaMacMemCpy( appSKey, LoRaMacAppSKey, 16 );
01055     
01056     IsLoRaMacNetworkJoined = true;
01057 }
01058 
01059 void LoRaMacMulticastChannelAdd( MulticastParams_t *channelParam )
01060 {
01061     // Reset downlink counter
01062     channelParam->DownLinkCounter = 0;
01063     
01064     if( MulticastChannels == NULL )
01065     {
01066         MulticastChannels = channelParam;
01067     }
01068     else
01069     {
01070         MulticastParams_t *cur = MulticastChannels;
01071         while( cur->Next != NULL )
01072         {
01073             cur = cur->Next;
01074         }
01075         cur->Next = channelParam;
01076     }
01077 }
01078 
01079 void LoRaMacMulticastChannelRemove( MulticastParams_t *channelParam )
01080 {
01081     MulticastParams_t *cur = NULL;
01082     
01083     // Remove the front element
01084     if( MulticastChannels == channelParam )
01085     {
01086         if( MulticastChannels != NULL )
01087         {
01088             cur = MulticastChannels;
01089             MulticastChannels = MulticastChannels->Next;
01090             cur->Next = NULL;
01091             // Last node in the list
01092             if( cur == MulticastChannels )
01093             {
01094                 MulticastChannels = NULL;
01095             }
01096         }
01097         return;
01098     }
01099     
01100     // Remove last element
01101     if( channelParam->Next == NULL )
01102     {
01103         if( MulticastChannels != NULL )
01104         {
01105             cur = MulticastChannels;
01106             MulticastParams_t *last = NULL;
01107             while( cur->Next != NULL )
01108             {
01109                 last = cur;
01110                 cur = cur->Next;
01111             }
01112             if( last != NULL )
01113             {
01114                 last->Next = NULL;
01115             }
01116             // Last node in the list
01117             if( cur == last )
01118             {
01119                 MulticastChannels = NULL;
01120             }
01121         }
01122         return;
01123     }
01124     
01125     // Remove a middle element
01126     cur = MulticastChannels;
01127     while( cur != NULL )
01128     {
01129         if( cur->Next == channelParam )
01130         {
01131             break;
01132         }
01133         cur = cur->Next;
01134     }
01135     if( cur != NULL )
01136     {
01137         MulticastParams_t *tmp = cur ->Next;
01138         cur->Next = tmp->Next;
01139         tmp->Next = NULL;
01140     }
01141 }
01142 
01143 uint8_t LoRaMacJoinReq( uint8_t *devEui, uint8_t *appEui, uint8_t *appKey )
01144 {
01145     LoRaMacHeader_t  macHdr;
01146 
01147     LoRaMacDevEui = devEui;
01148     LoRaMacAppEui = appEui;
01149     LoRaMacAppKey = appKey;
01150     
01151     macHdr.Value = 0;
01152     macHdr.Bits.MType        = FRAME_TYPE_JOIN_REQ;
01153     
01154     IsLoRaMacNetworkJoined = false;
01155     
01156 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01157     static uint8_t drSwitch = 0;
01158     
01159     if( ( ++drSwitch & 0x01 ) == 0x01 )
01160     {
01161         ChannelsDatarate = DR_0;
01162     }
01163     else
01164     {
01165         ChannelsDatarate = DR_4;
01166     }
01167 #endif
01168     return LoRaMacSend( &macHdr, NULL, 0, NULL, 0 );
01169 }
01170 
01171 uint8_t LoRaMacLinkCheckReq( void )
01172 {
01173     return AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 );
01174 }
01175 
01176 uint8_t LoRaMacSendFrame( uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
01177 {
01178     LoRaMacHeader_t  macHdr;
01179 
01180     macHdr.Value = 0;
01181 
01182     macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP;
01183     return LoRaMacSend( &macHdr, NULL, fPort, fBuffer, fBufferSize );
01184 }
01185 
01186 uint8_t LoRaMacSendConfirmedFrame( uint8_t fPort, void *fBuffer, uint16_t fBufferSize, uint8_t retries )
01187 {
01188     LoRaMacHeader_t  macHdr;
01189 
01190     if( AdrCtrlOn == false )
01191     {
01192         ChannelsDatarate = ChannelsDefaultDatarate;
01193     }
01194     AckTimeoutRetries = retries;
01195     AckTimeoutRetriesCounter = 1;
01196     
01197     macHdr.Value = 0;
01198 
01199     macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
01200     return LoRaMacSend( &macHdr, NULL, fPort, fBuffer, fBufferSize );
01201 }
01202 
01203 uint8_t LoRaMacSend( LoRaMacHeader_t  *macHdr, uint8_t *fOpts, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
01204 {
01205     LoRaMacFrameCtrl_t  fCtrl;
01206 
01207     fCtrl.Value = 0;
01208 
01209     fCtrl.Bits.FOptsLen      = 0;
01210     fCtrl.Bits.FPending      = 0;
01211     fCtrl.Bits.Ack           = false;
01212     fCtrl.Bits.AdrAckReq     = false;
01213     fCtrl.Bits.Adr           = AdrCtrlOn;
01214 
01215     if( LoRaMacSetNextChannel( ) == 0 )
01216     {
01217         printf("LoRaMacSend\r\n");
01218         return LoRaMacSendOnChannel( Channels[Channel], macHdr, &fCtrl, fOpts, fPort, fBuffer, fBufferSize );
01219     }
01220     return 5;
01221 }
01222 
01223 uint8_t LoRaMacPrepareFrame( ChannelParams_t channel, LoRaMacHeader_t  *macHdr, LoRaMacFrameCtrl_t  *fCtrl, uint8_t *fOpts, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
01224 {
01225     uint16_t i;
01226     uint8_t pktHeaderLen = 0;
01227     uint32_t mic = 0;
01228     
01229     LoRaMacBufferPktLen = 0;
01230     
01231     NodeAckRequested = false;
01232     
01233     if( fBuffer == NULL )
01234     {
01235         fBufferSize = 0;
01236     }
01237     else
01238     {
01239         if( ValidatePayloadLength( fBufferSize, ChannelsDatarate ) == false )
01240         {
01241             return 3;
01242         }
01243     }
01244 
01245     LoRaMacBuffer[pktHeaderLen++] = macHdr->Value;
01246 
01247     switch( macHdr->Bits.MType )
01248     {
01249         case FRAME_TYPE_JOIN_REQ:            
01250             RxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME;
01251             RxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME;
01252 
01253             LoRaMacBufferPktLen = pktHeaderLen;
01254         
01255             LoRaMacMemCpy( LoRaMacAppEui, LoRaMacBuffer + LoRaMacBufferPktLen, 8 );
01256             LoRaMacBufferPktLen += 8;
01257             LoRaMacMemCpy( LoRaMacDevEui, LoRaMacBuffer + LoRaMacBufferPktLen, 8 );
01258             LoRaMacBufferPktLen += 8;
01259 
01260             LoRaMacDevNonce = radio.Random( );
01261             
01262             LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
01263             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
01264 
01265             LoRaMacJoinComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
01266             
01267             LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
01268             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
01269             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
01270             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
01271             
01272             break;
01273         case FRAME_TYPE_DATA_CONFIRMED_UP:
01274             NodeAckRequested = true;
01275             //Intentional falltrough
01276         case FRAME_TYPE_DATA_UNCONFIRMED_UP:
01277             if( IsLoRaMacNetworkJoined == false )
01278             {
01279                 return 2; // No network has been joined yet
01280             }
01281             
01282             RxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME;
01283             RxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME;
01284 
01285             if( fOpts == NULL )
01286             {
01287                 fCtrl->Bits.FOptsLen = 0;
01288             }
01289 
01290             if( SrvAckRequested == true )
01291             {
01292                 SrvAckRequested = false;
01293                 fCtrl->Bits.Ack = 1;
01294             }
01295             
01296             if( fCtrl->Bits.Adr == true )
01297             {
01298                 if( ChannelsDatarate == LORAMAC_MIN_DATARATE )
01299                 {
01300                     AdrAckCounter = 0;
01301                     fCtrl->Bits.AdrAckReq = false;
01302                 }
01303                 else
01304                 {
01305                     if( AdrAckCounter > ADR_ACK_LIMIT )
01306                     {
01307                         fCtrl->Bits.AdrAckReq = true;
01308                     }
01309                     else
01310                     {
01311                         fCtrl->Bits.AdrAckReq = false;
01312                     }
01313                     if( AdrAckCounter > ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
01314                     {
01315                         AdrAckCounter = 0;
01316 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01317                         if( ChannelsDatarate > LORAMAC_MIN_DATARATE )
01318                         {
01319                             ChannelsDatarate--;
01320                         }
01321                         else
01322                         {
01323                             // Re-enable default channels LC1, LC2, LC3
01324                             ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
01325                         }
01326 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01327                         if( ( ChannelsDatarate > LORAMAC_MIN_DATARATE ) && ( ChannelsDatarate == DR_8 ) )
01328                         {
01329                             ChannelsDatarate = DR_4;
01330                         }
01331                         if( ChannelsDatarate > LORAMAC_MIN_DATARATE )
01332                         {
01333                             ChannelsDatarate--;
01334                         }
01335                         else
01336                         {
01337 #if defined( USE_BAND_915 )
01338                             // Re-enable default channels
01339                             ChannelsMask[0] = 0xFFFF;
01340                             ChannelsMask[1] = 0xFFFF;
01341                             ChannelsMask[2] = 0xFFFF;
01342                             ChannelsMask[3] = 0xFFFF;
01343                             ChannelsMask[4] = 0x00FF;
01344                             ChannelsMask[5] = 0x0000;
01345 #else // defined( USE_BAND_915_HYBRID )
01346                             // Re-enable default channels
01347                             ChannelsMask[0] = 0x00FF;
01348                             ChannelsMask[1] = 0x0000;
01349                             ChannelsMask[2] = 0x0000;
01350                             ChannelsMask[3] = 0x0000;
01351                             ChannelsMask[4] = 0x0001;
01352                             ChannelsMask[5] = 0x0000;
01353 #endif
01354                         }
01355 #else
01356     #error "Please define a frequency band in the compiler options."
01357 #endif
01358                     }
01359                 }
01360             }
01361             
01362             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
01363             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
01364             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
01365             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
01366 
01367             LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value;
01368 
01369             LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
01370             LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
01371 
01372             if( fOpts != NULL )
01373             {
01374                 for( i = 0; i < fCtrl->Bits.FOptsLen; i++ )
01375                 {
01376                     LoRaMacBuffer[pktHeaderLen++] = fOpts[i];
01377                 }
01378             }
01379             if( ( MacCommandsBufferIndex + fCtrl->Bits.FOptsLen ) <= 15 )
01380             {
01381                 if( MacCommandsInNextTx == true )
01382                 {
01383                     fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;
01384                     
01385                     // Update FCtrl field with new value of OptionsLength
01386                     LoRaMacBuffer[0x05] = fCtrl->Value;
01387                     for( i = 0; i < MacCommandsBufferIndex; i++ )
01388                     {
01389                         LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
01390                     }
01391                 }
01392             }
01393             MacCommandsInNextTx = false;
01394             MacCommandsBufferIndex = 0;
01395             
01396             if( ( pktHeaderLen + fBufferSize ) > LORAMAC_PHY_MAXPAYLOAD )
01397             {
01398                 return 3;
01399             }
01400 
01401             if( fBuffer != NULL )
01402             {
01403                 LoRaMacBuffer[pktHeaderLen++] = fPort;
01404                 
01405                 if( fPort == 0 )
01406                 {
01407                     LoRaMacPayloadEncrypt( ( uint8_t* )fBuffer, fBufferSize, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );
01408                 }
01409                 else
01410                 {
01411                     LoRaMacPayloadEncrypt( ( uint8_t* )fBuffer, fBufferSize, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );
01412                 }
01413                 LoRaMacMemCpy( LoRaMacPayload, LoRaMacBuffer + pktHeaderLen, fBufferSize );
01414             }
01415             LoRaMacBufferPktLen = pktHeaderLen + fBufferSize;
01416 
01417             LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
01418 
01419             if( ( LoRaMacBufferPktLen + LORAMAC_MFR_LEN ) > LORAMAC_PHY_MAXPAYLOAD )
01420             {
01421                 return 3;
01422             }
01423             LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
01424             LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
01425             LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
01426             LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
01427             
01428             LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
01429             break;
01430         default:
01431             return 4;
01432     }
01433 
01434     return 0;
01435 }
01436 
01437 uint8_t LoRaMacSendFrameOnChannel( ChannelParams_t channel )
01438 {
01439     printf("LoRaMacSendFrameOnChannel channel \r\n");
01440     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
01441     LoRaMacEventInfo.TxDatarate = ChannelsDatarate;
01442 
01443     ChannelsTxPower = LimitTxPower( ChannelsTxPower );
01444 
01445     radio.SetChannel( channel.Frequency );
01446     radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
01447 
01448 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01449     if( ChannelsDatarate == DR_7 )
01450     { // High Speed FSK channel
01451         radio.SetTxConfig( MODEM_FSK, TxPowers[ChannelsTxPower], 25e3, 0, Datarates[ChannelsDatarate] * 1e3, 0, 5, false, true, 0, 0, false, 3e6 );
01452         TxTimeOnAir = radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
01453     }
01454     else if( ChannelsDatarate == DR_6 )
01455     {
01456         printf("LoRaMacSendFrameOnChannel channel DR_6\r\n" ); 
01457         // High speed LoRa channel
01458         radio.SetTxConfig( MODEM_LORA, TxPowers[ChannelsTxPower], 0, 1, Datarates[ChannelsDatarate], 1, 8, false, true, 0, 0, false, 3e6 );
01459         TxTimeOnAir = radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
01460     }
01461     else
01462     {
01463         printf("LoRaMacSendFrameOnChannel channel other\r\n"); 
01464         // Normal LoRa channel
01465         radio.SetTxConfig( MODEM_LORA, TxPowers[ChannelsTxPower], 0, 0, Datarates[ChannelsDatarate], 1, 8, false, true, 0, 0, false, 3e6 );
01466         TxTimeOnAir = radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
01467     }
01468 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01469     if( ChannelsDatarate >= DR_4 )
01470     { // High speed LoRa channel BW500 kHz
01471         radio.SetTxConfig( MODEM_LORA, TxPowers[ChannelsTxPower], 0, 2, Datarates[ChannelsDatarate], 1, 8, false, true, 0, 0, false, 3e6 );
01472         TxTimeOnAir = radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
01473     }
01474     else
01475     { // Normal LoRa channel
01476         radio.SetTxConfig( MODEM_LORA, TxPowers[ChannelsTxPower], 0, 0, Datarates[ChannelsDatarate], 1, 8, false, true, 0, 0, false, 3e6 );
01477         TxTimeOnAir = radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
01478     }
01479 #else
01480     #error "Please define a frequency band in the compiler options."
01481 #endif
01482 
01483     if( MaxDCycle == 255 )
01484     {
01485         return 6;
01486     }
01487     if( MaxDCycle == 0 )
01488     {
01489         AggregatedTimeOff = 0;
01490     }
01491 
01492     LoRaMacState |= MAC_TX_RUNNING;
01493     // Starts the MAC layer status check timer
01494     //TimerStart( &MacStateCheckTimer );
01495     //MacStateCheckTimer.start(MAC_STATE_CHECK_TIMEOUT/1000);
01496     MacStateCheckTimer.attach_us(OnMacStateCheckTimerEvent, MAC_STATE_CHECK_TIMEOUT);
01497     
01498     //if( MAX( Bands[channel.Band].TimeOff, AggregatedTimeOff ) > ( TimerGetCurrentTime( ) ) )
01499     if( MAX( Bands[channel.Band].TimeOff, AggregatedTimeOff ) > ( timerGeneralPurpose.read_us( ) ) )
01500     {
01501         // Schedule transmission
01502         //TimerSetValue( &TxDelayedTimer, MAX( Bands[channel.Band].TimeOff, AggregatedTimeOff ) );
01503         //TimerStart( &TxDelayedTimer );
01504         //TxDelayedTimer.start(MAX( Bands[channel.Band].TimeOff, AggregatedTimeOff )/1000 );
01505 
01506         TxDelayedTimer.attach_us(OnTxDelayedTimerEvent, MAX( Bands[channel.Band].TimeOff, AggregatedTimeOff ));
01507 
01508     }
01509     else
01510     {
01511         // Send now
01512         radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
01513     }
01514     return 0;
01515 }
01516 
01517 
01518 void OnTxDelayedTimerEvent( void )
01519 {
01520     TxDelayedTimer.detach();
01521     //TimerStop( &TxDelayedTimer );
01522     //TxDelayedTimer.stop();
01523     radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
01524 }
01525 
01526 uint8_t LoRaMacSendOnChannel( ChannelParams_t channel, LoRaMacHeader_t  *macHdr, LoRaMacFrameCtrl_t  *fCtrl, uint8_t *fOpts, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
01527 {
01528     uint8_t status = 0;
01529     
01530     if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
01531     {
01532         printf("LoRaMacSendOnChannel MAC is busy\r\n");
01533         return 1; // MAC is busy transmitting a previous frame
01534     }
01535 
01536     status = LoRaMacPrepareFrame( channel, macHdr, fCtrl, fOpts, fPort, fBuffer, fBufferSize );
01537     if( status != 0 )
01538     {
01539         return status;
01540     }
01541 
01542     LoRaMacEventInfo.TxNbRetries = 0;
01543     LoRaMacEventInfo.TxAckReceived = false;
01544 
01545     return LoRaMacSendFrameOnChannel( channel );
01546 }
01547 
01548 static void LoRaMacProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize )
01549 {
01550     while( macIndex < commandsSize )
01551     {
01552         // Decode Frame MAC commands
01553         switch( payload[macIndex++] )
01554         {
01555             case SRV_MAC_LINK_CHECK_ANS:
01556                 LoRaMacEventFlags.Bits.LinkCheck = 1;
01557                 LoRaMacEventInfo.DemodMargin = payload[macIndex++];
01558                 LoRaMacEventInfo.NbGateways = payload[macIndex++];
01559                 break;
01560             case SRV_MAC_LINK_ADR_REQ:
01561                 {
01562                     uint8_t status = 0x07;
01563                     uint16_t chMask;
01564                     int8_t txPower = 0;
01565                     int8_t datarate = 0;
01566                     uint8_t nbRep = 0;
01567                     uint8_t chMaskCntl = 0;
01568                     uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
01569                     
01570                     // Initialize local copy of the channels mask array
01571                     for( uint8_t i = 0; i < 6; i++ )
01572                     {
01573                         channelsMask[i] = ChannelsMask[i];
01574                     }
01575                     datarate = payload[macIndex++];
01576                     txPower = datarate & 0x0F;
01577                     datarate = ( datarate >> 4 ) & 0x0F;
01578 
01579                     if( ( AdrCtrlOn == false ) && 
01580                         ( ( ChannelsDatarate != datarate ) || ( ChannelsTxPower != txPower ) ) )
01581                     { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
01582                         // Answer the server with fail status
01583                         // Power ACK     = 0
01584                         // Data rate ACK = 0
01585                         // Channel mask  = 0
01586                         AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
01587                         macIndex += 3;  // Skip over the remaining bytes of the request
01588                         break;
01589                     }
01590                     chMask = ( uint16_t )payload[macIndex++];
01591                     chMask |= ( uint16_t )payload[macIndex++] << 8;
01592 
01593                     nbRep = payload[macIndex++];
01594                     chMaskCntl = ( nbRep >> 4 ) & 0x07;
01595                     nbRep &= 0x0F;
01596                     if( nbRep == 0 )
01597                     {
01598                         nbRep = 1;
01599                     }
01600 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01601                     if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
01602                     {
01603                         status &= 0xFE; // Channel mask KO
01604                     }
01605                     else if( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 ) )
01606                     {
01607                         // RFU
01608                         status &= 0xFE; // Channel mask KO
01609                     }
01610                     else
01611                     {
01612                         for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
01613                         {
01614                             if( chMaskCntl == 6 )
01615                             {
01616                                 if( Channels[i].Frequency != 0 )
01617                                 {
01618                                     chMask |= 1 << i;
01619                                 }
01620                             }
01621                             else
01622                             {
01623                                 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
01624                                     ( Channels[i].Frequency == 0 ) )
01625                                 {// Trying to enable an undefined channel
01626                                     status &= 0xFE; // Channel mask KO
01627                                 }
01628                             }
01629                         }
01630                         channelsMask[0] = chMask;
01631                     }
01632 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01633                     if( chMaskCntl == 6 )
01634                     {
01635                         // Enable all 125 kHz channels
01636                         for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
01637                         {
01638                             for( uint8_t j = 0; j < 16; j++ )
01639                             {
01640                                 if( Channels[i + j].Frequency != 0 )
01641                                 {
01642                                     channelsMask[k] |= 1 << j;
01643                                 }
01644                             }
01645                         }
01646                     }
01647                     else if( chMaskCntl == 7 )
01648                     {
01649                         // Disable all 125 kHz channels
01650                         channelsMask[0] = 0x0000;
01651                         channelsMask[1] = 0x0000;
01652                         channelsMask[2] = 0x0000;
01653                         channelsMask[3] = 0x0000;
01654                     }
01655                     else if( chMaskCntl == 5 )
01656                     {
01657                         // RFU
01658                         status &= 0xFE; // Channel mask KO
01659                     }
01660                     else
01661                     {
01662                         for( uint8_t i = 0; i < 16; i++ )
01663                         {
01664                             if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
01665                                 ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) )
01666                             {// Trying to enable an undefined channel
01667                                 status &= 0xFE; // Channel mask KO
01668                             }
01669                         }
01670                         channelsMask[chMaskCntl] = chMask;
01671                         
01672                         if( CountNbEnabled125kHzChannels( channelsMask ) < 6 )
01673                         {
01674                             status &= 0xFE; // Channel mask KO
01675                         }
01676                     }
01677 #else
01678     #error "Please define a frequency band in the compiler options."
01679 #endif
01680                     if( ( ( datarate < LORAMAC_MIN_DATARATE ) ||
01681                           ( datarate > LORAMAC_MAX_DATARATE ) ) == true )
01682                     {
01683                         status &= 0xFD; // Datarate KO
01684                     }
01685 
01686                     //
01687                     // Remark MaxTxPower = 0 and MinTxPower = 5
01688                     //
01689                     if( ( ( LORAMAC_MAX_TX_POWER <= txPower ) &&
01690                           ( txPower <= LORAMAC_MIN_TX_POWER ) ) == false )
01691                     {
01692                         status &= 0xFB; // TxPower KO
01693                     }
01694                     if( ( status & 0x07 ) == 0x07 )
01695                     {
01696                         ChannelsDatarate = datarate;
01697                         ChannelsTxPower = txPower;
01698 #if defined( USE_BAND_915_HYBRID )
01699                         ChannelsMask[0] = channelsMask[0] & 0x00FF;
01700                         ChannelsMask[1] = channelsMask[1] & 0x0000;
01701                         ChannelsMask[2] = channelsMask[2] & 0x0000;
01702                         ChannelsMask[3] = channelsMask[3] & 0x0000;
01703                         ChannelsMask[4] = channelsMask[4] & 0x0001;
01704                         ChannelsMask[5] = channelsMask[5] & 0x0000;
01705 #else
01706                         ChannelsMask[0] = channelsMask[0];
01707                         ChannelsMask[1] = channelsMask[1];
01708                         ChannelsMask[2] = channelsMask[2];
01709                         ChannelsMask[3] = channelsMask[3];
01710                         ChannelsMask[4] = channelsMask[4];
01711                         ChannelsMask[5] = channelsMask[5];
01712 #endif
01713                         ChannelsNbRep = nbRep;
01714                     }
01715                     AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
01716                 }
01717                 break;
01718             case SRV_MAC_DUTY_CYCLE_REQ:
01719                 MaxDCycle = payload[macIndex++];
01720                 AggregatedDCycle = 1 << MaxDCycle;
01721                 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 );
01722                 break;
01723             case SRV_MAC_RX_PARAM_SETUP_REQ:
01724                 {
01725                     uint8_t status = 0x07;
01726                     int8_t datarate = 0;
01727                     int8_t drOffset = 0;
01728                     uint32_t freq = 0;
01729                 
01730                     drOffset = ( payload[macIndex] >> 4 ) & 0x07;
01731                     datarate = payload[macIndex] & 0x0F;
01732                     macIndex++;
01733                     freq = ( uint32_t )payload[macIndex++];
01734                     freq |= ( uint32_t )payload[macIndex++] << 8;
01735                     freq |= ( uint32_t )payload[macIndex++] << 16;
01736                     freq *= 100;
01737                     
01738                     if( radio.CheckRfFrequency( freq ) == false )
01739                     {
01740                         status &= 0xFE; // Channel frequency KO
01741                     }
01742                     
01743                     if( ( ( datarate < LORAMAC_MIN_DATARATE ) ||
01744                           ( datarate > LORAMAC_MAX_DATARATE ) ) == true )
01745                     {
01746                         status &= 0xFD; // Datarate KO
01747                     }
01748 
01749                     if( ( ( drOffset < LORAMAC_MIN_RX1_DR_OFFSET ) ||
01750                           ( drOffset > LORAMAC_MAX_RX1_DR_OFFSET ) ) == true )
01751                     {
01752                         status &= 0xFB; // Rx1DrOffset range KO
01753                     }
01754                     
01755                     if( ( status & 0x07 ) == 0x07 )
01756                     {
01757                         Rx2Channel.Datarate = datarate;
01758                         Rx2Channel.Frequency = freq;
01759                         Rx1DrOffset = drOffset;
01760                     }
01761                     AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
01762                 }
01763                 break;
01764             case SRV_MAC_DEV_STATUS_REQ:
01765                 {
01766                     uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
01767                     if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel  != NULL ) )
01768                     {
01769                         batteryLevel = LoRaMacCallbacks->GetBatteryLevel ( );
01770                     }
01771                     AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, LoRaMacEventInfo.RxSnr );
01772                 }
01773                 break;
01774             case SRV_MAC_NEW_CHANNEL_REQ:
01775                 {
01776                     uint8_t status = 0x03;
01777                     int8_t channelIndex = 0;
01778                     ChannelParams_t chParam;
01779                     
01780                     channelIndex = payload[macIndex++];
01781                     chParam.Frequency = ( uint32_t )payload[macIndex++];
01782                     chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8;
01783                     chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16;
01784                     chParam.Frequency *= 100;
01785                     chParam.DrRange.Value = payload[macIndex++];
01786                     
01787                     if( ( channelIndex < 3 ) || ( channelIndex > LORA_MAX_NB_CHANNELS ) )
01788                     {
01789                         status &= 0xFE; // Channel frequency KO
01790                     }
01791                 
01792                     if( radio.CheckRfFrequency( chParam.Frequency ) == false )
01793                     {
01794                         status &= 0xFE; // Channel frequency KO
01795                     }
01796 
01797                     if( ( chParam.DrRange.Fields.Min > chParam.DrRange.Fields.Max ) ||
01798                         ( ( ( LORAMAC_MIN_DATARATE <= chParam.DrRange.Fields.Min ) &&
01799                             ( chParam.DrRange.Fields.Min <= LORAMAC_MAX_DATARATE ) ) == false ) ||
01800                         ( ( ( LORAMAC_MIN_DATARATE <= chParam.DrRange.Fields.Max ) &&
01801                             ( chParam.DrRange.Fields.Max <= LORAMAC_MAX_DATARATE ) ) == false ) )
01802                     {
01803                         status &= 0xFD; // Datarate range KO
01804                     }
01805                     if( ( status & 0x03 ) == 0x03 )
01806                     {
01807                         LoRaMacSetChannel( channelIndex, chParam );
01808                     }
01809                     AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
01810                 }
01811                 break;
01812             case SRV_MAC_RX_TIMING_SETUP_REQ:
01813                 {
01814                     uint8_t delay = payload[macIndex++] & 0x0F;
01815                     
01816                     if( delay == 0 )
01817                     {
01818                         delay++;
01819                     }
01820                     ReceiveDelay1 = delay * 1e6;
01821                     ReceiveDelay2 = ReceiveDelay1 + 1e6;
01822                     AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
01823                 }
01824                 break;
01825             default:
01826                 // Unknown command. ABORT MAC commands processing
01827                 return;
01828         }
01829     }
01830 }
01831 
01832 /*!
01833  * Function to be executed on Tx Done event
01834  */
01835 static void OnRadioTxDone( void )
01836 {
01837     //TimerTime_t curTime = TimerGetCurrentTime( );
01838     TimerTime_t curTime = timerGeneralPurpose.read_us( );
01839     
01840     if( LoRaMacDeviceClass != CLASS_C )
01841     {
01842         radio.Sleep( );
01843     }
01844     else
01845     {
01846         OnRxWindow2TimerEvent();
01847     }
01848 
01849     // Update Band Time OFF
01850     Bands[Channels[Channel].Band].LastTxDoneTime = curTime;
01851     if( DutyCycleOn == true )
01852     {
01853         Bands[Channels[Channel].Band].TimeOff = TxTimeOnAir * Bands[Channels[Channel].Band].DCycle - TxTimeOnAir;
01854     }
01855     else
01856     {
01857         Bands[Channels[Channel].Band].TimeOff = 0;
01858     }
01859     // Update Agregated Time OFF
01860     AggregatedLastTxDoneTime = curTime;
01861     AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
01862 
01863     if( IsRxWindowsEnabled == true )
01864     {
01865         //TimerSetValue( &RxWindowTimer1, RxWindow1Delay );
01866         //TimerStart( &RxWindowTimer1 );
01867         //RxWindowTimer1.attach_us(&OnRxWindow1TimerEvent, RxWindow1Delay);
01868         //RxWindowTimer1.start(RxWindow1Delay/1000);
01869         RxWindowTimer1.attach_us(OnRxWindow1TimerEvent, RxWindow1Delay);
01870         
01871         if( LoRaMacDeviceClass != CLASS_C )
01872         {
01873             //TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
01874             //TimerStart( &RxWindowTimer2 );
01875             //RxWindowTimer2.attach_us(&OnRxWindow2TimerEvent, RxWindow2Delay);
01876             //RxWindowTimer2.start(RxWindow2Delay/1000);
01877             RxWindowTimer2.attach_us(OnRxWindow2TimerEvent, RxWindow2Delay);
01878         }
01879     }
01880     else
01881     {
01882         LoRaMacEventFlags.Bits.Tx = 1;
01883         LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
01884     }
01885     
01886     if( NodeAckRequested == false )
01887     {
01888         ChannelsNbRepCounter++;
01889     }
01890 }
01891 
01892 /*!
01893  * Function to be executed on Rx Done event
01894  */
01895 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
01896 {
01897     printf("OnRadioRxDone\r\n");
01898     LoRaMacHeader_t  macHdr;
01899     LoRaMacFrameCtrl_t  fCtrl;
01900 
01901     uint8_t pktHeaderLen = 0;
01902     uint32_t address = 0;
01903     uint8_t appPayloadStartIndex = 0;
01904     uint8_t port = 0xFF;
01905     uint8_t frameLen = 0;
01906     uint32_t mic = 0;
01907     uint32_t micRx = 0;
01908     
01909     uint16_t sequenceCounter = 0;
01910     uint16_t sequenceCounterPrev = 0;
01911     uint16_t sequenceCounterDiff = 0;
01912     uint32_t downLinkCounter = 0;
01913 
01914     MulticastParams_t *curMulticastParams = NULL;
01915     uint8_t *nwkSKey = LoRaMacNwkSKey;
01916     uint8_t *appSKey = LoRaMacAppSKey;
01917     
01918     bool isMicOk = false;
01919 
01920     if( LoRaMacDeviceClass != CLASS_C )
01921     {
01922         radio.Sleep( );
01923     }
01924     else
01925     {
01926         if( LoRaMacEventFlags.Bits.RxSlot == 0 )
01927         {
01928             OnRxWindow2TimerEvent();
01929         }
01930     }
01931     //TimerStop( &RxWindowTimer2 );
01932     //RxWindowTimer2.stop();
01933     RxWindowTimer2.detach();
01934 
01935     macHdr.Value = payload[pktHeaderLen++];
01936     
01937     switch( macHdr.Bits.MType )
01938     {
01939         case FRAME_TYPE_JOIN_ACCEPT:
01940             if( IsLoRaMacNetworkJoined == true )
01941             {
01942                 break;
01943             }
01944             LoRaMacJoinDecrypt( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );
01945 
01946             LoRaMacRxPayload[0] = macHdr.Value;
01947 
01948             LoRaMacJoinComputeMic( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic );
01949             
01950             micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN];
01951             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 );
01952             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 );
01953             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 );
01954             
01955             if( micRx == mic )
01956             {
01957                 LoRaMacEventFlags.Bits.Rx = 1;
01958                 LoRaMacEventInfo.RxSnr = snr;
01959                 LoRaMacEventInfo.RxRssi = rssi;
01960 
01961                 LoRaMacJoinComputeSKeys( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );
01962 
01963                 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4];
01964                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 );
01965                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 );
01966                 
01967                 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7];
01968                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 );
01969                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 );
01970                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
01971                 
01972                 // DLSettings
01973                 Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
01974                 Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
01975 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01976                 /*
01977                  * WARNING: To be removed once Semtech server implementation
01978                  *          is corrected.
01979                  */
01980                 if( Rx2Channel.Datarate == DR_3 )
01981                 {
01982                     Rx2Channel.Datarate = DR_8;
01983                 }
01984 #endif
01985                 // RxDelay
01986                 ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
01987                 if( ReceiveDelay1 == 0 )
01988                 {
01989                     ReceiveDelay1 = 1;
01990                 }
01991                 ReceiveDelay1 *= 1e6;
01992                 ReceiveDelay2 = ReceiveDelay1 + 1e6;
01993 
01994 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
01995                 //CFList
01996                 if( ( size - 1 ) > 16 )
01997                 {
01998                     ChannelParams_t param;
01999                     param.DrRange.Value = ( DR_5 << 4 ) | DR_0;
02000 
02001                     for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
02002                     {
02003                         param.Frequency = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
02004                         LoRaMacSetChannel( i, param );
02005                     }
02006                 }
02007 #endif
02008                 LoRaMacEventFlags.Bits.JoinAccept = 1;
02009                 IsLoRaMacNetworkJoined = true;
02010                 ChannelsDatarate = ChannelsDefaultDatarate;
02011                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
02012             }
02013             else
02014             {
02015                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
02016             }
02017 
02018             LoRaMacEventFlags.Bits.Tx = 1;
02019             break;
02020         case FRAME_TYPE_DATA_CONFIRMED_DOWN:
02021         case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
02022             {
02023                 address = payload[pktHeaderLen++];
02024                 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
02025                 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
02026                 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 );
02027 
02028                 if( address != LoRaMacDevAddr )
02029                 {
02030                     curMulticastParams = MulticastChannels;
02031                     while( curMulticastParams != NULL )
02032                     {
02033                         if( address == curMulticastParams->Address )
02034                         {
02035                             LoRaMacEventFlags.Bits.Multicast = 1;
02036                             nwkSKey = curMulticastParams->NwkSKey;
02037                             appSKey = curMulticastParams->AppSKey;
02038                             downLinkCounter = curMulticastParams->DownLinkCounter;
02039                             break;
02040                         }
02041                         curMulticastParams = curMulticastParams->Next;
02042                     }
02043                     if( LoRaMacEventFlags.Bits.Multicast == 0 )
02044                     {
02045                         // We are not the destination of this frame.
02046                         LoRaMacEventFlags.Bits.Tx = 1;
02047                         LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL;
02048                         LoRaMacState &= ~MAC_TX_RUNNING;
02049                         return;
02050                     }
02051                 }
02052                 else
02053                 {
02054                     LoRaMacEventFlags.Bits.Multicast = 0;
02055                     nwkSKey = LoRaMacNwkSKey;
02056                     appSKey = LoRaMacAppSKey;
02057                     downLinkCounter = DownLinkCounter;
02058                 }
02059                 
02060                 if( LoRaMacDeviceClass != CLASS_A )
02061                 {
02062                     LoRaMacState |= MAC_RX;
02063                     // Starts the MAC layer status check timer
02064                     //TimerStart( &MacStateCheckTimer );
02065                     //MacStateCheckTimer.start(MAC_STATE_CHECK_TIMEOUT/1000);
02066                     MacStateCheckTimer.attach_us(OnMacStateCheckTimerEvent, MAC_STATE_CHECK_TIMEOUT);
02067                 }
02068                 fCtrl.Value = payload[pktHeaderLen++];
02069                 
02070                 sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
02071                 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
02072 
02073                 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
02074 
02075                 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN];
02076                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 1] << 8 );
02077                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16 );
02078                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24 );
02079 
02080                 sequenceCounterPrev = ( uint16_t )downLinkCounter;
02081                 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
02082 
02083                 if( sequenceCounterDiff < ( 1 << 15 ) )
02084                 {
02085                     downLinkCounter += sequenceCounterDiff;
02086                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
02087                     if( micRx == mic )
02088                     {
02089                         isMicOk = true;
02090                     }
02091                 }
02092                 else
02093                 {
02094                     // check for downlink counter roll-over
02095                     uint32_t  downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
02096                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
02097                     if( micRx == mic )
02098                     {
02099                         isMicOk = true;
02100                         downLinkCounter = downLinkCounterTmp;
02101                     }
02102                 }
02103 
02104                 if( isMicOk == true )
02105                 {
02106                     LoRaMacEventFlags.Bits.Rx = 1;
02107                     LoRaMacEventInfo.RxSnr = snr;
02108                     LoRaMacEventInfo.RxRssi = rssi;
02109                     LoRaMacEventInfo.RxBufferSize = 0;
02110                     AdrAckCounter = 0;
02111 
02112                     // Update 32 bits downlink counter
02113                     if( LoRaMacEventFlags.Bits.Multicast == 1 )
02114                     {
02115                         curMulticastParams->DownLinkCounter = downLinkCounter;
02116                     }
02117                     else
02118                     {
02119                         DownLinkCounter = downLinkCounter;
02120                     }
02121 
02122                     if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN )
02123                     {
02124                         SrvAckRequested = true;
02125                     }
02126                     else
02127                     {
02128                         SrvAckRequested = false;
02129                     }
02130                     // Check if the frame is an acknowledgement
02131                     if( fCtrl.Bits.Ack == 1 )
02132                     {
02133                         LoRaMacEventInfo.TxAckReceived = true;
02134 
02135                         // Stop the AckTimeout timer as no more retransmissions 
02136                         // are needed.
02137                         //TimerStop( &AckTimeoutTimer );
02138                         //AckTimeoutTimer.stop();
02139                         AckTimeoutTimer.detach();
02140                     }
02141                     else
02142                     {
02143                         LoRaMacEventInfo.TxAckReceived = false;
02144                         if( AckTimeoutRetriesCounter > AckTimeoutRetries )
02145                         {
02146                             // Stop the AckTimeout timer as no more retransmissions 
02147                             // are needed.
02148                             //TimerStop( &AckTimeoutTimer );
02149                             //AckTimeoutTimer.stop();
02150                             AckTimeoutTimer.detach();
02151                         }
02152                     }
02153                     
02154                     if( fCtrl.Bits.FOptsLen > 0 )
02155                     {
02156                         // Decode Options field MAC commands
02157                         LoRaMacProcessMacCommands( payload, 8, appPayloadStartIndex );
02158                     }
02159                     
02160                     if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
02161                     {
02162                         port = payload[appPayloadStartIndex++];
02163                         frameLen = ( size - 4 ) - appPayloadStartIndex;
02164                         
02165                         if( port == 0 )
02166                         {
02167                             LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
02168                                                    frameLen,
02169                                                    nwkSKey,
02170                                                    address,
02171                                                    DOWN_LINK,
02172                                                    downLinkCounter,
02173                                                    LoRaMacRxPayload );
02174                             
02175                             // Decode frame payload MAC commands
02176                             LoRaMacProcessMacCommands( LoRaMacRxPayload, 0, frameLen );
02177                         }
02178                         else
02179                         {
02180                             LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
02181                                                    frameLen,
02182                                                    appSKey,
02183                                                    address,
02184                                                    DOWN_LINK,
02185                                                    downLinkCounter,
02186                                                    LoRaMacRxPayload );
02187 
02188                             LoRaMacEventFlags.Bits.RxData = 1;
02189                             LoRaMacEventInfo.RxPort = port;
02190                             LoRaMacEventInfo.RxBuffer = LoRaMacRxPayload;
02191                             LoRaMacEventInfo.RxBufferSize = frameLen;
02192                         }
02193                     }
02194 
02195                     LoRaMacEventFlags.Bits.Tx = 1;
02196                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
02197                 }
02198                 else
02199                 {
02200                     LoRaMacEventInfo.TxAckReceived = false;
02201                     
02202                     LoRaMacEventFlags.Bits.Tx = 1;
02203                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
02204                     LoRaMacState &= ~MAC_TX_RUNNING;
02205                 }
02206             }
02207             break;
02208         case FRAME_TYPE_PROPRIETARY:
02209             //Intentional falltrough
02210         default:
02211             LoRaMacEventFlags.Bits.Tx = 1;
02212             LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
02213             LoRaMacState &= ~MAC_TX_RUNNING;
02214             break;
02215     }
02216 }
02217 
02218 /*!
02219  * Function executed on Radio Tx Timeout event
02220  */
02221 static void OnRadioTxTimeout( void )
02222 {
02223     if( LoRaMacDeviceClass != CLASS_C )
02224     {
02225         radio.Sleep( );
02226     }
02227     else
02228     {
02229         OnRxWindow2TimerEvent();
02230     }
02231     
02232     LoRaMacEventFlags.Bits.Tx = 1;
02233     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
02234 }
02235 
02236 /*!
02237  * Function executed on Radio Rx Timeout event
02238  */
02239 static void OnRadioRxTimeout( void )
02240 {
02241     printf("OnRadioRxTimeout \r\n");
02242     if( LoRaMacDeviceClass != CLASS_C )
02243     {
02244         radio.Sleep( );
02245     }
02246     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
02247     {
02248         LoRaMacEventFlags.Bits.Tx = 1;
02249         LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
02250     }
02251 }
02252 
02253 /*!
02254  * Function executed on Radio Rx Error event
02255  */
02256 static void OnRadioRxError( void )
02257 {
02258     if( LoRaMacDeviceClass != CLASS_C )
02259     {
02260         radio.Sleep( );
02261     }
02262     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
02263     {
02264         LoRaMacEventFlags.Bits.Tx = 1;
02265         LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
02266     }
02267 }
02268 
02269 /*!
02270  * Initializes and opens the reception window
02271  *
02272  * \param [IN] freq window channel frequency
02273  * \param [IN] datarate window channel datarate
02274  * \param [IN] bandwidth window channel bandwidth
02275  * \param [IN] timeout window channel timeout
02276  */
02277 void LoRaMacRxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
02278 {
02279     uint8_t downlinkDatarate = Datarates[datarate];
02280     //RadioModems_t modem;
02281     ModemType modem;
02282     
02283     if( radio.GetState( ) == IDLE )
02284     {
02285         radio.SetChannel( freq );
02286 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02287         if( datarate == DR_7 )
02288         {
02289             modem = MODEM_FSK;
02290             radio.SetRxConfig( MODEM_FSK, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
02291         }
02292         else
02293         {
02294             modem = MODEM_LORA;
02295             radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02296         }
02297 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02298         modem = MODEM_LORA;
02299         radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02300 #endif
02301         if( RepeaterSupport == true )
02302         {
02303             radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] );
02304         }
02305         else
02306         {
02307             radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] );
02308         }
02309 
02310         if( rxContinuous == false )
02311         {
02312             radio.Rx( MaxRxWindow );
02313         }
02314         else
02315         {
02316             radio.Rx( 0 ); // Continuous mode
02317         }
02318     }
02319 }
02320 
02321 /*!
02322  * Function executed on first Rx window timer event
02323  */
02324 static void OnRxWindow1TimerEvent(void)
02325 {
02326     uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0
02327     int8_t datarate = 0;
02328     uint32_t bandwidth = 0; // LoRa 125 kHz
02329 
02330     //TimerStop( &RxWindowTimer1 );
02331     //RxWindowTimer1.stop();
02332     RxWindowTimer1.detach();
02333     LoRaMacEventFlags.Bits.RxSlot = 0;
02334 
02335 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02336     datarate = ChannelsDatarate - Rx1DrOffset;
02337     if( datarate < 0 )
02338     {
02339         datarate = DR_0;
02340     }
02341 
02342     // For higher datarates, we increase the number of symbols generating a Rx Timeout
02343     if( datarate >= DR_3 )
02344     { // DR_6, DR_5, DR_4, DR_3
02345         symbTimeout = 8;
02346     }
02347     if( datarate == DR_6 )
02348     {// LoRa 250 kHz
02349         bandwidth  = 1;
02350     }
02351     LoRaMacRxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false );
02352 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02353     datarate = datarateOffsets[ChannelsDatarate][Rx1DrOffset];
02354     if( datarate < 0 )
02355     {
02356         datarate = DR_0;
02357     }
02358     // For higher datarates, we increase the number of symbols generating a Rx Timeout
02359     if( datarate > DR_0 )
02360     { // DR_1, DR_2, DR_3, DR_4, DR_8, DR_9, DR_10, DR_11, DR_12, DR_13
02361         symbTimeout = 8;
02362     }
02363     if( datarate >= DR_4 )
02364     {// LoRa 500 kHz
02365         bandwidth  = 2;
02366     }
02367     LoRaMacRxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false );
02368 #else
02369     #error "Please define a frequency band in the compiler options."
02370 #endif
02371 }
02372 
02373 /*!
02374  * Function executed on second Rx window timer event
02375  */
02376 static void OnRxWindow2TimerEvent(void)
02377 {
02378     uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0
02379     uint32_t bandwidth = 0; // LoRa 125 kHz
02380 
02381     RxWindowTimer2.detach();
02382     //TimerStop( &RxWindowTimer2 );
02383     //RxWindowTimer2.stop();
02384     LoRaMacEventFlags.Bits.RxSlot = 1;
02385 
02386     if( NodeAckRequested == true )
02387     {
02388         //TimerSetValue( &AckTimeoutTimer, ACK_TIMEOUT + randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
02389         //TimerStart( &AckTimeoutTimer );
02390         //AckTimeoutTimer.start((ACK_TIMEOUT + randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ))/1000);
02391         AckTimeoutTimer.attach_us(OnAckTimeoutTimerEvent, ACK_TIMEOUT + randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ));
02392     }
02393 
02394 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02395     // For higher datarates, we increase the number of symbols generating a Rx Timeout
02396     if( Rx2Channel.Datarate >= DR_3 )
02397     { // DR_6, DR_5, DR_4, DR_3
02398         symbTimeout = 8;
02399     }
02400     if( Rx2Channel.Datarate == DR_6 )
02401     {// LoRa 250 kHz
02402         bandwidth  = 1;
02403     }
02404 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02405     // For higher datarates, we increase the number of symbols generating a Rx Timeout
02406     if( Rx2Channel.Datarate > DR_0 )
02407     { // DR_1, DR_2, DR_3, DR_4, DR_8, DR_9, DR_10, DR_11, DR_12, DR_13
02408         symbTimeout = 8;
02409     }
02410     if( Rx2Channel.Datarate >= DR_4 )
02411     {// LoRa 500 kHz
02412         bandwidth  = 2;
02413     }
02414 #else
02415     #error "Please define a frequency band in the compiler options."
02416 #endif
02417     if( LoRaMacDeviceClass != CLASS_C )
02418     {
02419         LoRaMacRxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, false );
02420     }
02421     else
02422     {
02423         LoRaMacRxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, true );
02424     }
02425 }
02426 
02427 /*!
02428  * Function executed on MacStateCheck timer event
02429  */
02430 static void OnMacStateCheckTimerEvent( void )
02431 {
02432     printf("OnMacStateCheckTimerEvent \r\n");
02433     //TimerStop( &MacStateCheckTimer );
02434     //MacStateCheckTimer.stop();
02435     MacStateCheckTimer.detach();
02436 
02437     if( LoRaMacEventFlags.Bits.Tx == 1 )
02438     {
02439         if( NodeAckRequested == false )
02440         {
02441             if( LoRaMacEventFlags.Bits.JoinAccept == true )
02442             {
02443                 // Join messages aren't repeated automatically
02444                 ChannelsNbRepCounter = ChannelsNbRep;
02445                 UpLinkCounter = 0;
02446             }
02447             if( ChannelsNbRepCounter >= ChannelsNbRep )
02448             {
02449                 ChannelsNbRepCounter = 0;
02450 
02451                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
02452 
02453                 AdrAckCounter++;
02454                 if( IsUpLinkCounterFixed == false )
02455                 {
02456                     UpLinkCounter++;
02457                 }
02458 
02459                 LoRaMacState &= ~MAC_TX_RUNNING;
02460             }
02461             else
02462             {
02463                 LoRaMacEventFlags.Bits.Tx = 0;
02464                 // Sends the same frame again
02465                 if( LoRaMacSetNextChannel( ) == 0 )
02466                 {
02467                     LoRaMacSendFrameOnChannel( Channels[Channel] );
02468                 }
02469             }
02470         }
02471         else
02472         {
02473             /*
02474              * For confirmed uplinks, ignore MIC and address errors and keep retrying.
02475              */
02476             if( ( LoRaMacEventInfo.Status == LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ) ||
02477                 ( LoRaMacEventInfo.Status == LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ) )
02478             {
02479                 AckTimeoutRetry = true;
02480             }
02481         }
02482 
02483         if( LoRaMacEventFlags.Bits.Rx == 1 )
02484         {
02485             if( ( LoRaMacEventInfo.TxAckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
02486             {
02487                 AckTimeoutRetry = false;
02488                 if( IsUpLinkCounterFixed == false )
02489                 {
02490                     UpLinkCounter++;
02491                 }
02492                 LoRaMacEventInfo.TxNbRetries = AckTimeoutRetriesCounter;
02493                 
02494                 LoRaMacState &= ~MAC_TX_RUNNING;
02495             }
02496         }
02497         
02498         if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & MAC_CHANNEL_CHECK ) == 0 ) )
02499         {
02500             AckTimeoutRetry = false;
02501             if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) )
02502             {
02503                 AckTimeoutRetriesCounter++;
02504                 
02505                 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
02506                 {
02507                     ChannelsDatarate = MAX( ChannelsDatarate - 1, LORAMAC_MIN_DATARATE );
02508                 }
02509                 LoRaMacEventFlags.Bits.Tx = 0;
02510                 // Sends the same frame again
02511                 if( LoRaMacSetNextChannel( ) == 0 )
02512                 {
02513                     LoRaMacSendFrameOnChannel( Channels[Channel] );
02514                 }
02515             }
02516             else
02517             {
02518 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02519                 // Re-enable default channels LC1, LC2, LC3
02520                 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
02521 #elif defined( USE_BAND_915 )
02522                 // Re-enable default channels
02523                 ChannelsMask[0] = 0xFFFF;
02524                 ChannelsMask[1] = 0xFFFF;
02525                 ChannelsMask[2] = 0xFFFF;
02526                 ChannelsMask[3] = 0xFFFF;
02527                 ChannelsMask[4] = 0x00FF;
02528                 ChannelsMask[5] = 0x0000;
02529 #elif defined( USE_BAND_915_HYBRID )
02530                 // Re-enable default channels
02531                 ChannelsMask[0] = 0x00FF;
02532                 ChannelsMask[1] = 0x0000;
02533                 ChannelsMask[2] = 0x0000;
02534                 ChannelsMask[3] = 0x0000;
02535                 ChannelsMask[4] = 0x0001;
02536                 ChannelsMask[5] = 0x0000;
02537 #else
02538     #error "Please define a frequency band in the compiler options."
02539 #endif
02540                 LoRaMacState &= ~MAC_TX_RUNNING;
02541                 
02542                 LoRaMacEventInfo.TxAckReceived = false;
02543                 LoRaMacEventInfo.TxNbRetries = AckTimeoutRetriesCounter;
02544                 if( IsUpLinkCounterFixed == false )
02545                 {
02546                     UpLinkCounter++;
02547                 }
02548                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
02549             }
02550         }
02551     }
02552     // Handle reception for Class B and Class C
02553     if( ( LoRaMacState & MAC_RX ) == MAC_RX )
02554     {
02555         LoRaMacState &= ~MAC_RX;
02556     }
02557     if( LoRaMacState == MAC_IDLE )
02558     {
02559         LoRaMacNotify( &LoRaMacEventFlags, &LoRaMacEventInfo );
02560     }
02561     else
02562     {
02563         // Operation not finished restart timer
02564         MacStateCheckTimer.attach_us(OnMacStateCheckTimerEvent, MAC_STATE_CHECK_TIMEOUT);
02565         //TimerStart( &MacStateCheckTimer );
02566         //MacStateCheckTimer.start(MAC_STATE_CHECK_TIMEOUT/1000);
02567     }
02568 }
02569 
02570 static void OnAckTimeoutTimerEvent(void)
02571 {
02572     AckTimeoutTimer.detach();
02573     //TimerStop( &AckTimeoutTimer );
02574     //AckTimeoutTimer.stop();
02575 
02576     AckTimeoutRetry = true;
02577     LoRaMacState &= ~MAC_ACK_REQ;
02578 }
02579 
02580 /*!
02581  * ============================================================================
02582  * = LoRaMac utility functions                                                =
02583  * ============================================================================
02584  */
02585 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate )
02586 {
02587     bool payloadSizeOk = false;
02588     uint8_t maxN = 0;
02589 
02590     // Get the maximum payload length
02591     if( RepeaterSupport == true )
02592     {
02593         maxN = MaxPayloadOfDatarateRepeater[datarate];
02594     }
02595     else
02596     {
02597         maxN = MaxPayloadOfDatarate[datarate];
02598     }
02599 
02600     // Validation of the application payload size
02601     if( lenN <= maxN )
02602     {
02603         payloadSizeOk = true;
02604     }
02605 
02606     return payloadSizeOk;
02607 }
02608 
02609 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02610 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask )
02611 {
02612     uint8_t nb125kHzChannels = 0;
02613 
02614     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
02615     {
02616         for( uint8_t j = 0; j < 16; j++ )
02617         {// Verify if the channel is active
02618             if( ( channelsMask[k] & ( 1 << j ) ) == ( 1 << j ) )
02619             {
02620                 nb125kHzChannels++;
02621             }
02622         }
02623     }
02624 
02625     return nb125kHzChannels;
02626 }
02627 #endif
02628 
02629 static int8_t LimitTxPower( int8_t txPower )
02630 {
02631     int8_t resultTxPower = txPower;
02632 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02633     if( ( ChannelsDatarate == DR_4 ) ||
02634         ( ( ChannelsDatarate >= DR_8 ) && ( ChannelsDatarate <= DR_13 ) ) )
02635     {// Limit tx power to max 26dBm
02636         resultTxPower =  MAX( txPower, TX_POWER_26_DBM );
02637     }
02638     else
02639     {
02640         if( CountNbEnabled125kHzChannels( ChannelsMask ) < 50 )
02641         {// Limit tx power to max 21dBm
02642             resultTxPower = MAX( txPower, TX_POWER_20_DBM );
02643         }
02644     }
02645 #endif
02646     return resultTxPower;
02647 }
02648 
02649 void LoRaMacChannelRemove( uint8_t id )
02650 {
02651     if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
02652     {
02653         return;
02654     }
02655 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02656     if( id < 64 )
02657     {
02658         if( CountNbEnabled125kHzChannels( ChannelsMask ) <= 6 )
02659         {
02660             return;
02661         }
02662     }
02663 #else
02664     if( id < 3 )
02665     {
02666         return;
02667     }
02668 #endif
02669 
02670     uint8_t index = 0;
02671     index = id / 16;
02672 
02673     if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
02674     {
02675         return;
02676     }
02677 
02678     // Deactivate channel
02679     ChannelsMask[index] &= ~( 1 << ( id % 16 ) );
02680 
02681     return;
02682 }
02683 
02684 /*!
02685  * ============================================================================
02686  * = LoRaMac setup functions                                                  =
02687  * ============================================================================
02688  */
02689 void LoRaMacSetDeviceClass( DeviceClass_t deviceClass )
02690 {
02691     LoRaMacDeviceClass = deviceClass;
02692 }
02693 
02694 void LoRaMacSetPublicNetwork( bool enable )
02695 {
02696     PublicNetwork = enable;
02697     radio.SetModem( MODEM_LORA );
02698     if( PublicNetwork == true )
02699     {
02700         // Change LoRa modem SyncWord
02701         radio.Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
02702     }
02703     else
02704     {
02705         // Change LoRa modem SyncWord
02706         radio.Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
02707     }
02708 }
02709 
02710 void LoRaMacSetChannel( uint8_t id, ChannelParams_t params )
02711 {
02712     params.Band = 0;
02713     Channels[id] = params;
02714     // Activate the newly created channel
02715     if( id < 16 )
02716     {
02717         ChannelsMask[0] |= 1 << id;
02718     }
02719     else if( id < 32 )
02720     {
02721         ChannelsMask[1] |= 1 << ( id - 16 );
02722     }
02723     else if( id < 48 )
02724     {
02725         ChannelsMask[2] |= 1 << ( id - 32 );
02726     }
02727     else if( id < 64 )
02728     {
02729         ChannelsMask[3] |= 1 << ( id - 48 );
02730     }
02731     else if( id < 72 )
02732     {
02733         ChannelsMask[4] |= 1 << ( id - 64 );
02734     }
02735     else
02736     {
02737         // Don't activate the channel
02738     }
02739 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 )
02740     Channels[id].Band = 0; // 1% duty cycle on EU433 and CN780 bands
02741 #elif defined( USE_BAND_868 )
02742     if( ( Channels[id].Frequency >= 865000000 ) && ( Channels[id].Frequency <= 868000000 ) )
02743     {
02744         if( Channels[id].Band != BAND_G1_0 )
02745         {
02746             Channels[id].Band = BAND_G1_0;
02747         }
02748     }
02749     else if( ( Channels[id].Frequency > 868000000 ) && ( Channels[id].Frequency <= 868600000 ) )
02750     {
02751         if( Channels[id].Band != BAND_G1_1 )
02752         {
02753             Channels[id].Band = BAND_G1_1;
02754         }
02755     }
02756     else if( ( Channels[id].Frequency >= 868700000 ) && ( Channels[id].Frequency <= 869200000 ) )
02757     {
02758         if( Channels[id].Band != BAND_G1_2 )
02759         {
02760             Channels[id].Band = BAND_G1_2;
02761         }
02762     }
02763     else if( ( Channels[id].Frequency >= 869400000 ) && ( Channels[id].Frequency <= 869650000 ) )
02764     {
02765         if( Channels[id].Band != BAND_G1_3 )
02766         {
02767             Channels[id].Band = BAND_G1_3;
02768         }
02769     }
02770     else if( ( Channels[id].Frequency >= 869700000 ) && ( Channels[id].Frequency <= 870000000 ) )
02771     {
02772         if( Channels[id].Band != BAND_G1_4 )
02773         {
02774             Channels[id].Band = BAND_G1_4;
02775         }
02776     }
02777     else
02778     {
02779         Channels[id].Frequency = 0;
02780         Channels[id].DrRange.Value = 0;
02781     }
02782 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02783     Channels[id].Band = 0; // No duty cycle on US915 band
02784 #else
02785     #error "Please define a frequency band in the compiler options."
02786 #endif
02787     // Check if it is a valid channel
02788     if( Channels[id].Frequency == 0 )
02789     {
02790         LoRaMacChannelRemove( id );
02791     }
02792 }
02793 
02794 void LoRaMacSetRx2Channel( Rx2ChannelParams_t param )
02795 {
02796     Rx2Channel = param;
02797 }
02798 
02799 void LoRaMacSetChannelsTxPower( int8_t txPower )
02800 {
02801     if( ( txPower >= LORAMAC_MAX_TX_POWER ) &&
02802         ( txPower <= LORAMAC_MIN_TX_POWER ) )
02803     {
02804 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02805         int8_t txPwr = LimitTxPower( txPower );
02806         if( txPwr == txPower )
02807         {
02808             ChannelsTxPower = txPower;
02809         }
02810 #else
02811         ChannelsTxPower = txPower;
02812 #endif
02813     }
02814 }
02815 
02816 void LoRaMacSetChannelsDatarate( int8_t datarate )
02817 {
02818     ChannelsDefaultDatarate = ChannelsDatarate = datarate;
02819 }
02820 
02821 void LoRaMacSetChannelsMask( uint16_t *mask )
02822 {
02823 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02824     if( ( CountNbEnabled125kHzChannels( mask ) < 6 ) &&
02825         ( CountNbEnabled125kHzChannels( mask ) > 0 ) )
02826     {
02827 
02828     }
02829     else
02830     {
02831         LoRaMacMemCpy( (uint8_t* ) mask,
02832                        ( uint8_t* ) ChannelsMask, 10 );
02833     }
02834 #else
02835     if( ( mask[0] & 0x0007 ) != 0x0007 )
02836     {
02837     }
02838     else
02839     {
02840         LoRaMacMemCpy( ( uint8_t* ) mask,
02841                        ( uint8_t* ) ChannelsMask, 2 );
02842     }
02843 #endif
02844 }
02845 
02846 void LoRaMacSetChannelsNbRep( uint8_t nbRep )
02847 {
02848     if( nbRep < 1 )
02849     {
02850         nbRep = 1;
02851     }
02852     if( nbRep > 15 )
02853     {
02854         nbRep = 15;
02855     }
02856     ChannelsNbRep = nbRep;
02857 }
02858 
02859 void LoRaMacSetMaxRxWindow( uint32_t delay )
02860 {
02861     MaxRxWindow = delay;
02862 }
02863 
02864 void LoRaMacSetReceiveDelay1( uint32_t delay )
02865 {
02866     ReceiveDelay1 = delay;
02867 }
02868 
02869 void LoRaMacSetReceiveDelay2( uint32_t delay )
02870 {
02871     ReceiveDelay2 = delay;
02872 }
02873 
02874 void LoRaMacSetJoinAcceptDelay1( uint32_t delay )
02875 {
02876     JoinAcceptDelay1 = delay;
02877 }
02878 
02879 void LoRaMacSetJoinAcceptDelay2( uint32_t delay )
02880 {
02881     JoinAcceptDelay2 = delay;
02882 }
02883 
02884 uint32_t LoRaMacGetUpLinkCounter( void )
02885 {
02886     return UpLinkCounter;
02887 }
02888 
02889 uint32_t LoRaMacGetDownLinkCounter( void )
02890 {
02891     return DownLinkCounter;
02892 }
02893 
02894 /*!
02895  * ============================================================================
02896  * = LoRaMac test functions                                                   =
02897  * ============================================================================
02898  */
02899 void LoRaMacTestSetDutyCycleOn( bool enable )
02900 {
02901     DutyCycleOn = enable;
02902 }
02903 
02904 void LoRaMacTestRxWindowsOn( bool enable )
02905 {
02906     IsRxWindowsEnabled = enable;
02907 }
02908 
02909 void LoRaMacTestSetMic( uint16_t upLinkCounter )
02910 {
02911     UpLinkCounter = upLinkCounter;
02912     IsUpLinkCounterFixed = true;
02913 }