LoRaWAN MAC layer implementation

Dependents:   LoRaWAN-demo-72_tjm LoRaWAN-demo-72_jlc LoRaWAN-demo-elmo frdm_LoRa_Connect_Woodstream_Demo_tjm ... more

LoRAWAN-lib is a port of the GitHub LoRaMac-node LoRaWAN MAC layer implementation.

This library depends on the SX1276Lib or SX1272Lib radio drivers depending on the used mbed component shield.

This library depends also on some cryptographic helper functions as well as helper functions for the timers management. These can be found on the example projects under the system directory.

The example projects are:

  1. LoRaWAN-demo-72
  2. LoRaWAN-demo-76
  3. LoRaWAN-demo-NAMote72

The LoRaWAN specification specifies different ISM bands operating parameters. These are all implemented under the LoRaMac-board.h file.

In order to select which band to use, please change line 24 of board.h file provided on the examples projects as follows:


EU868

board.h

#define USE_BAND_868


US915

board.h

#define USE_BAND_915


US915 - Hybrid

board.h

#define USE_BAND_915_HYBRID


CN780

board.h

#define USE_BAND_780


EU433

board.h

#define USE_BAND_433

Files at this revision

API Documentation at this revision

Comitter:
mluis
Date:
Tue Jul 05 13:24:54 2016 +0000
Parent:
6:d7a34ded7c87
Child:
8:26002607de9c
Commit message:
Synchronized with https://github.com/Lora-net/LoRaMac-node git revision 7a4aec588de628d864c364e9469ae45105fdbe26

Changed in this revision

LoRaMac-api-v3.h Show annotated file Show diff for this revision Revisions of this file
LoRaMac-board.h Show diff for this revision Revisions of this file
LoRaMac-definitions.h Show annotated file Show diff for this revision Revisions of this file
LoRaMac.cpp Show annotated file Show diff for this revision Revisions of this file
LoRaMac.h Show annotated file Show diff for this revision Revisions of this file
--- a/LoRaMac-api-v3.h	Wed May 18 11:19:24 2016 +0000
+++ b/LoRaMac-api-v3.h	Tue Jul 05 13:24:54 2016 +0000
@@ -33,7 +33,6 @@
 
 // Includes board dependent definitions such as channels frequencies
 #include "LoRaMac.h"
