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
Revision:
1:91e4e6c60d1e
Parent:
0:91d1a7783bb9
Child:
2:14a5d6ad92d5
--- a/LoRaMac.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ b/LoRaMac.cpp	Mon Nov 23 10:09:43 2015 +0000
@@ -12,10 +12,7 @@
 
 Maintainer: Miguel Luis and Gregory Cristian
 */
-#include "mbed.h"
 #include "board.h"
-#include "utilities.h"
-#include "sx1276-hal.h"
 
 #include "LoRaMacCrypto.h"
 #include "LoRaMac.h"
@@ -23,7 +20,12 @@
 /*!
  * Maximum PHY layer payload size
  */
-#define LORAMAC_PHY_MAXPAYLOAD                      250
+#define LORAMAC_PHY_MAXPAYLOAD                      255
+
+/*!
+ * Maximum MAC commands buffer size
+ */
+#define LORA_MAC_COMMAND_MAX_LENGTH                 15
 
 /*!
  * Device IEEE EUI
@@ -173,7 +175,7 @@
 /*!
  * Buffer containing the MAC layer commands
  */
-static uint8_t MacCommandsBuffer[15];
+static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
 
 #if defined( USE_BAND_433 )
 /*!
@@ -449,7 +451,7 @@
 /*!
  * LoRaMac upper layer event functions
  */
-static LoRaMacEvent_t *LoRaMacEvents;
+static LoRaMacCallbacks_t *LoRaMacCallbacks;
 
 /*!
  * LoRaMac notification event flags
@@ -581,8 +583,7 @@
 /*!
  * Radio events function pointer
  */
-//static RadioEvents_t RadioEvents;
-SX1276MB1xAS Radio( OnRadioTxDone, OnRadioTxTimeout, OnRadioRxDone, OnRadioRxTimeout, OnRadioRxError, NULL, NULL );
+static RadioEvents_t RadioEvents;
 
 /*!
  * \brief Validates if the payload fits into the frame, taking the datarate
@@ -633,7 +634,7 @@
     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
     TimerTime_t curTime = TimerGetCurrentTime( );
 
-    memset( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
+    memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
 
     // Update Aggregated duty cycle
     if( AggregatedTimeOff < ( curTime - AggregatedLastTxDoneTime ) )
@@ -741,70 +742,99 @@
  * \param [in] p1  1st parameter ( optional depends on the command )
  * \param [in] p2  2nd parameter ( optional depends on the command )
  *
- * \retval status  Function status [0: OK, 1: Unknown command, 2: Buffer full]
+ * \retval status  Function status [0: OK, 1: Unknown command, 2: Busy]
  */
 static uint8_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
 {
-    MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+    uint8_t status = 2; // Busy
+
     switch( cmd )
     {
         case MOTE_MAC_LINK_CHECK_REQ:
-            // No payload for this command
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this command
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_LINK_ADR_ANS:
-            // Margin
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Margin
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_DUTY_CYCLE_ANS:
-            // No payload for this answer
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this answer
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_RX_PARAM_SETUP_ANS:
-            // Status: Datarate ACK, Channel ACK
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Status: Datarate ACK, Channel ACK
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_DEV_STATUS_ANS:
-            // 1st byte Battery
-            // 2nd byte Margin
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 2 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // 1st byte Battery
+                // 2nd byte Margin
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_NEW_CHANNEL_ANS:
-            // Status: Datarate range OK, Channel frequency OK
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Status: Datarate range OK, Channel frequency OK
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_RX_TIMING_SETUP_ANS:
-            // No payload for this answer
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this answer
+                status = 0; // OK
+            }
             break;
         default:
-            return 1;
+            return 1; // Unknown command
     }
-    if( MacCommandsBufferIndex <= 15 )
+    if( status == 0 )
     {
         MacCommandsInNextTx = true;
-        return 0;
     }
-    else
-    {
-        return 2;
-    }
+    return status;
 }
 
 // TODO: Add Documentation
 static void LoRaMacNotify( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
 {
-    if( ( LoRaMacEvents != NULL ) && ( LoRaMacEvents->MacEvent != NULL ) )
+    if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->MacEvent != NULL ) )
     {
-        LoRaMacEvents->MacEvent( flags, info );
+        LoRaMacCallbacks->MacEvent( flags, info );
     }
     flags->Value = 0;
 }
 