-#include "LoRaMac-board.h"
 
 /*!
  * Beacon interval in us
--- a/LoRaMac-board.h	Wed May 18 11:19:24 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,508 +0,0 @@
-/*
- / _____)             _              | |
-( (____  _____ ____ _| |_ _____  ____| |__
- \____ \| ___ |    (_   _) ___ |/ ___)  _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
-
-Description: LoRa MAC layer board dependent definitions
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
-#ifndef __LORAMAC_BOARD_H__
-#define __LORAMAC_BOARD_H__
-
-/*!
- * Returns individual channel mask
- *
- * \param[IN] channelIndex Channel index 1 based
- * \retval channelMask
- */
-#define LC( channelIndex )            ( uint16_t )( 1 << ( channelIndex - 1 ) )
-
-#if defined( USE_BAND_433 )
-
-/*!
- * LoRaMac maximum number of channels
- */
-#define LORA_MAX_NB_CHANNELS                        16
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MAX_DATARATE                     DR_7
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MAX_DATARATE                     DR_7
-
-/*!
- * Default datarate used by the node
- */
-#define LORAMAC_DEFAULT_DATARATE                    DR_0
-
-/*!
- * Minimal Rx1 receive datarate offset
- */
-#define LORAMAC_MIN_RX1_DR_OFFSET                   0
-
-/*!
- * Maximal Rx1 receive datarate offset
- */
-#define LORAMAC_MAX_RX1_DR_OFFSET                   5
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MAX_TX_POWER                        TX_POWER_10_DBM
-
-/*!
- * Default Tx output power used by the node
- */
-#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_10_DBM
-
-/*!
- * LoRaMac TxPower definition
- */
-#define TX_POWER_10_DBM                             0
-#define TX_POWER_07_DBM                             1
-#define TX_POWER_04_DBM                             2
-#define TX_POWER_01_DBM                             3
-#define TX_POWER_M2_DBM                             4
-#define TX_POWER_M5_DBM                             5
-
-/*!
- * LoRaMac datarates definition
- */
-#define DR_0                                        0  // SF12 - BW125
-#define DR_1                                        1  // SF11 - BW125
-#define DR_2                                        2  // SF10 - BW125
-#define DR_3                                        3  // SF9  - BW125
-#define DR_4                                        4  // SF8  - BW125
-#define DR_5                                        5  // SF7  - BW125
-#define DR_6                                        6  // SF7  - BW250
-#define DR_7                                        7  // FSK
-
-/*!
- * Second reception window channel definition.
- */
-// Channel = { Frequency [Hz], Datarate }
-#define RX_WND_2_CHANNEL                                  { 434665000, DR_0 }
-
-/*!
- * LoRaMac maximum number of bands
- */
-#define LORA_MAX_NB_BANDS                           1
-
-// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
-#define BAND0              { 100, TX_POWER_10_DBM, 0,  0 } //  1.0 %
-
-/*!
- * LoRaMac default channels
- */
-// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
-#define LC1                { 433175000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC2                { 433375000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC3                { 433575000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-
-/*!
- * LoRaMac duty cycle for the join procedure
- */
-#define JOIN_DC            1000
-
-/*!
- * LoRaMac channels which are allowed for the join procedure
- */
-#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
-
-#elif defined( USE_BAND_780 )
-
-/*!
- * LoRaMac maximum number of channels
- */
-#define LORA_MAX_NB_CHANNELS                        16
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MAX_DATARATE                     DR_7
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MAX_DATARATE                     DR_7
-
-/*!
- * Default datarate used by the node
- */
-#define LORAMAC_DEFAULT_DATARATE                    DR_0
-
-/*!
- * Minimal Rx1 receive datarate offset
- */
-#define LORAMAC_MIN_RX1_DR_OFFSET                   0
-
-/*!
- * Maximal Rx1 receive datarate offset
- */
-#define LORAMAC_MAX_RX1_DR_OFFSET                   5
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MAX_TX_POWER                        TX_POWER_10_DBM
-
-/*!
- * Default Tx output power used by the node
- */
-#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_10_DBM
-
-/*!
- * LoRaMac TxPower definition
- */
-#define TX_POWER_10_DBM                             0
-#define TX_POWER_07_DBM                             1
-#define TX_POWER_04_DBM                             2
-#define TX_POWER_01_DBM                             3
-#define TX_POWER_M2_DBM                             4
-#define TX_POWER_M5_DBM                             5
-
-/*!
- * LoRaMac datarates definition
- */
-#define DR_0                                        0  // SF12 - BW125
-#define DR_1                                        1  // SF11 - BW125
-#define DR_2                                        2  // SF10 - BW125
-#define DR_3                                        3  // SF9  - BW125
-#define DR_4                                        4  // SF8  - BW125
-#define DR_5                                        5  // SF7  - BW125
-#define DR_6                                        6  // SF7  - BW250
-#define DR_7                                        7  // FSK
-
-/*!
- * Second reception window channel definition.
- */
-// Channel = { Frequency [Hz], Datarate }
-#define RX_WND_2_CHANNEL                                  { 786000000, DR_0 }
-
-/*!
- * LoRaMac maximum number of bands
- */
-#define LORA_MAX_NB_BANDS                           1
-
-// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
-#define BAND0              { 100, TX_POWER_10_DBM, 0,  0 } //  1.0 %
-
-/*!
- * LoRaMac default channels
- */
-// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
-#define LC1                { 779500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC2                { 779700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC3                { 779900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-
-/*!
- * LoRaMac duty cycle for the join procedure
- */
-#define JOIN_DC            1000
-
-/*!
- * LoRaMac channels which are allowed for the join procedure
- */
-#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
-
-#elif defined( USE_BAND_868 )
-
-/*!
- * LoRaMac maximum number of channels
- */
-#define LORA_MAX_NB_CHANNELS                        16
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MAX_DATARATE                     DR_7
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MAX_DATARATE                     DR_7
-
-/*!
- * Default datarate used by the node
- */
-#define LORAMAC_DEFAULT_DATARATE                    DR_0
-
-/*!
- * Minimal Rx1 receive datarate offset
- */
-#define LORAMAC_MIN_RX1_DR_OFFSET                   0
-
-/*!
- * Maximal Rx1 receive datarate offset
- */
-#define LORAMAC_MAX_RX1_DR_OFFSET                   5
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MIN_TX_POWER                        TX_POWER_02_DBM
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MAX_TX_POWER                        TX_POWER_20_DBM
-
-/*!
- * Default Tx output power used by the node
- */
-#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_14_DBM
-
-/*!
- * LoRaMac TxPower definition
- */
-#define TX_POWER_20_DBM                             0
-#define TX_POWER_14_DBM                             1
-#define TX_POWER_11_DBM                             2
-#define TX_POWER_08_DBM                             3
-#define TX_POWER_05_DBM                             4
-#define TX_POWER_02_DBM                             5
-
-/*!
- * LoRaMac datarates definition
- */
-#define DR_0                                        0  // SF12 - BW125
-#define DR_1                                        1  // SF11 - BW125
-#define DR_2                                        2  // SF10 - BW125
-#define DR_3                                        3  // SF9  - BW125
-#define DR_4                                        4  // SF8  - BW125
-#define DR_5                                        5  // SF7  - BW125
-#define DR_6                                        6  // SF7  - BW250
-#define DR_7                                        7  // FSK
-
-/*!
- * Second reception window channel definition.
- */
-// Channel = { Frequency [Hz], Datarate }
-#define RX_WND_2_CHANNEL                                  { 869525000, DR_0 }
-
-/*!
- * LoRaMac maximum number of bands
- */
-#define LORA_MAX_NB_BANDS                           5
-
-/*!
- * LoRaMac EU868 default bands
- */
-typedef enum
-{
-    BAND_G1_0,
-    BAND_G1_1,
-    BAND_G1_2,
-    BAND_G1_3,
-    BAND_G1_4,
-}BandId_t;
-
-// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
-#define BAND0              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
-#define BAND1              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
-#define BAND2              { 1000, TX_POWER_14_DBM, 0,  0 } //  0.1 %
-#define BAND3              { 10  , TX_POWER_14_DBM, 0,  0 } // 10.0 %
-#define BAND4              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
-
-/*!
- * LoRaMac default channels
- */
-// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
-#define LC1                { 868100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
-#define LC2                { 868300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
-#define LC3                { 868500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
-
-/*!
- * LoRaMac duty cycle for the join procedure
- */
-#define JOIN_DC            1000
-
-/*!
- * LoRaMac channels which are allowed for the join procedure
- */
-#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
-
-#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
-
-/*!
- * LoRaMac maximum number of channels
- */
-#define LORA_MAX_NB_CHANNELS                        72
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MIN_DATARATE                     DR_0
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_TX_MAX_DATARATE                     DR_4
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MIN_DATARATE                     DR_8
-
-/*!
- * Minimal datarate that can be used by the node
- */
-#define LORAMAC_RX_MAX_DATARATE                     DR_13
-
-/*!
- * Default datarate used by the node
- */
-#define LORAMAC_DEFAULT_DATARATE                    DR_0
-
-/*!
- * Minimal Rx1 receive datarate offset
- */
-#define LORAMAC_MIN_RX1_DR_OFFSET                   0
-
-/*!
- * Maximal Rx1 receive datarate offset
- */
-#define LORAMAC_MAX_RX1_DR_OFFSET                   3
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MIN_TX_POWER                        TX_POWER_10_DBM
-
-/*!
- * Minimal Tx output power that can be used by the node
- */
-#define LORAMAC_MAX_TX_POWER                        TX_POWER_30_DBM
-
-/*!
- * Default Tx output power used by the node
- */
-#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_20_DBM
-
-/*!
- * LoRaMac TxPower definition
- */
-#define TX_POWER_30_DBM                             0
-#define TX_POWER_28_DBM                             1
-#define TX_POWER_26_DBM                             2
-#define TX_POWER_24_DBM                             3
-#define TX_POWER_22_DBM                             4
-#define TX_POWER_20_DBM                             5
-#define TX_POWER_18_DBM                             6
-#define TX_POWER_16_DBM                             7
-#define TX_POWER_14_DBM                             8
-#define TX_POWER_12_DBM                             9
-#define TX_POWER_10_DBM                             10
-
-/*!
- * LoRaMac datarates definition
- */
-#define DR_0                                        0  // SF10 - BW125 |
-#define DR_1                                        1  // SF9  - BW125 |
-#define DR_2                                        2  // SF8  - BW125 +-> Up link
-#define DR_3                                        3  // SF7  - BW125 |
-#define DR_4                                        4  // SF8  - BW500 |
-#define DR_5                                        5  // RFU
-#define DR_6                                        6  // RFU
-#define DR_7                                        7  // RFU
-#define DR_8                                        8  // SF12 - BW500 |
-#define DR_9                                        9  // SF11 - BW500 |
-#define DR_10                                       10 // SF10 - BW500 |
-#define DR_11                                       11 // SF9  - BW500 |
-#define DR_12                                       12 // SF8  - BW500 +-> Down link
-#define DR_13                                       13 // SF7  - BW500 |
-#define DR_14                                       14 // RFU          |
-#define DR_15                                       15 // RFU          |
-
-/*!
- * Second reception window channel definition.
- */
-// Channel = { Frequency [Hz], Datarate }
-#define RX_WND_2_CHANNEL                                  { 923300000, DR_8 }
-
-/*!
- * LoRaMac maximum number of bands
- */
-#define LORA_MAX_NB_BANDS                           1
-
-// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
-#define BAND0              { 1, TX_POWER_20_DBM, 0,  0 } //  100.0 %
-
-/*!
- * LoRaMac default channels
- */
-// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
-/*
- * US band channels are initialized using a loop in LoRaMacInit function
- * \code
- * // 125 kHz channels
- * for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
- * {
- *     Channels[i].Frequency = 902.3e6 + i * 200e3;
- *     Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0;
- *     Channels[i].Band = 0;
- * }
- * // 500 kHz channels
- * for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
- * {
- *     Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
- *     Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
- *     Channels[i].Band = 0;
- * }
- * \endcode
- */
-#else
-    #error "Please define a frequency band in the compiler options."
-#endif
-
-#endif // __LORAMAC_BOARD_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LoRaMac-definitions.h	Tue Jul 05 13:24:54 2016 +0000
@@ -0,0 +1,522 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: LoRa MAC layer global definitions
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __LORAMAC_BOARD_H__
+#define __LORAMAC_BOARD_H__
+
+/*!
+ * Returns individual channel mask
+ *
+ * \param[IN] channelIndex Channel index 1 based
+ * \retval channelMask
+ */
+#define LC( channelIndex )            ( uint16_t )( 1 << ( channelIndex - 1 ) )
+
+#if defined( USE_BAND_433 )
+
+/*!
+ * LoRaMac maximum number of channels
+ */
+#define LORA_MAX_NB_CHANNELS                        16
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MAX_DATARATE                     DR_7
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MAX_DATARATE                     DR_7
+
+/*!
+ * Default datarate used by the node
+ */
+#define LORAMAC_DEFAULT_DATARATE                    DR_0
+
+/*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
+ * Minimal Tx output power that can be used by the node
+ */
+#define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
+
+/*!
+ * Maximal Tx output power that can be used by the node
+ */
+#define LORAMAC_MAX_TX_POWER                        TX_POWER_10_DBM
+
+/*!
+ * Default Tx output power used by the node
+ */
+#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_10_DBM
+
+/*!
+ * LoRaMac TxPower definition
+ */
+#define TX_POWER_10_DBM                             0
+#define TX_POWER_07_DBM                             1
+#define TX_POWER_04_DBM                             2
+#define TX_POWER_01_DBM                             3
+#define TX_POWER_M2_DBM                             4
+#define TX_POWER_M5_DBM                             5
+
+/*!
+ * LoRaMac datarates definition
+ */
+#define DR_0                                        0  // SF12 - BW125
+#define DR_1                                        1  // SF11 - BW125
+#define DR_2                                        2  // SF10 - BW125
+#define DR_3                                        3  // SF9  - BW125
+#define DR_4                                        4  // SF8  - BW125
+#define DR_5                                        5  // SF7  - BW125
+#define DR_6                                        6  // SF7  - BW250
+#define DR_7                                        7  // FSK
+
+/*!
+ * Second reception window channel definition.
+ */
+// Channel = { Frequency [Hz], Datarate }
+#define RX_WND_2_CHANNEL                                  { 434665000, DR_0 }
+
+/*!
+ * LoRaMac maximum number of bands
+ */
+#define LORA_MAX_NB_BANDS                           1
+
+// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
+#define BAND0              { 100, TX_POWER_10_DBM, 0,  0 } //  1.0 %
+
+/*!
+ * LoRaMac default channels
+ */
+// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
+#define LC1                { 433175000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC2                { 433375000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC3                { 433575000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+
+/*!
+ * LoRaMac duty cycle for the back-off procedure
+ */
+#define BACKOFF_DC_1_HOUR       100
+#define BACKOFF_DC_10_HOURS     1000
+#define BACKOFF_DC_24_HOURS     10000
+
+#define BACKOFF_RND_OFFSET      600000
+
+/*!
+ * LoRaMac channels which are allowed for the join procedure
+ */
+#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
+
+#elif defined( USE_BAND_780 )
+
+/*!
+ * LoRaMac maximum number of channels
+ */
+#define LORA_MAX_NB_CHANNELS                        16
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MAX_DATARATE                     DR_7
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MAX_DATARATE                     DR_7
+
+/*!
+ * Default datarate used by the node
+ */
+#define LORAMAC_DEFAULT_DATARATE                    DR_0
+
+/*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
+ * Minimal Tx output power that can be used by the node
+ */
+#define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
+
+/*!
+ * Maximal Tx output power that can be used by the node
+ */
+#define LORAMAC_MAX_TX_POWER                        TX_POWER_10_DBM
+
+/*!
+ * Default Tx output power used by the node
+ */
+#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_10_DBM
+
+/*!
+ * LoRaMac TxPower definition
+ */
+#define TX_POWER_10_DBM                             0
+#define TX_POWER_07_DBM                             1
+#define TX_POWER_04_DBM                             2
+#define TX_POWER_01_DBM                             3
+#define TX_POWER_M2_DBM                             4
+#define TX_POWER_M5_DBM                             5
+
+/*!
+ * LoRaMac datarates definition
+ */
+#define DR_0                                        0  // SF12 - BW125
+#define DR_1                                        1  // SF11 - BW125
+#define DR_2                                        2  // SF10 - BW125
+#define DR_3                                        3  // SF9  - BW125
+#define DR_4                                        4  // SF8  - BW125
+#define DR_5                                        5  // SF7  - BW125
+#define DR_6                                        6  // SF7  - BW250
+#define DR_7                                        7  // FSK
+
+/*!
+ * Second reception window channel definition.
+ */
+// Channel = { Frequency [Hz], Datarate }
+#define RX_WND_2_CHANNEL                                  { 786000000, DR_0 }
+
+/*!
+ * LoRaMac maximum number of bands
+ */
+#define LORA_MAX_NB_BANDS                           1
+
+// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
+#define BAND0              { 100, TX_POWER_10_DBM, 0,  0 } //  1.0 %
+
+/*!
+ * LoRaMac default channels
+ */
+// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
+#define LC1                { 779500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC2                { 779700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC3                { 779900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+
+/*!
+ * LoRaMac duty cycle for the back-off procedure
+ */
+#define BACKOFF_DC_1_HOUR       100
+#define BACKOFF_DC_10_HOURS     1000
+#define BACKOFF_DC_24_HOURS     10000
+
+#define BACKOFF_RND_OFFSET      600000
+
+/*!
+ * LoRaMac channels which are allowed for the join procedure
+ */
+#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
+
+#elif defined( USE_BAND_868 )
+
+/*!
+ * LoRaMac maximum number of channels
+ */
+#define LORA_MAX_NB_CHANNELS                        16
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MAX_DATARATE                     DR_7
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MAX_DATARATE                     DR_7
+
+/*!
+ * Default datarate used by the node
+ */
+#define LORAMAC_DEFAULT_DATARATE                    DR_0
+
+/*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
+ * Minimal Tx output power that can be used by the node
+ */
+#define LORAMAC_MIN_TX_POWER                        TX_POWER_02_DBM
+
+/*!
+ * Maximal Tx output power that can be used by the node
+ */
+#define LORAMAC_MAX_TX_POWER                        TX_POWER_20_DBM
+
+/*!
+ * Default Tx output power used by the node
+ */
+#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_14_DBM
+
+/*!
+ * LoRaMac TxPower definition
+ */
+#define TX_POWER_20_DBM                             0
+#define TX_POWER_14_DBM                             1
+#define TX_POWER_11_DBM                             2
+#define TX_POWER_08_DBM                             3
+#define TX_POWER_05_DBM                             4
+#define TX_POWER_02_DBM                             5
+
+/*!
+ * LoRaMac datarates definition
+ */
+#define DR_0                                        0  // SF12 - BW125
+#define DR_1                                        1  // SF11 - BW125
+#define DR_2                                        2  // SF10 - BW125
+#define DR_3                                        3  // SF9  - BW125
+#define DR_4                                        4  // SF8  - BW125
+#define DR_5                                        5  // SF7  - BW125
+#define DR_6                                        6  // SF7  - BW250
+#define DR_7                                        7  // FSK
+
+/*!
+ * Second reception window channel definition.
+ */
+// Channel = { Frequency [Hz], Datarate }
+#define RX_WND_2_CHANNEL                                  { 869525000, DR_0 }
+
+/*!
+ * LoRaMac maximum number of bands
+ */
+#define LORA_MAX_NB_BANDS                           5
+
+/*!
+ * LoRaMac EU868 default bands
+ */
+typedef enum
+{
+    BAND_G1_0,
+    BAND_G1_1,
+    BAND_G1_2,
+    BAND_G1_3,
+    BAND_G1_4,
+}BandId_t;
+
+// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
+#define BAND0              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
+#define BAND1              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
+#define BAND2              { 1000, TX_POWER_14_DBM, 0,  0 } //  0.1 %
+#define BAND3              { 10  , TX_POWER_14_DBM, 0,  0 } // 10.0 %
+#define BAND4              { 100 , TX_POWER_14_DBM, 0,  0 } //  1.0 %
+
+/*!
+ * LoRaMac default channels
+ */
+// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
+#define LC1                { 868100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
+#define LC2                { 868300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
+#define LC3                { 868500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
+
+/*!
+ * LoRaMac duty cycle for the back-off procedure
+ */
+#define BACKOFF_DC_1_HOUR       100
+#define BACKOFF_DC_10_HOURS     1000
+#define BACKOFF_DC_24_HOURS     10000
+
+#define BACKOFF_RND_OFFSET      600000
+
+/*!
+ * LoRaMac channels which are allowed for the join procedure
+ */
+#define JOIN_CHANNELS      ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
+
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+
+/*!
+ * LoRaMac maximum number of channels
+ */
+#define LORA_MAX_NB_CHANNELS                        72
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MIN_DATARATE                     DR_0
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_TX_MAX_DATARATE                     DR_4
+
+/*!
+ * Minimal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MIN_DATARATE                     DR_8
+
+/*!
+ * Maximal datarate that can be used by the node
+ */
+#define LORAMAC_RX_MAX_DATARATE                     DR_13
+
+/*!
+ * Default datarate used by the node
+ */
+#define LORAMAC_DEFAULT_DATARATE                    DR_0
+
+/*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   3
+
+/*!
+ * Minimal Tx output power that can be used by the node
+ */
+#define LORAMAC_MIN_TX_POWER                        TX_POWER_10_DBM
+
+/*!
+ * Maximal Tx output power that can be used by the node
+ */
+#define LORAMAC_MAX_TX_POWER                        TX_POWER_30_DBM
+
+/*!
+ * Default Tx output power used by the node
+ */
+#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_20_DBM
+
+/*!
+ * LoRaMac TxPower definition
+ */
+#define TX_POWER_30_DBM                             0
+#define TX_POWER_28_DBM                             1
+#define TX_POWER_26_DBM                             2
+#define TX_POWER_24_DBM                             3
+#define TX_POWER_22_DBM                             4
+#define TX_POWER_20_DBM                             5
+#define TX_POWER_18_DBM                             6
+#define TX_POWER_16_DBM                             7
+#define TX_POWER_14_DBM                             8
+#define TX_POWER_12_DBM                             9
+#define TX_POWER_10_DBM                             10
+
+/*!
+ * LoRaMac datarates definition
+ */
+#define DR_0                                        0  // SF10 - BW125 |
+#define DR_1                                        1  // SF9  - BW125 |
+#define DR_2                                        2  // SF8  - BW125 +-> Up link
+#define DR_3                                        3  // SF7  - BW125 |
+#define DR_4                                        4  // SF8  - BW500 |
+#define DR_5                                        5  // RFU
+#define DR_6                                        6  // RFU
+#define DR_7                                        7  // RFU
+#define DR_8                                        8  // SF12 - BW500 |
+#define DR_9                                        9  // SF11 - BW500 |
+#define DR_10                                       10 // SF10 - BW500 |
+#define DR_11                                       11 // SF9  - BW500 |
+#define DR_12                                       12 // SF8  - BW500 +-> Down link
+#define DR_13                                       13 // SF7  - BW500 |
+#define DR_14                                       14 // RFU          |
+#define DR_15                                       15 // RFU          |
+
+/*!
+ * Second reception window channel definition.
+ */
+// Channel = { Frequency [Hz], Datarate }
+#define RX_WND_2_CHANNEL                                  { 923300000, DR_8 }
+
+/*!
+ * LoRaMac maximum number of bands
+ */
+#define LORA_MAX_NB_BANDS                           1
+
+// Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff }
+#define BAND0              { 1, TX_POWER_20_DBM, 0,  0 } //  100.0 %
+
+#define BACKOFF_RND_OFFSET      600000
+
+/*!
+ * LoRaMac default channels
+ */
+// Channel = { Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
+/*
+ * US band channels are initialized using a loop in LoRaMacInit function
+ * \code
+ * // 125 kHz channels
+ * for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
+ * {
+ *     Channels[i].Frequency = 902.3e6 + i * 200e3;
+ *     Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0;
+ *     Channels[i].Band = 0;
+ * }
+ * // 500 kHz channels
+ * for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
+ * {
+ *     Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
+ *     Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
+ *     Channels[i].Band = 0;
+ * }
+ * \endcode
+ */
+#else
+    #error "Please define a frequency band in the compiler options."
+#endif
+
+#endif // __LORAMAC_BOARD_H__
--- a/LoRaMac.cpp	Wed May 18 11:19:24 2016 +0000
+++ b/LoRaMac.cpp	Tue Jul 05 13:24:54 2016 +0000
@@ -186,10 +186,20 @@
 static uint8_t MacCommandsBufferIndex = 0;
 
 /*!
+ * Contains the current MacCommandsBuffer index for MAC commands to repeat
+ */
+static uint8_t MacCommandsBufferToRepeatIndex = 0;
+
+/*!
  * Buffer containing the MAC layer commands
  */
 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
 
+/*!
+ * Buffer containing the MAC layer commands which must be repeated
+ */
+static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH];
+
 #if defined( USE_BAND_433 )
 /*!
  * Data rates table definition
@@ -324,28 +334,17 @@
     { DR_12, DR_11, DR_10, DR_9  }, // DR_2
     { DR_13, DR_12, DR_11, DR_10 }, // DR_3
     { DR_13, DR_13, DR_12, DR_11 }, // DR_4
-    { 0xFF , 0xFF , 0xFF , 0xFF  },
-    { 0xFF , 0xFF , 0xFF , 0xFF  },
-    { 0xFF , 0xFF , 0xFF , 0xFF  },
-    { DR_8 , DR_8 , DR_8 , DR_8  },
-    { DR_9 , DR_8 , DR_8 , DR_8  },
-    { DR_10, DR_9 , DR_8 , DR_8  },
-    { DR_11, DR_10, DR_9 , DR_8  },
-    { DR_12, DR_11, DR_10, DR_9  },
-    { DR_13, DR_12, DR_11, DR_10 },
-    { 0xFF , 0xFF , 0xFF , 0xFF  },
-    { 0xFF , 0xFF , 0xFF , 0xFF  },
 };
 
 /*!
  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
  */
-const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 129, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
+const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
 
 /*!
  * Maximum payload with respect to the datarate index. Can operate with repeater.
  */
-const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 129, 242, 242, 0, 0, 0, 33, 103, 222, 222, 222, 222, 0, 0 };
+const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 };
 
 /*!
  * Tx output powers table definition
@@ -369,44 +368,35 @@
  * Contains the channels which remain to be applied.
  */
 static uint16_t ChannelsMaskRemaining[6];
+
+/*!
+ * Defines the first channel for RX window 2 for US band
+ */
+#define LORAMAC_FIRST_RX2_CHANNEL           ( (uint32_t) 923.3e6 )
+
+/*!
+ * Defines the last channel for RX window 2 for US band
+ */
+#define LORAMAC_LAST_RX2_CHANNEL            ( (uint32_t) 927.5e6 )
+
+/*!
+ * Defines the step width of the channels for RX window 2
+ */
+#define LORAMAC_STEPWIDTH_RX2_CHANNEL       ( (uint32_t) 600e3 )
+
 #else
     #error "Please define a frequency band in the compiler options."
 #endif
 
 /*!
- * LoRaMAC 2nd reception window settings
- */
-static Rx2ChannelParams_t Rx2Channel = RX_WND_2_CHANNEL;
-
-/*!
- * Datarate offset between uplink and downlink on first window
+ * LoRaMac parameters
  */
-static uint8_t Rx1DrOffset = 0;
-
-/*!
- * Mask indicating which channels are enabled
- */
-static uint16_t ChannelsMask[6];
+LoRaMacParams_t LoRaMacParams;
 
 /*!
- * Channels Tx output power
- */
-static int8_t ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
-
-/*!
- * Channels datarate
+ * LoRaMac default parameters
  */
-static int8_t ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
-
-/*!
- * Channels default datarate
- */
-static int8_t ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE;
-
-/*!
- * Number of uplink messages repetitions [1:15] (unconfirmed messages only)
- */
-static uint8_t ChannelsNbRep = 1;
+LoRaMacParams_t LoRaMacParamsDefaults;
 
 /*!
  * Uplink messages repetitions counter
@@ -436,6 +426,9 @@
  */
 static uint8_t Channel;
 
+/*!
+ * Channel index of the last transmission
+ */
 static uint8_t LastTxChannel;
 
 /*!
@@ -490,14 +483,6 @@
 static TimerEvent_t RxWindowTimer2;
 
 /*!
- * LoRaMac reception windows delay from end of Tx
- */
-static uint32_t ReceiveDelay1;
-static uint32_t ReceiveDelay2;
-static uint32_t JoinAcceptDelay1;
-static uint32_t JoinAcceptDelay2;
-
-/*!
  * LoRaMac reception windows delay
  * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME
  *         join frame  : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME
@@ -506,11 +491,6 @@
 static uint32_t RxWindow2Delay;
 
 /*!
- * LoRaMac maximum time a reception window stays open
- */
-static uint32_t MaxRxWindow;
-
-/*!
  * Acknowledge timeout timer. Used for packet retransmissions.
  */
 static TimerEvent_t AckTimeoutTimer;
@@ -536,6 +516,11 @@
 TimerTime_t TxTimeOnAir = 0;
 
 /*!
+ * Number of trials for the Join Request
+ */
+static uint16_t JoinRequestTrials;
+
+/*!
  * Structure to hold an MCPS indication data.
  */
 static McpsIndication_t McpsIndication;
@@ -645,6 +630,15 @@
 static void RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous );
 
 /*!
+ * \brief Verifies if the RX window 2 frequency is in range
+ *
+ * \param [IN] freq window channel frequency
+ *
+ * \retval status  Function status [1: OK, 0: Frequency not applicable]
+ */
+static bool Rx2FreqInRange( uint32_t freq );
+
+/*!
  * \brief Adds a new MAC command to be sent.
  *
  * \Remark MAC layer internal function
@@ -664,6 +658,20 @@
 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 );
 
 /*!
+ * \brief Parses the MAC commands which must be repeated.
+ *
+ * \Remark MAC layer internal function
+ *
+ * \param [IN] cmdBufIn  Buffer which stores the MAC commands to send
+ * \param [IN] length  Length of the input buffer to parse
+ * \param [OUT] cmdBufOut  Buffer which stores the MAC commands which must be
+ *                         repeated.
+ *
+ * \retval Size of the MAC commands to repeat.
+ */
+static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut );
+
+/*!
  * \brief Validates if the payload fits into the frame, taking the datarate
  *        into account.
  *
@@ -804,12 +812,27 @@
 static LoRaMacStatus_t ScheduleTx( void );
 
 /*
+ * \brief Sets the duty cycle for retransmissions
+ *
+ * \retval Duty cycle
+ */
+static uint16_t RetransmissionDutyCylce( void );
+
+/*
  * \brief Calculates the back-off time for the band of a channel.
  *
  * \param [IN] channel     The last Tx channel index
  */
 static void CalculateBackOff( uint8_t channel );
 
+/*
+ * \brief Alternates the datarate of the channel for the join request.
+ *
+ * \param [IN] nbTrials    Number of performed join requests.
+ * \retval Datarate to apply
+ */
+static int8_t AlternateDatarate( uint16_t nbTrials );
+
 /*!
  * \brief LoRaMAC layer prepared frame buffer transmission with channel specification
  *
@@ -821,7 +844,10 @@
  */
 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel );
 