-typedef uint8_t ( *GetBatteryLevel )( );
-GetBatteryLevel LoRaMacGetBatteryLevel;
-
-void LoRaMacInit( LoRaMacEvent_t *events, uint8_t ( *getBatteryLevel )( ) )
+void LoRaMacInit( LoRaMacCallbacks_t *callbacks )
 {
-    LoRaMacEvents = events;
+    LoRaMacCallbacks = callbacks;
 
     LoRaMacEventFlags.Value = 0;
     
@@ -821,8 +851,6 @@
     LoRaMacEventInfo.NbGateways = 0;
     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
    
-    LoRaMacGetBatteryLevel = getBatteryLevel;
-    
     LoRaMacDeviceClass = CLASS_A;
     
     UpLinkCounter = 1;
@@ -908,9 +936,17 @@
     TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
     TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
     TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
+    
+    // Initialize Radio driver
+    RadioEvents.TxDone = OnRadioTxDone;
+    RadioEvents.RxDone = OnRadioRxDone;
+    RadioEvents.RxError = OnRadioRxError;
+    RadioEvents.TxTimeout = OnRadioTxTimeout;
+    RadioEvents.RxTimeout = OnRadioRxTimeout;
+    Radio.Init( &RadioEvents );
 
     // Random seed initialization
-    srand( Radio.Random( ) );
+    srand1( Radio.Random( ) );
 
     // Initialize channel index.
     Channel = LORA_MAX_NB_CHANNELS;
@@ -1035,7 +1071,7 @@
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
     static uint8_t drSwitch = 0;
     
-    if( drSwitch == 0 )
+    if( ( ++drSwitch & 0x01 ) == 0x01 )
     {
         ChannelsDatarate = DR_0;
     }
@@ -1043,7 +1079,6 @@
     {
         ChannelsDatarate = DR_4;
     }
-    drSwitch = ( drSwitch + 1 ) % 2;
 #endif
     return LoRaMacSend( &macHdr, NULL, 0, NULL, 0 );
 }
@@ -1268,9 +1303,9 @@
                         LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
                     }
                 }
-                MacCommandsInNextTx = false;
-                MacCommandsBufferIndex = 0;
             }
+            MacCommandsInNextTx = false;
+            MacCommandsBufferIndex = 0;
             
             if( ( pktHeaderLen + fBufferSize ) > LORAMAC_PHY_MAXPAYLOAD )
             {
@@ -1448,10 +1483,11 @@
                         // Data rate ACK = 0
                         // Channel mask  = 0
                         AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
+                        macIndex += 3;  // Skip over the remaining bytes of the request
                         break;
                     }
-                    chMask = payload[macIndex++];
-                    chMask |= payload[macIndex++] << 8;
+                    chMask = ( uint16_t )payload[macIndex++];
+                    chMask |= ( uint16_t )payload[macIndex++] << 8;
 
                     nbRep = payload[macIndex++];
                     chMaskCntl = ( nbRep >> 4 ) & 0x07;
@@ -1590,10 +1626,9 @@
                     int8_t drOffset = 0;
                     uint32_t freq = 0;
                 
-                    drOffset = payload[macIndex++];
-                    datarate = drOffset & 0x0F;
-                    drOffset = ( drOffset >> 4 ) & 0x0F;
-                    
+                    drOffset = ( payload[macIndex] >> 4 ) & 0x07;
+                    datarate = payload[macIndex] & 0x0F;
+                    macIndex++;
                     freq = ( uint32_t )payload[macIndex++];
                     freq |= ( uint32_t )payload[macIndex++] << 8;
                     freq |= ( uint32_t )payload[macIndex++] << 16;
@@ -1610,7 +1645,8 @@
                         status &= 0xFD; // Datarate KO
                     }
 
-                    if( ( ( drOffset < 0 ) || ( drOffset > 5 ) ) == true )
+                    if( ( ( drOffset < LORAMAC_MIN_RX1_DR_OFFSET ) ||
+                          ( drOffset > LORAMAC_MAX_RX1_DR_OFFSET ) ) == true )
                     {
                         status &= 0xFB; // Rx1DrOffset range KO
                     }