-
+/*!
+ * \brief Resets MAC specific parameters to default
+ */
+static void ResetMacParameters( void );
 
 static void OnRadioTxDone( void )
 {
@@ -980,26 +1006,26 @@
                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
 
                 // DLSettings
-                Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
-                Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
+                LoRaMacParams.Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
+                LoRaMacParams.Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
                 /*
                  * WARNING: To be removed once Semtech server implementation
                  *          is corrected.
                  */
-                if( Rx2Channel.Datarate == DR_3 )
+                if( LoRaMacParams.Rx2Channel.Datarate == DR_3 )
                 {
-                    Rx2Channel.Datarate = DR_8;
+                    LoRaMacParams.Rx2Channel.Datarate = DR_8;
                 }
 #endif
                 // RxDelay
-                ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
-                if( ReceiveDelay1 == 0 )
+                LoRaMacParams.ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
+                if( LoRaMacParams.ReceiveDelay1 == 0 )
                 {
-                    ReceiveDelay1 = 1;
+                    LoRaMacParams.ReceiveDelay1 = 1;
                 }
-                ReceiveDelay1 *= 1e6;
-                ReceiveDelay2 = ReceiveDelay1 + 1e6;
+                LoRaMacParams.ReceiveDelay1 *= 1e6;
+                LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e6;
 
 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
                 //CFList
@@ -1019,7 +1045,7 @@
 #endif
                 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
                 IsLoRaMacNetworkJoined = true;
-                ChannelsDatarate = ChannelsDefaultDatarate;
+                LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
             }
             else
             {
@@ -1122,6 +1148,7 @@
                     McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
 
                     AdrAckCounter = 0;
+                    MacCommandsBufferToRepeatIndex = 0;
 
                     // Update 32 bits downlink counter
                     if( multicast == 1 )
@@ -1191,11 +1218,6 @@
                         }
                     }
 
-                    if( fCtrl.Bits.FOptsLen > 0 )
-                    {
-                        // Decode Options field MAC commands
-                        ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
-                    }
                     if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
                     {
                         port = payload[appPayloadStartIndex++];
@@ -1205,19 +1227,32 @@
 
                         if( port == 0 )
                         {
-                            LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
-                                                   frameLen,
-                                                   nwkSKey,
-                                                   address,
-                                                   DOWN_LINK,
-                                                   downLinkCounter,
-                                                   LoRaMacRxPayload );
-
-                            // Decode frame payload MAC commands
-                            ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
+                            if( fCtrl.Bits.FOptsLen == 0 )
+                            {
+                                LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
+                                                       frameLen,
+                                                       nwkSKey,
+                                                       address,
+                                                       DOWN_LINK,
+                                                       downLinkCounter,
+                                                       LoRaMacRxPayload );
+
+                                // Decode frame payload MAC commands
+                                ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
+                            }
+                            else
+                            {
+                                skipIndication = true;
+                            }
                         }
                         else
                         {
+                            if( fCtrl.Bits.FOptsLen > 0 )
+                            {
+                                // Decode Options field MAC commands. Omit the fPort.
+                                ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr );
+                            }
+
                             LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
                                                    frameLen,
                                                    appSKey,
@@ -1234,6 +1269,15 @@
                             }
                         }
                     }
+                    else
+                    {
+                        if( fCtrl.Bits.FOptsLen > 0 )
+                        {
+                            // Decode Options field MAC commands
+                            ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
+                        }
+                    }
+
                     if( skipIndication == false )
                     {
                         LoRaMacFlags.Bits.McpsInd = 1;
@@ -1370,17 +1414,20 @@
             {
                 if( MlmeConfirm.MlmeRequest == MLME_JOIN )
                 {
+                    // Retransmit only if the answer is not OK
+                    ChannelsNbRepCounter = 0;
+
                     if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK )
                     {
+                        // Stop retransmission
+                        ChannelsNbRepCounter = LoRaMacParams.ChannelsNbRep;
                         UpLinkCounter = 0;
                     }
-                    // Join messages aren't repeated automatically
-                    ChannelsNbRepCounter = ChannelsNbRep;
                 }
             }
             if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) )
             {
-                if( ( ChannelsNbRepCounter >= ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) )
+                if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) )
                 {
                     ChannelsNbRepCounter = 0;
 
@@ -1426,7 +1473,7 @@
 
                 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
                 {
-                    ChannelsDatarate = MAX( ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE );
+                    LoRaMacParams.ChannelsDatarate = MAX( LoRaMacParams.ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE );
                 }
                 LoRaMacFlags.Bits.MacDone = 0;
                 // Sends the same frame again
@@ -1436,18 +1483,18 @@
             {
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
                 // Re-enable default channels LC1, LC2, LC3
-                ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+                LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
 #elif defined( USE_BAND_915 )
                 // Re-enable default channels
-                ChannelsMask[0] = 0xFFFF;
-                ChannelsMask[1] = 0xFFFF;
-                ChannelsMask[2] = 0xFFFF;
-                ChannelsMask[3] = 0xFFFF;
-                ChannelsMask[4] = 0x00FF;
-                ChannelsMask[5] = 0x0000;
+                LoRaMacParams.ChannelsMask[0] = 0xFFFF;
+                LoRaMacParams.ChannelsMask[1] = 0xFFFF;
+                LoRaMacParams.ChannelsMask[2] = 0xFFFF;
+                LoRaMacParams.ChannelsMask[3] = 0xFFFF;
+                LoRaMacParams.ChannelsMask[4] = 0x00FF;
+                LoRaMacParams.ChannelsMask[5] = 0x0000;
 #elif defined( USE_BAND_915_HYBRID )
                 // Re-enable default channels
-                ReenableChannels( ChannelsMask[4], ChannelsMask );
+                ReenableChannels( LoRaMacParams.ChannelsMask[4], LoRaMacParams.ChannelsMask );
 #else
     #error "Please define a frequency band in the compiler options."
 #endif
@@ -1500,9 +1547,26 @@
 
 static void OnTxDelayedTimerEvent( void )
 {
+    LoRaMacHeader_t macHdr;
+    LoRaMacFrameCtrl_t fCtrl;
+
     TimerStop( &TxDelayedTimer );
     LoRaMacState &= ~MAC_TX_DELAYED;
 
+    if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) )
+    {
+        macHdr.Value = 0;
+        macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
+
+        fCtrl.Value = 0;
+        fCtrl.Bits.Adr = AdrCtrlOn;
+
+        /* In case of a join request retransmission, the stack must prepare
+         * the frame again, because the network server keeps track of the random
+         * LoRaMacDevNonce values to prevent reply attacks. */
+        PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 );
+    }
+
     ScheduleTx( );
 }
 
@@ -1521,7 +1585,7 @@
     }
 
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
-    datarate = ChannelsDatarate - Rx1DrOffset;
+    datarate = LoRaMacParams.ChannelsDatarate - LoRaMacParams.Rx1DrOffset;
     if( datarate < 0 )
     {
         datarate = DR_0;
@@ -1543,7 +1607,7 @@
     }
     RxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false );
 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
-    datarate = datarateOffsets[ChannelsDatarate][Rx1DrOffset];
+    datarate = datarateOffsets[LoRaMacParams.ChannelsDatarate][LoRaMacParams.Rx1DrOffset];
     if( datarate < 0 )
     {
         datarate = DR_0;
@@ -1583,7 +1647,7 @@
     {// LoRa 500 kHz
         bandwidth  = 2;
     }
-    RxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false );
+    RxWindowSetup( LORAMAC_FIRST_RX2_CHANNEL + ( Channel % 8 ) * LORAMAC_STEPWIDTH_RX2_CHANNEL, datarate, bandwidth, symbTimeout, false );
 #else
     #error "Please define a frequency band in the compiler options."
 #endif
@@ -1599,22 +1663,22 @@
 
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
     // For higher datarates, we increase the number of symbols generating a Rx Timeout
-    if( ( Rx2Channel.Datarate == DR_3 ) || ( Rx2Channel.Datarate == DR_4 ) )
+    if( ( LoRaMacParams.Rx2Channel.Datarate == DR_3 ) || ( LoRaMacParams.Rx2Channel.Datarate == DR_4 ) )
     { // DR_4, DR_3
         symbTimeout = 8;
     }
-    else if( Rx2Channel.Datarate == DR_5 )
+    else if( LoRaMacParams.Rx2Channel.Datarate == DR_5 )
     {
         symbTimeout = 10;
     }
-    else if( Rx2Channel.Datarate == DR_6 )
+    else if( LoRaMacParams.Rx2Channel.Datarate == DR_6 )
     {// LoRa 250 kHz
         bandwidth  = 1;
         symbTimeout = 14;
     }
 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
     // For higher datarates, we increase the number of symbols generating a Rx Timeout
-    switch( Rx2Channel.Datarate )
+    switch( LoRaMacParams.Rx2Channel.Datarate )
     {
         case DR_0:       // SF10 - BW125
             symbTimeout = 5;
@@ -1644,7 +1708,7 @@
         default:
             break;
     }
-    if( Rx2Channel.Datarate >= DR_4 )
+    if( LoRaMacParams.Rx2Channel.Datarate >= DR_4 )
     {// LoRa 500 kHz
         bandwidth  = 2;
     }
@@ -1653,11 +1717,11 @@
 #endif
     if( LoRaMacDeviceClass != CLASS_C )
     {
-        RxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, false );
+        RxWindowSetup( LoRaMacParams.Rx2Channel.Frequency, LoRaMacParams.Rx2Channel.Datarate, bandwidth, symbTimeout, false );
     }
     else
     {
-        RxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, true );
+        RxWindowSetup( LoRaMacParams.Rx2Channel.Frequency, LoRaMacParams.Rx2Channel.Datarate, bandwidth, symbTimeout, true );
     }
 }
 
@@ -1688,17 +1752,17 @@
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
     if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
     { // Restore default channels
-        memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, 8 );
+        memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask, 8 );
     }
-    if( ( ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
+    if( ( LoRaMacParams.ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
     { // Make sure, that the channels are activated
-        ChannelsMaskRemaining[4] = ChannelsMask[4];
+        ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask[4];
     }
 #else
-    if( CountBits( ChannelsMask[0], 16 ) == 0 )
+    if( CountBits( LoRaMacParams.ChannelsMask[0], 16 ) == 0 )
     {
         // Re-enable default channels, if no channel is enabled
-        ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+        LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
     }
 #endif
 
@@ -1738,7 +1802,7 @@
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
                 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 )
 #else
-                if( ( ChannelsMask[k] & ( 1 << j ) ) != 0 )
+                if( ( LoRaMacParams.ChannelsMask[k] & ( 1 << j ) ) != 0 )
 #endif
                 {
                     if( Channels[i + j].Frequency == 0 )
@@ -1754,8 +1818,8 @@
                         }
                     }
 #endif
-                    if( ( ( Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate ) &&
-                          ( ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
+                    if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate ) &&
+                          ( LoRaMacParams.ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
                     { // Check if the current channel selection supports the given datarate
                         continue;
                     }
@@ -1856,7 +1920,7 @@
 
         if( rxContinuous == false )
         {
-            Radio.Rx( MaxRxWindow );
+            Radio.Rx( LoRaMacParams.MaxRxWindow );
         }
         else
         {
@@ -1865,6 +1929,22 @@
     }
 }
 
+static bool Rx2FreqInRange( uint32_t freq )
+{
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
+    if( Radio.CheckRfFrequency( freq ) == true )
+#elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
+    if( ( Radio.CheckRfFrequency( freq ) == true ) &&
+        ( freq >= LORAMAC_FIRST_RX2_CHANNEL ) &&
+        ( freq <= LORAMAC_LAST_RX2_CHANNEL ) &&
+        ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX2_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX2_CHANNEL ) == 0 ) )
+#endif
+    {
+        return true;
+    }
+    return false;
+}
+
 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
 {
     uint16_t maxN = 0;
@@ -1987,14 +2067,14 @@
 {
     int8_t resultTxPower = txPower;
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
-    if( ( ChannelsDatarate == DR_4 ) ||
-        ( ( ChannelsDatarate >= DR_8 ) && ( ChannelsDatarate <= DR_13 ) ) )
+    if( ( LoRaMacParams.ChannelsDatarate == DR_4 ) ||
+        ( ( LoRaMacParams.ChannelsDatarate >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate <= DR_13 ) ) )
     {// Limit tx power to max 26dBm
         resultTxPower =  MAX( txPower, TX_POWER_26_DBM );
     }
     else
     {
-        if( CountNbEnabled125kHzChannels( ChannelsMask ) < 50 )
+        if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask ) < 50 )
         {// Limit tx power to max 21dBm
             resultTxPower = MAX( txPower, TX_POWER_20_DBM );
         }
@@ -2031,7 +2111,7 @@
 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut )
 {
     bool adrAckReq = false;
-    int8_t datarate = ChannelsDatarate;
+    int8_t datarate = LoRaMacParams.ChannelsDatarate;
 
     if( adrEnabled == true )
     {
@@ -2052,7 +2132,7 @@
             }
             if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
             {
-                if( ( ( AdrAckCounter - ADR_ACK_DELAY ) % ADR_ACK_LIMIT ) == 0 )
+                if( ( AdrAckCounter % ADR_ACK_DELAY ) == 0 )
                 {
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
                     if( datarate > LORAMAC_TX_MIN_DATARATE )
@@ -2063,9 +2143,8 @@
                     {
                         if( updateChannelMask == true )
                         {
-
                             // Re-enable default channels LC1, LC2, LC3
-                            ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+                            LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
                         }
                     }
 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
@@ -2083,15 +2162,15 @@
                         {
 #if defined( USE_BAND_915 )
                             // Re-enable default channels
-                            ChannelsMask[0] = 0xFFFF;
-                            ChannelsMask[1] = 0xFFFF;
-                            ChannelsMask[2] = 0xFFFF;
-                            ChannelsMask[3] = 0xFFFF;
-                            ChannelsMask[4] = 0x00FF;
-                            ChannelsMask[5] = 0x0000;
+                            LoRaMacParams.ChannelsMask[0] = 0xFFFF;
+                            LoRaMacParams.ChannelsMask[1] = 0xFFFF;
+                            LoRaMacParams.ChannelsMask[2] = 0xFFFF;
+                            LoRaMacParams.ChannelsMask[3] = 0xFFFF;
+                            LoRaMacParams.ChannelsMask[4] = 0x00FF;
+                            LoRaMacParams.ChannelsMask[5] = 0x0000;
 #else // defined( USE_BAND_915_HYBRID )
                             // Re-enable default channels
-                            ReenableChannels( ChannelsMask[4], ChannelsMask );
+                            ReenableChannels( LoRaMacParams.ChannelsMask[4], LoRaMacParams.ChannelsMask );
 #endif
                         }
                     }
@@ -2111,11 +2190,13 @@
 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
 {
     LoRaMacStatus_t status = LORAMAC_STATUS_BUSY;
+    // The maximum buffer length must take MAC commands to re-send into account.
+    uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
 
     switch( cmd )
     {
         case MOTE_MAC_LINK_CHECK_REQ:
-            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            if( MacCommandsBufferIndex < bufLen )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // No payload for this command
@@ -2123,7 +2204,7 @@
             }
             break;
         case MOTE_MAC_LINK_ADR_ANS:
-            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            if( MacCommandsBufferIndex < ( bufLen - 1 ) )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // Margin
@@ -2132,7 +2213,7 @@
             }
             break;
         case MOTE_MAC_DUTY_CYCLE_ANS:
-            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            if( MacCommandsBufferIndex < bufLen )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // No payload for this answer
@@ -2140,7 +2221,7 @@
             }
             break;
         case MOTE_MAC_RX_PARAM_SETUP_ANS:
-            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            if( MacCommandsBufferIndex < ( bufLen - 1 ) )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // Status: Datarate ACK, Channel ACK
@@ -2149,7 +2230,7 @@
             }
             break;
         case MOTE_MAC_DEV_STATUS_ANS:
-            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 2 ) )
+            if( MacCommandsBufferIndex < ( bufLen - 2 ) )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // 1st byte Battery
@@ -2160,7 +2241,7 @@
             }
             break;
         case MOTE_MAC_NEW_CHANNEL_ANS:
-            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            if( MacCommandsBufferIndex < ( bufLen - 1 ) )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // Status: Datarate range OK, Channel frequency OK
@@ -2169,7 +2250,7 @@
             }
             break;
         case MOTE_MAC_RX_TIMING_SETUP_ANS:
-            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            if( MacCommandsBufferIndex < bufLen )
             {
                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
                 // No payload for this answer
@@ -2186,6 +2267,40 @@
     return status;
 }
 
+static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut )
+{
+    uint8_t i = 0;
+    uint8_t cmdCount = 0;
+
+    if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) )
+    {
+        return 0;
+    }
+
+    for( i = 0; i < length; i++ )
+    {
+        switch( cmdBufIn[i] )
+        {
+            case MOTE_MAC_RX_PARAM_SETUP_ANS:
+            {
+                cmdBufOut[cmdCount++] = cmdBufIn[i++];
+                cmdBufOut[cmdCount++] = cmdBufIn[i++];
+                cmdBufOut[cmdCount++] = cmdBufIn[i];
+                break;
+            }
+            case MOTE_MAC_RX_TIMING_SETUP_ANS:
+            {
+                cmdBufOut[cmdCount++] = cmdBufIn[i];
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    return cmdCount;
+}
+
 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
 {
     while( macIndex < commandsSize )
@@ -2212,14 +2327,14 @@
                     // Initialize local copy of the channels mask array
                     for( i = 0; i < 6; i++ )
                     {
-                        channelsMask[i] = ChannelsMask[i];
+                        channelsMask[i] = LoRaMacParams.ChannelsMask[i];
                     }
                     datarate = payload[macIndex++];
                     txPower = datarate & 0x0F;
                     datarate = ( datarate >> 4 ) & 0x0F;
 
                     if( ( AdrCtrlOn == false ) &&
-                        ( ( ChannelsDatarate != datarate ) || ( ChannelsTxPower != txPower ) ) )
+                        ( ( LoRaMacParams.ChannelsDatarate != datarate ) || ( LoRaMacParams.ChannelsTxPower != txPower ) ) )
                     { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
                         // Answer the server with fail status
                         // Power ACK     = 0
@@ -2341,17 +2456,17 @@
                     }
                     if( ( status & 0x07 ) == 0x07 )
                     {
-                        ChannelsDatarate = datarate;
-                        ChannelsTxPower = txPower;
-
-                        ChannelsMask[0] = channelsMask[0];
-                        ChannelsMask[1] = channelsMask[1];
-                        ChannelsMask[2] = channelsMask[2];
-                        ChannelsMask[3] = channelsMask[3];
-                        ChannelsMask[4] = channelsMask[4];
-                        ChannelsMask[5] = channelsMask[5];
-
-                        ChannelsNbRep = nbRep;
+                        LoRaMacParams.ChannelsDatarate = datarate;
+                        LoRaMacParams.ChannelsTxPower = txPower;
+
+                        LoRaMacParams.ChannelsMask[0] = channelsMask[0];
+                        LoRaMacParams.ChannelsMask[1] = channelsMask[1];
+                        LoRaMacParams.ChannelsMask[2] = channelsMask[2];
+                        LoRaMacParams.ChannelsMask[3] = channelsMask[3];
+                        LoRaMacParams.ChannelsMask[4] = channelsMask[4];
+                        LoRaMacParams.ChannelsMask[5] = channelsMask[5];
+
+                        LoRaMacParams.ChannelsNbRep = nbRep;
                     }
                     AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
                 }
@@ -2377,7 +2492,7 @@
                     freq |= ( uint32_t )payload[macIndex++] << 16;
                     freq *= 100;
 
-                    if( Radio.CheckRfFrequency( freq ) == false )
+                    if( Rx2FreqInRange( freq ) == false )
                     {
                         status &= 0xFE; // Channel frequency KO
                     }
@@ -2400,9 +2515,9 @@
 
                     if( ( status & 0x07 ) == 0x07 )
                     {
-                        Rx2Channel.Datarate = datarate;
-                        Rx2Channel.Frequency = freq;
-                        Rx1DrOffset = drOffset;
+                        LoRaMacParams.Rx2Channel.Datarate = datarate;
+                        LoRaMacParams.Rx2Channel.Frequency = freq;
+                        LoRaMacParams.Rx1DrOffset = drOffset;
                     }
                     AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
                 }
@@ -2493,8 +2608,8 @@
                     {
                         delay++;
                     }
-                    ReceiveDelay1 = delay * 1e6;
-                    ReceiveDelay2 = ReceiveDelay1 + 1e6;
+                    LoRaMacParams.ReceiveDelay1 = delay * 1e6;
+                    LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e6;
                     AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
                 }
                 break;
@@ -2556,11 +2671,11 @@
     while( SetNextChannel( &dutyCycleTimeOff ) == false )
     {
         // Set the default datarate
-        ChannelsDatarate = ChannelsDefaultDatarate;
+        LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
 
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
         // Re-enable default channels LC1, LC2, LC3
-        ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+        LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
 #endif
     }
 
@@ -2581,15 +2696,45 @@
     }
 }
 
+static uint16_t RetransmissionDutyCylce( void )
+{
+    uint16_t dutyCycle = 0;
+
+#if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 )
+    TimerTime_t timeElapsed = TimerGetElapsedTime( 0 );
+
+    if( timeElapsed < 3600000000 )
+    {
+        dutyCycle = BACKOFF_DC_1_HOUR;
+    }
+    else if( timeElapsed < ( 3600000000 + 36000000000 ) )
+    {
+        dutyCycle = BACKOFF_DC_10_HOURS;
+    }
+    else
+    {
+        dutyCycle = BACKOFF_DC_24_HOURS;
+    }
+#endif
+    return dutyCycle;
+}
+
 static void CalculateBackOff( uint8_t channel )
 {
     uint16_t dutyCycle = Bands[Channels[channel].Band].DCycle;
+    uint16_t joinDutyCycle = 0;
+    bool rndTimeOff = false;
 
     if( IsLoRaMacNetworkJoined == false )
     {
-#if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 )
-        dutyCycle = JOIN_DC;
-#endif
+        joinDutyCycle = RetransmissionDutyCylce( );
+        dutyCycle = MAX( dutyCycle, joinDutyCycle );
+
+        // Make sure to not apply the random back-off to the first TX
+        if( TxTimeOnAir > 0 )
+        {
+            rndTimeOff = true;
+        }
     }
 
     // Update Band Time OFF
@@ -2601,10 +2746,126 @@
     {
         Bands[Channels[channel].Band].TimeOff = 0;
     }
+
+    if( rndTimeOff == true )
+    {
+        Bands[Channels[channel].Band].TimeOff = randr( Bands[Channels[channel].Band].TimeOff,
+                                                       Bands[Channels[channel].Band].TimeOff + BACKOFF_RND_OFFSET );
+    }
+
     // Update Aggregated Time OFF
     AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
 }
 