@@ -1625,7 +1661,14 @@
                 }
                 break;
             case SRV_MAC_DEV_STATUS_REQ:
-                AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, LoRaMacGetBatteryLevel( ), LoRaMacEventInfo.RxSnr );
+                {
+                    uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
+                    if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
+                    {
+                        batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
+                    }
+                    AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, LoRaMacEventInfo.RxSnr );
+                }
                 break;
             case SRV_MAC_NEW_CHANNEL_REQ:
                 {
@@ -1723,6 +1766,12 @@
             TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
             TimerStart( &RxWindowTimer2 );
         }
+        if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) )
+        {
+            TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + ACK_TIMEOUT +
+                                             randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
+            TimerStart( &AckTimeoutTimer );
+        }
     }
     else
     {
@@ -1732,6 +1781,7 @@
     
     if( NodeAckRequested == false )
     {
+        LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
         ChannelsNbRepCounter++;
     }
 }
@@ -1746,18 +1796,20 @@
 
     uint8_t pktHeaderLen = 0;
     uint32_t address = 0;
-    uint16_t sequenceCounter = 0;
-    int32_t sequence = 0;
     uint8_t appPayloadStartIndex = 0;
     uint8_t port = 0xFF;
     uint8_t frameLen = 0;
     uint32_t mic = 0;
     uint32_t micRx = 0;
     
+    uint16_t sequenceCounter = 0;
+    uint16_t sequenceCounterPrev = 0;
+    uint16_t sequenceCounterDiff = 0;
+    uint32_t downLinkCounter = 0;
+
     MulticastParams_t *curMulticastParams = NULL;
     uint8_t *nwkSKey = LoRaMacNwkSKey;
     uint8_t *appSKey = LoRaMacAppSKey;
-    uint32_t downLinkCounter = 0;
     
     bool isMicOk = false;
 
@@ -1814,7 +1866,16 @@
                 // DLSettings
                 Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
                 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 )
+                {
+                    Rx2Channel.Datarate = DR_8;
+                }
+#endif
                 // RxDelay
                 ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
                 if( ReceiveDelay1 == 0 )
@@ -1847,8 +1908,6 @@
             {
                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
             }
-
-            LoRaMacEventFlags.Bits.Tx = 1;
             break;
         case FRAME_TYPE_DATA_CONFIRMED_DOWN:
         case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
@@ -1898,8 +1957,8 @@
                 }
                 fCtrl.Value = payload[pktHeaderLen++];
                 
-                sequenceCounter |= ( uint32_t )payload[pktHeaderLen++];
-                sequenceCounter |= ( uint32_t )payload[pktHeaderLen++] << 8;
+                sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
+                sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
 
                 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
 
@@ -1908,45 +1967,39 @@
                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16 );
                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24 );
 
-                sequence = ( int32_t )sequenceCounter - ( int32_t )( downLinkCounter & 0xFFFF );
-                if( sequence < 0 )
+                sequenceCounterPrev = ( uint16_t )downLinkCounter;
+                sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
+
+                if( sequenceCounterDiff < ( 1 << 15 ) )
                 {
-                    // sequence reset or roll over happened
-                    downLinkCounter = ( downLinkCounter & 0xFFFF0000 ) | ( sequenceCounter + ( uint32_t )0x10000 );
+                    downLinkCounter += sequenceCounterDiff;
                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
                     if( micRx == mic )
                     {
                         isMicOk = true;
                     }
-                    else
-                    {
-                        isMicOk = false;
-                        // sequence reset
-                        if( LoRaMacEventFlags.Bits.Multicast == 1 )
-                        {
-                            curMulticastParams->DownLinkCounter = downLinkCounter = sequenceCounter;
-                        }
-                        else
-                        {
-                            DownLinkCounter = downLinkCounter = sequenceCounter;
-                        }
-                        LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
-                    }
                 }
                 else
                 {
-                    downLinkCounter = ( downLinkCounter & 0xFFFF0000 ) | sequenceCounter;
-                    LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
+                    // check for downlink counter roll-over
+                    uint32_t  downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
+                    LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
+                    if( micRx == mic )
+                    {
+                        isMicOk = true;
+                        downLinkCounter = downLinkCounterTmp;
+                    }
                 }
 