+static int8_t AlternateDatarate( uint16_t nbTrials )
+{
+    int8_t datarate = LORAMAC_TX_MIN_DATARATE;
+#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+#if defined( USE_BAND_915 )
+    // Re-enable 500 kHz default channels
+    LoRaMacParams.ChannelsMask[4] = 0x00FF;
+#else // defined( USE_BAND_915_HYBRID )
+    // Re-enable 500 kHz default channels
+    ReenableChannels( LoRaMacParams.ChannelsMask[4], LoRaMacParams.ChannelsMask );
+#endif
+
+    if( ( nbTrials & 0x01 ) == 0x01 )
+    {
+        datarate = DR_4;
+    }
+    else
+    {
+        datarate = DR_1;
+    }
+#else
+    if( ( nbTrials % 48 ) == 0 )
+    {
+        datarate = DR_0;
+    }
+    else if( ( nbTrials % 32 ) == 0 )
+    {
+        datarate = DR_1;
+    }
+    else if( ( nbTrials % 24 ) == 0 )
+    {
+        datarate = DR_2;
+    }
+    else if( ( nbTrials % 16 ) == 0 )
+    {
+        datarate = DR_3;
+    }
+    else if( ( nbTrials % 8 ) == 0 )
+    {
+        datarate = DR_4;
+    }
+    else
+    {
+        datarate = DR_5;
+    }
+#endif
+    return datarate;
+}
+
+static void ResetMacParameters( void )
+{
+    IsLoRaMacNetworkJoined = false;
+
+    // Counters
+    UpLinkCounter = 1;
+    DownLinkCounter = 0;
+    AdrAckCounter = 0;
+
+    ChannelsNbRepCounter = 0;
+
+    AckTimeoutRetries = 1;
+    AckTimeoutRetriesCounter = 1;
+    AckTimeoutRetry = false;
+
+    MaxDCycle = 0;
+    AggregatedDCycle = 1;
+
+    MacCommandsBufferIndex = 0;
+    MacCommandsBufferToRepeatIndex = 0;
+
+    IsRxWindowsEnabled = true;
+
+    LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower;
+    LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
+
+    LoRaMacParams.MaxRxWindow = LoRaMacParamsDefaults.MaxRxWindow;
+    LoRaMacParams.ReceiveDelay1 = LoRaMacParamsDefaults.ReceiveDelay1;
+    LoRaMacParams.ReceiveDelay2 = LoRaMacParamsDefaults.ReceiveDelay2;
+    LoRaMacParams.JoinAcceptDelay1 = LoRaMacParamsDefaults.JoinAcceptDelay1;
+    LoRaMacParams.JoinAcceptDelay2 = LoRaMacParamsDefaults.JoinAcceptDelay2;
+
+    LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset;
+    LoRaMacParams.ChannelsNbRep = LoRaMacParamsDefaults.ChannelsNbRep;
+
+    LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel;
+
+    memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
+
+#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+    memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
+#endif
+
+
+    NodeAckRequested = false;
+    SrvAckRequested = false;
+    MacCommandsInNextTx = false;
+
+    // Reset Multicast downlink counters
+    MulticastParams_t *cur = MulticastChannels;
+    while( cur != NULL )
+    {
+        cur->DownLinkCounter = 0;
+        cur = cur->Next;
+    }
+
+    // Initialize channel index.
+    Channel = LORA_MAX_NB_CHANNELS;
+}
+
 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
 {
     uint16_t i;
@@ -2628,8 +2889,8 @@
     switch( macHdr->Bits.MType )
     {
         case FRAME_TYPE_JOIN_REQ:
-            RxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME;
-            RxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME;
+            RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 - RADIO_WAKEUP_TIME;
+            RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 - RADIO_WAKEUP_TIME;
 
             LoRaMacBufferPktLen = pktHeaderLen;
 
@@ -2660,15 +2921,15 @@
                 return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet
             }
 
-            fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &ChannelsDatarate );
-
-            if( ValidatePayloadLength( fBufferSize, ChannelsDatarate, MacCommandsBufferIndex ) == false )
+            fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &LoRaMacParams.ChannelsDatarate );
+
+            if( ValidatePayloadLength( fBufferSize, LoRaMacParams.ChannelsDatarate, MacCommandsBufferIndex ) == false )
             {
                 return LORAMAC_STATUS_LENGTH_ERROR;
             }
 
-            RxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME;
-            RxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME;
+            RxWindow1Delay = LoRaMacParams.ReceiveDelay1 - RADIO_WAKEUP_TIME;
+            RxWindow2Delay = LoRaMacParams.ReceiveDelay2 - RADIO_WAKEUP_TIME;
 
             if( SrvAckRequested == true )
             {
@@ -2686,6 +2947,10 @@
             LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
             LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
 
+            // Copy the MAC commands which must be re-send into the MAC command buffer
+            memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );
+            MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
+
             if( ( payload != NULL ) && ( payloadSize > 0 ) )
             {
                 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) )
@@ -2710,6 +2975,12 @@
                 }
             }
             MacCommandsInNextTx = false;
+            // Store MAC commands which must be re-send in case the device does not receive a downlink anymore
+            MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );
+            if( MacCommandsBufferToRepeatIndex > 0 )
+            {
+                MacCommandsInNextTx = true;
+            }
             MacCommandsBufferIndex = 0;
 
             if( ( payload != NULL ) && ( payloadSize > 0 ) )
@@ -2754,29 +3025,29 @@
 
 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel )
 {
-    int8_t datarate = Datarates[ChannelsDatarate];
+    int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate];
     int8_t txPowerIndex = 0;
     int8_t txPower = 0;
 
-    txPowerIndex = LimitTxPower( ChannelsTxPower );
+    txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower );
     txPower = TxPowers[txPowerIndex];
 
     MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
     McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
-    McpsConfirm.Datarate = ChannelsDatarate;
+    McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate;
     McpsConfirm.TxPower = txPowerIndex;
 
     Radio.SetChannel( channel.Frequency );
 
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
-    if( ChannelsDatarate == DR_7 )
+    if( LoRaMacParams.ChannelsDatarate == DR_7 )
     { // High Speed FSK channel
         Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen );
         Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e6 );
         TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
 
     }
-    else if( ChannelsDatarate == DR_6 )
+    else if( LoRaMacParams.ChannelsDatarate == DR_6 )
     { // High speed LoRa channel
         Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
@@ -2790,7 +3061,7 @@
     }
 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
     Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
-    if( ChannelsDatarate >= DR_4 )
+    if( LoRaMacParams.ChannelsDatarate >= DR_4 )
     { // High speed LoRa channel BW500 kHz
         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
         TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
@@ -2840,40 +3111,64 @@
     LoRaMacFlags.Value = 0;
 
     LoRaMacDeviceClass = CLASS_A;
-
-    UpLinkCounter = 1;
-    DownLinkCounter = 0;
-    AdrAckCounter = 0;
-
+    LoRaMacState = MAC_IDLE;
+
+    JoinRequestTrials = 0;
     RepeaterSupport = false;
-    IsRxWindowsEnabled = true;
-    IsLoRaMacNetworkJoined = false;
-    LoRaMacState = MAC_IDLE;
-
+
+    // Reset duty cycle times
+    AggregatedLastTxDoneTime = 0;
+    AggregatedTimeOff = 0;
+
+    // Duty cycle
 #if defined( USE_BAND_433 )
-    ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
+    DutyCycleOn = false;
 #elif defined( USE_BAND_780 )
-    ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
+    DutyCycleOn = false;
 #elif defined( USE_BAND_868 )
-    ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
+    DutyCycleOn = true;
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+    DutyCycleOn = false;
+#else
+    #error "Please define a frequency band in the compiler options."
+#endif
+
+    // Reset to defaults
+    LoRaMacParamsDefaults.ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
+    LoRaMacParamsDefaults.ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
+
+    LoRaMacParamsDefaults.MaxRxWindow = MAX_RX_WINDOW;
+    LoRaMacParamsDefaults.ReceiveDelay1 = RECEIVE_DELAY1;
+    LoRaMacParamsDefaults.ReceiveDelay2 = RECEIVE_DELAY2;
+    LoRaMacParamsDefaults.JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1;
+    LoRaMacParamsDefaults.JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2;
+
+    LoRaMacParamsDefaults.ChannelsNbRep = 1;
+    LoRaMacParamsDefaults.Rx1DrOffset = 0;
+
+    LoRaMacParamsDefaults.Rx2Channel = ( Rx2ChannelParams_t )RX_WND_2_CHANNEL;
+
+    // Channel mask
+#if defined( USE_BAND_433 )
+    LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
+#elif defined( USE_BAND_780 )
+    LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
+#elif defined( USE_BAND_868 )
+    LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
 #elif defined( USE_BAND_915 )
-    ChannelsMask[0] = 0xFFFF;
-    ChannelsMask[1] = 0xFFFF;
-    ChannelsMask[2] = 0xFFFF;
-    ChannelsMask[3] = 0xFFFF;
-    ChannelsMask[4] = 0x00FF;
-    ChannelsMask[5] = 0x0000;
-
-    memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) );
+    LoRaMacParamsDefaults.ChannelsMask[0] = 0xFFFF;
+    LoRaMacParamsDefaults.ChannelsMask[1] = 0xFFFF;
+    LoRaMacParamsDefaults.ChannelsMask[2] = 0xFFFF;
+    LoRaMacParamsDefaults.ChannelsMask[3] = 0xFFFF;
+    LoRaMacParamsDefaults.ChannelsMask[4] = 0x00FF;
+    LoRaMacParamsDefaults.ChannelsMask[5] = 0x0000;
 #elif defined( USE_BAND_915_HYBRID )
-    ChannelsMask[0] = 0x00FF;
-    ChannelsMask[1] = 0x0000;
-    ChannelsMask[2] = 0x0000;
-    ChannelsMask[3] = 0x0000;
-    ChannelsMask[4] = 0x0001;
-    ChannelsMask[5] = 0x0000;
-
-    memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) );
+    LoRaMacParamsDefaults.ChannelsMask[0] = 0x00FF;
+    LoRaMacParamsDefaults.ChannelsMask[1] = 0x0000;
+    LoRaMacParamsDefaults.ChannelsMask[2] = 0x0000;
+    LoRaMacParamsDefaults.ChannelsMask[3] = 0x0000;
+    LoRaMacParamsDefaults.ChannelsMask[4] = 0x0001;
+    LoRaMacParamsDefaults.ChannelsMask[5] = 0x0000;
 #else
     #error "Please define a frequency band in the compiler options."
 #endif
@@ -2895,34 +3190,9 @@
     }
 #endif
 