-                if( ( isMicOk == true ) ||
-                    ( micRx == mic ) )
+                if( isMicOk == true )
                 {
                     LoRaMacEventFlags.Bits.Rx = 1;
                     LoRaMacEventInfo.RxSnr = snr;
                     LoRaMacEventInfo.RxRssi = rssi;
                     LoRaMacEventInfo.RxBufferSize = 0;
                     AdrAckCounter = 0;
+
+                    // Update 32 bits downlink counter
                     if( LoRaMacEventFlags.Bits.Multicast == 1 )
                     {
                         curMulticastParams->DownLinkCounter = downLinkCounter;
@@ -2025,27 +2078,29 @@
                         }
                     }
 
-                    LoRaMacEventFlags.Bits.Tx = 1;
                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
                 }
                 else
                 {
                     LoRaMacEventInfo.TxAckReceived = false;
                     
-                    LoRaMacEventFlags.Bits.Tx = 1;
                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
                     LoRaMacState &= ~MAC_TX_RUNNING;
+                    if( NodeAckRequested == true )
+                    {
+                        OnAckTimeoutTimerEvent( );
+                    }
                 }
             }
             break;
         case FRAME_TYPE_PROPRIETARY:
             //Intentional falltrough
         default:
-            LoRaMacEventFlags.Bits.Tx = 1;
             LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
             LoRaMacState &= ~MAC_TX_RUNNING;
             break;
     }
+    LoRaMacEventFlags.Bits.Tx = 1;
 }
 
 /*!
@@ -2075,6 +2130,10 @@
     {
         Radio.Sleep( );
     }
+    else
+    {
+        OnRxWindow2TimerEvent( );
+    }
     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
     {
         LoRaMacEventFlags.Bits.Tx = 1;
@@ -2091,6 +2150,10 @@
     {
         Radio.Sleep( );
     }
+    else
+    {
+        OnRxWindow2TimerEvent( );
+    }
     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
     {
         LoRaMacEventFlags.Bits.Tx = 1;
@@ -2108,17 +2171,36 @@
  */
 void LoRaMacRxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
 {
-    if( Radio.GetStatus( ) == IDLE )
+    uint8_t downlinkDatarate = Datarates[datarate];
+    RadioModems_t modem;
+
+    if( Radio.GetStatus( ) == RF_IDLE )
     {
         Radio.SetChannel( freq );
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
         if( datarate == DR_7 )
         {
-            Radio.SetRxConfig( MODEM_FSK, 50e3, Datarates[datarate] * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
+            modem = MODEM_FSK;
+            Radio.SetRxConfig( MODEM_FSK, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
         }
         else
         {
-            Radio.SetRxConfig( MODEM_LORA, bandwidth, Datarates[datarate], 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
+            modem = MODEM_LORA;
+            Radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
         }
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+        modem = MODEM_LORA;
+        Radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
+#endif
+        if( RepeaterSupport == true )
+        {
+            Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] );
+        }
+        else
+        {
+            Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] );
+        }
+
         if( rxContinuous == false )
         {
             Radio.Rx( MaxRxWindow );
@@ -2142,6 +2224,10 @@
     TimerStop( &RxWindowTimer1 );
     LoRaMacEventFlags.Bits.RxSlot = 0;
 
+    if( LoRaMacDeviceClass == CLASS_C )
+    {
+        Radio.Standby( );
+    }
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
     datarate = ChannelsDatarate - Rx1DrOffset;
     if( datarate < 0 )
@@ -2174,7 +2260,6 @@
     {// LoRa 500 kHz
         bandwidth  = 2;
     }
-    //LoRaMacRxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false );
     LoRaMacRxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false );
 #else
     #error "Please define a frequency band in the compiler options."
@@ -2338,7 +2423,6 @@
                 {
                     UpLinkCounter++;
                 }
-                LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
             }
         }
     }
@@ -2350,6 +2434,7 @@
     if( LoRaMacState == MAC_IDLE )
     {
         LoRaMacNotify( &LoRaMacEventFlags, &LoRaMacEventInfo );
+        LoRaMacEventFlags.Bits.Tx = 0;
     }
     else
     {