-    ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
-    ChannelsDefaultDatarate = ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
-    ChannelsNbRep = 1;
-    ChannelsNbRepCounter = 0;
-
-    MaxDCycle = 0;
-    AggregatedDCycle = 1;
-    AggregatedLastTxDoneTime = 0;
-    AggregatedTimeOff = 0;
-
-#if defined( USE_BAND_433 )
-    DutyCycleOn = false;
-#elif defined( USE_BAND_780 )
-    DutyCycleOn = false;
-#elif defined( USE_BAND_868 )
-    DutyCycleOn = true;
-#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
-    DutyCycleOn = false;
-#else
-    #error "Please define a frequency band in the compiler options."
-#endif
-
-    MaxRxWindow = MAX_RX_WINDOW;
-    ReceiveDelay1 = RECEIVE_DELAY1;
-    ReceiveDelay2 = RECEIVE_DELAY2;
-    JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1;
-    JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2;
-
+    ResetMacParameters( );
+
+    // Initialize timers
     TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
 
@@ -2942,9 +3212,6 @@
     // Random seed initialization
     srand1( Radio.Random( ) );
 
-    // Initialize channel index.
-    Channel = LORA_MAX_NB_CHANNELS;
-
     PublicNetwork = true;
     SetPublicNetwork( PublicNetwork );
     Radio.Sleep( );
@@ -2954,7 +3221,8 @@
 
 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
 {
-    int8_t datarate = ChannelsDefaultDatarate;
+    int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate;
+    uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex;
 
     if( txInfo == NULL )
     {
@@ -2972,9 +3240,9 @@
         txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate];
     }
 
-    if( txInfo->CurrentPayloadSize >= MacCommandsBufferIndex )
+    if( txInfo->CurrentPayloadSize >= fOptLen )
     {
-        txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - MacCommandsBufferIndex;
+        txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen;
     }
     else
     {
@@ -2986,7 +3254,7 @@
         return LORAMAC_STATUS_LENGTH_ERROR;
     }
 
-    if( ValidatePayloadLength( size, datarate, MacCommandsBufferIndex ) == false )
+    if( ValidatePayloadLength( size, datarate, fOptLen ) == false )
     {
         return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR;
     }
@@ -3057,57 +3325,57 @@
         }
         case MIB_RX2_CHANNEL:
         {
-            mibGet->Param.Rx2Channel = Rx2Channel;
+            mibGet->Param.Rx2Channel = LoRaMacParams.Rx2Channel;
             break;
         }
         case MIB_CHANNELS_MASK:
         {
-            mibGet->Param.ChannelsMask = ChannelsMask;
+            mibGet->Param.ChannelsMask = LoRaMacParams.ChannelsMask;
             break;
         }
         case MIB_CHANNELS_NB_REP:
         {
-            mibGet->Param.ChannelNbRep = ChannelsNbRep;
+            mibGet->Param.ChannelNbRep = LoRaMacParams.ChannelsNbRep;
             break;
         }
         case MIB_MAX_RX_WINDOW_DURATION:
         {
-            mibGet->Param.MaxRxWindow = MaxRxWindow;
+            mibGet->Param.MaxRxWindow = LoRaMacParams.MaxRxWindow;
             break;
         }
         case MIB_RECEIVE_DELAY_1:
         {
-            mibGet->Param.ReceiveDelay1 = ReceiveDelay1;
+            mibGet->Param.ReceiveDelay1 = LoRaMacParams.ReceiveDelay1;
             break;
         }
         case MIB_RECEIVE_DELAY_2:
         {
-            mibGet->Param.ReceiveDelay2 = ReceiveDelay2;
+            mibGet->Param.ReceiveDelay2 = LoRaMacParams.ReceiveDelay2;
             break;
         }
         case MIB_JOIN_ACCEPT_DELAY_1:
         {
-            mibGet->Param.JoinAcceptDelay1 = JoinAcceptDelay1;
+            mibGet->Param.JoinAcceptDelay1 = LoRaMacParams.JoinAcceptDelay1;
             break;
         }
         case MIB_JOIN_ACCEPT_DELAY_2:
         {
-            mibGet->Param.JoinAcceptDelay2 = JoinAcceptDelay2;
+            mibGet->Param.JoinAcceptDelay2 = LoRaMacParams.JoinAcceptDelay2;
             break;
         }
         case MIB_CHANNELS_DEFAULT_DATARATE:
         {
-            mibGet->Param.ChannelsDefaultDatarate = ChannelsDefaultDatarate;
+            mibGet->Param.ChannelsDefaultDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
             break;
         }
         case MIB_CHANNELS_DATARATE:
         {
-            mibGet->Param.ChannelsDatarate = ChannelsDatarate;
+            mibGet->Param.ChannelsDatarate = LoRaMacParams.ChannelsDatarate;
             break;
         }
         case MIB_CHANNELS_TX_POWER:
         {
-            mibGet->Param.ChannelsTxPower = ChannelsTxPower;
+            mibGet->Param.ChannelsTxPower = LoRaMacParams.ChannelsTxPower;
             break;
         }
         case MIB_UPLINK_COUNTER:
@@ -3231,7 +3499,7 @@
         }
         case MIB_RX2_CHANNEL:
         {
-            Rx2Channel = mibSet->Param.Rx2Channel;
+            LoRaMacParams.Rx2Channel = mibSet->Param.Rx2Channel;
             break;
         }
         case MIB_CHANNELS_MASK:
@@ -3253,12 +3521,12 @@
                     }
                     else
                     {
-                        memcpy1( ( uint8_t* ) ChannelsMask,
-                                 ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( ChannelsMask ) );
-                        for ( uint8_t i = 0; i < sizeof( ChannelsMask ) / 2; i++ )
+                        memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask,
+                                 ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
+                        for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask ) / 2; i++ )
                         {
                             // Disable channels which are no longer available
-                            ChannelsMaskRemaining[i] &= ChannelsMask[i];
+                            ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask[i];
                         }
                     }
                 }
@@ -3267,7 +3535,7 @@
                     status = LORAMAC_STATUS_PARAMETER_INVALID;
                 }
 #else
-                memcpy1( ( uint8_t* ) ChannelsMask,
+                memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask,
                          ( uint8_t* ) mibSet->Param.ChannelsMask, 2 );
 #endif
             }
@@ -3282,7 +3550,7 @@
             if( ( mibSet->Param.ChannelNbRep >= 1 ) &&
                 ( mibSet->Param.ChannelNbRep <= 15 ) )
             {
-                ChannelsNbRep = mibSet->Param.ChannelNbRep;
+                LoRaMacParams.ChannelsNbRep = mibSet->Param.ChannelNbRep;
             }
             else
             {
@@ -3292,27 +3560,27 @@
         }
         case MIB_MAX_RX_WINDOW_DURATION:
         {
-            MaxRxWindow = mibSet->Param.MaxRxWindow;
+            LoRaMacParams.MaxRxWindow = mibSet->Param.MaxRxWindow;
             break;
         }
         case MIB_RECEIVE_DELAY_1:
         {
-            ReceiveDelay1 = mibSet->Param.ReceiveDelay1;
+            LoRaMacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1;
             break;
         }
         case MIB_RECEIVE_DELAY_2:
         {
-            ReceiveDelay2 = mibSet->Param.ReceiveDelay2;
+            LoRaMacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2;
             break;
         }
         case MIB_JOIN_ACCEPT_DELAY_1:
         {
-            JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1;
+            LoRaMacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1;
             break;
         }
         case MIB_JOIN_ACCEPT_DELAY_2:
         {
-            JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2;
+            LoRaMacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2;
             break;
         }
         case MIB_CHANNELS_DEFAULT_DATARATE:
@@ -3320,7 +3588,7 @@
             if( ValueInRange( mibSet->Param.ChannelsDefaultDatarate,
                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
             {
-                ChannelsDefaultDatarate = mibSet->Param.ChannelsDefaultDatarate;
+                LoRaMacParamsDefaults.ChannelsDatarate = mibSet->Param.ChannelsDefaultDatarate;
             }
             else
             {
@@ -3333,7 +3601,7 @@
             if( ValueInRange( mibSet->Param.ChannelsDatarate,
                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
             {
-                ChannelsDatarate = mibSet->Param.ChannelsDatarate;
+                LoRaMacParams.ChannelsDatarate = mibSet->Param.ChannelsDatarate;
             }
             else
             {
@@ -3346,7 +3614,7 @@
             if( ValueInRange( mibSet->Param.ChannelsTxPower,
                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
             {
-                ChannelsTxPower = mibSet->Param.ChannelsTxPower;
+                LoRaMacParams.ChannelsTxPower = mibSet->Param.ChannelsTxPower;
             }
             else
             {
@@ -3412,7 +3680,7 @@
             frequencyInvalid = true;
         }
 
-        if( params.DrRange.Fields.Min > ChannelsDefaultDatarate )
+        if( params.DrRange.Fields.Min > LoRaMacParamsDefaults.ChannelsDatarate )
         {
             datarateInvalid = true;
         }
@@ -3474,7 +3742,7 @@
     // Every parameter is valid, activate the channel
     Channels[id] = params;
     Channels[id].Band = band;
-    ChannelsMask[0] |= ( 1 << id );
+    LoRaMacParams.ChannelsMask[0] |= ( 1 << id );
 
     return LORAMAC_STATUS_OK;
 #endif
@@ -3501,7 +3769,7 @@
         Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
 
         // Disable the channel as it doesn't exist anymore
-        if( DisableChannelInMask( id, ChannelsMask ) == false )
+        if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask ) == false )
         {
             return LORAMAC_STATUS_PARAMETER_INVALID;
         }
@@ -3631,28 +3899,10 @@
             macHdr.Value = 0;
             macHdr.Bits.MType  = FRAME_TYPE_JOIN_REQ;
 
-            IsLoRaMacNetworkJoined = false;
-
-#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
-#if defined( USE_BAND_915 )
-            // Re-enable 500 kHz default channels
-            ChannelsMask[4] = 0x00FF;
-#else // defined( USE_BAND_915_HYBRID )
-            // Re-enable 500 kHz default channels
-            ChannelsMask[4] = 0x0001;
-#endif
-
-            static uint8_t drSwitch = 0;
-
-            if( ( ++drSwitch & 0x01 ) == 0x01 )
-            {
-                ChannelsDatarate = DR_0;
-            }
-            else
-            {
-                ChannelsDatarate = DR_4;
-            }
-#endif
+            ResetMacParameters( );
+
+            JoinRequestTrials++;
+            LoRaMacParams.ChannelsDatarate = AlternateDatarate( JoinRequestTrials );
 
             status = Send( &macHdr, 0, NULL, 0 );
             break;
@@ -3751,7 +4001,7 @@
         {
             if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true )
             {
-                ChannelsDatarate = datarate;
+                LoRaMacParams.ChannelsDatarate = datarate;
             }
             else
             {
--- a/LoRaMac.h	Wed May 18 11:19:24 2016 +0000
+++ b/LoRaMac.h	Tue Jul 05 13:24:54 2016 +0000
@@ -47,7 +47,7 @@
 #define __LORAMAC_H__
 
 // Includes board dependent definitions such as channels frequencies
-#include "LoRaMac-board.h"
+#include "LoRaMac-definitions.h"
 
 /*!
  * Beacon interval in us
@@ -149,11 +149,6 @@
  */
 #define LORA_MAC_PUBLIC_SYNCWORD                    0x34
 
- /*!
- * LoRaMac internal state
- */
-//uint32_t LoRaMacState;
-
 /*!
  * LoRaWAN devices classes definition
  */
@@ -162,19 +157,19 @@
     /*!
      * LoRaWAN device class A
      *
-     * LoRaWAN Specification V1.0, chapter 3ff
+     * LoRaWAN Specification V1.0.1, chapter 3ff
      */
     CLASS_A,
     /*!
      * LoRaWAN device class B
      *
-     * LoRaWAN Specification V1.0, chapter 8ff
+     * LoRaWAN Specification V1.0.1, chapter 8ff
      */
     CLASS_B,
     /*!
      * LoRaWAN device class C
      *
-     * LoRaWAN Specification V1.0, chapter 17ff
+     * LoRaWAN Specification V1.0.1, chapter 17ff
      */
     CLASS_C,
 }DeviceClass_t;
@@ -274,6 +269,57 @@
 }Rx2ChannelParams_t;
 
 /*!
+ * Global MAC layer parameters
+ */
+typedef struct sLoRaMacParams
+{
+    /*!
+     * Channels TX power
+     */
+    int8_t ChannelsTxPower;
+    /*!
+     * Channels data rate
+     */
+    int8_t ChannelsDatarate;
+    /*!
+     * LoRaMac maximum time a reception window stays open
+     */
+    uint32_t MaxRxWindow;
+    /*!
+     * Receive delay 1
+     */
+    uint32_t ReceiveDelay1;
+    /*!
+     * Receive delay 2
+     */
+    uint32_t ReceiveDelay2;
+    /*!
+     * Join accept delay 1
+     */
+    uint32_t JoinAcceptDelay1;
+    /*!
+     * Join accept delay 1
+     */
+    uint32_t JoinAcceptDelay2;
+    /*!
+     * Number of uplink messages repetitions [1:15] (unconfirmed messages only)
+     */
+    uint8_t ChannelsNbRep;
+    /*!
+     * Datarate offset between uplink and downlink on first window
+     */
+    uint8_t Rx1DrOffset;
+    /*!
+     * LoRaMAC 2nd reception window settings
+     */
+    Rx2ChannelParams_t Rx2Channel;
+    /*!
+     * Mask indicating which channels are enabled
+     */
+    uint16_t ChannelsMask[6];
+}LoRaMacParams_t;
+
+/*!
  * LoRaMAC multicast channel parameter
  */
 typedef struct sMulticastParams
@@ -303,7 +349,7 @@
 /*!
  * LoRaMAC frame types
  *
- * LoRaWAN Specification V1.0, chapter 4.2.1, table 1
+ * LoRaWAN Specification V1.0.1, chapter 4.2.1, table 1
  */
 typedef enum eLoRaMacFrameType
 {
@@ -344,7 +390,7 @@
 /*!
  * LoRaMAC mote MAC commands
  *
- * LoRaWAN Specification V1.0, chapter 5, table 4
+ * LoRaWAN Specification V1.0.1, chapter 5, table 4
  */
 typedef enum eLoRaMacMoteCmd
 {
@@ -381,7 +427,7 @@
 /*!
  * LoRaMAC server MAC commands
  *
- * LoRaWAN Specification V1.0, chapter 5, table 4
+ * LoRaWAN Specification V1.0.1 chapter 5, table 4
  */
 typedef enum eLoRaMacSrvCmd
 {
@@ -441,7 +487,7 @@
 /*!
  * LoRaMAC header field definition (MHDR field)
  *
- * LoRaWAN Specification V1.0, chapter 4.2
+ * LoRaWAN Specification V1.0.1, chapter 4.2
  */
 typedef union uLoRaMacHeader
 {
@@ -472,7 +518,7 @@
 /*!
  * LoRaMAC frame control field definition (FCtrl)
  *
- * LoRaWAN Specification V1.0, chapter 4.3.1
+ * LoRaWAN Specification V1.0.1, chapter 4.3.1
  */
 typedef union uLoRaMacFrameCtrl
 {
@@ -642,7 +688,7 @@
      * Frame port field. Must be set if the payload is not empty. Use the
      * application specific frame port values: [1...223]
      *
-     * LoRaWAN Specification V1.0, chapter 4.3.2
+     * LoRaWAN Specification V1.0.1, chapter 4.3.2
      */
     uint8_t fPort;
     /*!
@@ -668,7 +714,7 @@
      * Frame port field. Must be set if the payload is not empty. Use the
      * application specific frame port values: [1...223]
      *
-     * LoRaWAN Specification V1.0, chapter 4.3.2
+     * LoRaWAN Specification V1.0.1, chapter 4.3.2
      */
     uint8_t fPort;
     /*!
@@ -686,7 +732,7 @@
     /*!
      * Number of trials to transmit the frame, if the LoRaMAC layer did not
      * receive an acknowledgment. The MAC performs a datarate adaptation,
-     * according to the LoRaWAN Specification V1.0, chapter 18.4, according
+     * according to the LoRaWAN Specification V1.0.1, chapter 19.4, according
      * to the following table:
      *
      * Transmission nb | Data Rate
@@ -883,13 +929,13 @@
     /*!
      * Initiates the Over-the-Air activation
      *
-     * LoRaWAN Specification V1.0, chapter 6.2
+     * LoRaWAN Specification V1.0.1, chapter 6.2
      */
     MLME_JOIN,
     /*!
      * LinkCheckReq - Connectivity validation
      *
-     * LoRaWAN Specification V1.0, chapter 5, table 4
+     * LoRaWAN Specification V1.0.1, chapter 5, table 4
      */
     MLME_LINK_CHECK,
 }Mlme_t;
@@ -902,19 +948,19 @@
     /*!
      * Globally unique end-device identifier
      *
-     * LoRaWAN Specification V1.0, chapter 6.2.1
+     * LoRaWAN Specification V1.0.1, chapter 6.2.1
      */
     uint8_t *DevEui;
     /*!
      * Application identifier
      *
-     * LoRaWAN Specification V1.0, chapter 6.1.2
+     * LoRaWAN Specification V1.0.1, chapter 6.1.2
      */
     uint8_t *AppEui;
     /*!
      * AES-128 application key
      *
-     * LoRaWAN Specification V1.0, chapter 6.2.2
+     * LoRaWAN Specification V1.0.1, chapter 6.2.2
      */
     uint8_t *AppKey;
 }MlmeReqJoin_t;
@@ -1014,19 +1060,19 @@
     /*!
      * LoRaWAN device class
      *
-     * LoRaWAN Specification V1.0
+     * LoRaWAN Specification V1.0.1
      */
     MIB_DEVICE_CLASS,
     /*!
      * LoRaWAN Network joined attribute
      *
-     * LoRaWAN Specification V1.0
+     * LoRaWAN Specification V1.0.1
      */
     MIB_NETWORK_JOINED,
     /*!
      * Adaptive data rate
      *
-     * LoRaWAN Specification V1.0, chapter 4.3.1.1
+     * LoRaWAN Specification V1.0.1, chapter 4.3.1.1
      *
      * [true: ADR enabled, false: ADR disabled]
      */
@@ -1034,31 +1080,31 @@
     /*!
      * Network identifier
      *
-     * LoRaWAN Specification V1.0, chapter 6.2.5
+     * LoRaWAN Specification V1.0.1, chapter 6.1.1
      */
     MIB_NET_ID,
     /*!
      * End-device address
      *
-     * LoRaWAN Specification V1.0, chapter 6.1.2
+     * LoRaWAN Specification V1.0.1, chapter 6.1.1
      */
     MIB_DEV_ADDR,
     /*!
      * Network session key
      *
-     * LoRaWAN Specification V1.0, chapter 6.1.3
+     * LoRaWAN Specification V1.0.1, chapter 6.1.3
      */
     MIB_NWK_SKEY,
     /*!
      * Application session key
      *
-     * LoRaWAN Specification V1.0, chapter 6.1.4
+     * LoRaWAN Specification V1.0.1, chapter 6.1.4
      */
     MIB_APP_SKEY,
     /*!
      * Set the network type to public or private
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      *
      * [true: public network, false: private network]
      */
@@ -1066,7 +1112,7 @@
     /*!
      * Support the operation with repeaters
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      *
      * [true: repeater support enabled, false: repeater support disabled]
      */
@@ -1076,61 +1122,61 @@
      * pointer which references the first entry of the channel list. The
      * list is of size LORA_MAX_NB_CHANNELS
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_CHANNELS,
     /*!
      * Set receive window 2 channel
      *
-     * LoRaWAN Specification V1.0, chapter 3.3.2
+     * LoRaWAN Specification V1.0.1, chapter 3.3.2
      */
     MIB_RX2_CHANNEL,
     /*!
      * LoRaWAN channels mask
      *
-     * LoRaWAN Specification V1.0, chapter 5.2
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_CHANNELS_MASK,
     /*!
      * Set the number of repetitions on a channel
      *
-     * LoRaWAN Specification V1.0, chapter 5.2
+     * LoRaWAN Specification V1.0.1, chapter 5.2
      */
     MIB_CHANNELS_NB_REP,
     /*!
      * Maximum receive window duration in [us]
      *
-     * LoRaWAN Specification V1.0, chapter 3.3.3
+     * LoRaWAN Specification V1.0.1, chapter 3.3.3
      */
     MIB_MAX_RX_WINDOW_DURATION,
     /*!
      * Receive delay 1 in [us]
      *
-     * LoRaWAN Specification V1.0, chapter 6
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_RECEIVE_DELAY_1,
     /*!
      * Receive delay 2 in [us]
      *
-     * LoRaWAN Specification V1.0, chapter 6
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_RECEIVE_DELAY_2,
     /*!
      * Join accept delay 1 in [us]
      *
-     * LoRaWAN Specification V1.0, chapter 6
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_JOIN_ACCEPT_DELAY_1,
     /*!
      * Join accept delay 2 in [us]
      *
-     * LoRaWAN Specification V1.0, chapter 6
+     * LoRaWAN Specification V1.0.1, chapter 7
      */
     MIB_JOIN_ACCEPT_DELAY_2,
     /*!
      * Default Data rate of a channel
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      *
      * EU868 - [DR_0, DR_1, DR_2, DR_3, DR_4, DR_5, DR_6, DR_7]
      *
@@ -1140,7 +1186,7 @@
     /*!
      * Data rate of a channel
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      *
      * EU868 - [DR_0, DR_1, DR_2, DR_3, DR_4, DR_5, DR_6, DR_7]
      *
@@ -1150,7 +1196,7 @@
     /*!
      * Transmission power of a channel
      *
-     * LoRaWAN Specification V1.0, chapter 7
+     * LoRaWAN Specification V1.0.1, chapter 7
      *
      * EU868 - [TX_POWER_20_DBM, TX_POWER_14_DBM, TX_POWER_11_DBM,
      *          TX_POWER_08_DBM, TX_POWER_05_DBM, TX_POWER_02_DBM]
@@ -1164,13 +1210,13 @@
     /*!
      * LoRaWAN Up-link counter
      *
-     * LoRaWAN Specification V1.0, chapter 4.3.1.5
+     * LoRaWAN Specification V1.0.1, chapter 4.3.1.5
      */
     MIB_UPLINK_COUNTER,
     /*!
      * LoRaWAN Down-link counter
      *
-     * LoRaWAN Specification V1.0, chapter 4.3.1.5
+     * LoRaWAN Specification V1.0.1, chapter 4.3.1.5
      */
     MIB_DOWNLINK_COUNTER,
     /*!