Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

Branch:
v4.2.0
Revision:
11:507de2ecd2b3
Parent:
10:be956b45a7ba
Child:
12:d09ccf69cc93
--- a/LoRaMac.cpp	Fri Aug 26 11:37:55 2016 -0400
+++ b/LoRaMac.cpp	Fri Aug 26 16:10:43 2016 -0400
@@ -156,7 +156,7 @@
 /*!
  * LoRaMac ADR control status
  */
-static bool AdrCtrlOn = false;
+static bool AdrCtrlOn = true;
 
 /*!
  * Counts the number of missed ADR acknowledgements
@@ -2370,6 +2370,13 @@
 
 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
 {
+    uint8_t  validLinkAdrCmds = 0;
+    uint8_t  linkAdrStatus    = 0x07;
+    int8_t   txPower          = 0;
+    int8_t   datarate         = 0;
+    uint8_t  nbRep            = 0;
+    uint16_t channelsMask[6]  = {0,0,0,0,0,0}; 
+
     while( macIndex < commandsSize )
     {
         // Decode Frame MAC commands
@@ -2382,22 +2389,11 @@
                 break;
             case SRV_MAC_LINK_ADR_REQ:
                 {
-                    uint8_t i;
-                    uint8_t status = 0x07;
+                    uint8_t  chMaskCntl = 0;
                     uint16_t chMask;
-                    int8_t txPower = 0;
-                    int8_t datarate = 0;
-                    uint8_t nbRep = 0;
-                    uint8_t chMaskCntl = 0;
-                    uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
-
-                    // Initialize local copy of the channels mask array
-                    for( i = 0; i < 6; i++ )
-                    {
-                        channelsMask[i] = ChannelsMask[i];
-                    }
+
                     datarate = payload[macIndex++];
-                    txPower = datarate & 0x0F;
+                    txPower  = datarate & 0x0F;
                     datarate = ( datarate >> 4 ) & 0x0F;
 
                     if( ( AdrCtrlOn == false ) &&
@@ -2411,6 +2407,16 @@
                         macIndex += 3;  // Skip over the remaining bytes of the request
                         break;
                     }
+                    else if ( validLinkAdrCmds++ == 0 )
+                    {
+                        // Initialize local copy of the channels mask array
+                        for(uint8_t i = 0; i < 6; i++ )
+                        {
+                            channelsMask[i] = ChannelsMask[i];
+                        }
+                    }
+
+
                     chMask = ( uint16_t )payload[macIndex++];
                     chMask |= ( uint16_t )payload[macIndex++] << 8;
 
@@ -2424,13 +2430,13 @@
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
                     if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
                     {
-                        status &= 0xFE; // Channel mask KO
+                        linkAdrStatus &= 0xFE; // Channel mask KO
                     }
                     else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) ||
                              ( chMaskCntl >= 7 ) )
                     {
                         // RFU
-                        status &= 0xFE; // Channel mask KO
+                        linkAdrStatus &= 0xFE; // Channel mask KO
                     }
                     else
                     {
@@ -2448,7 +2454,7 @@
                                 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
                                     ( Channels[i].Frequency == 0 ) )
                                 {// Trying to enable an undefined channel
-                                    status &= 0xFE; // Channel mask KO
+                                    linkAdrStatus &= 0xFE; // Channel mask KO
                                 }
                             }
                         }
@@ -2488,39 +2494,14 @@
                     else if( chMaskCntl == 5 )
                     {
                         // RFU
-                        status &= 0xFE; // Channel mask KO
-                    }
-
-                    if(status == 0xFF)
-                    {
-                        for( uint8_t i = 0; i < 16; i++ )
-                        {
-                            if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
-                                ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) )
-                            {// Trying to enable an undefined channel
-                                status &= 0xFE; // Channel mask KO
-                            }
-                        }
-                        channelsMask[chMaskCntl] = chMask;
-
-                        if( CountNbEnabled125kHzChannels( channelsMask ) < 6 )
-                        {
-                            status &= 0xFE; // Channel mask KO
-                        }
-
-#if defined( USE_BAND_915_HYBRID )
-                        if( ValidateChannelMask( channelsMask ) == false )
-                        {
-                            status &= 0xFE; // Channel mask KO
-                        }
-#endif
+                        linkAdrStatus &= 0xFE; // Channel mask KO
                     }
 #else
     #error "Please define a frequency band in the compiler options."
 #endif
                     if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
                     {
-                        status &= 0xFD; // Datarate KO
+                        linkAdrStatus &= 0xFD; // Datarate KO
                     }
 
                     //
@@ -2528,23 +2509,8 @@
                     //
                     if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
                     {
-                        status &= 0xFB; // TxPower KO
+                        linkAdrStatus &= 0xFB; // TxPower KO
                     }
-                    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;
-                    }
-                    AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
                 }
                 break;
             case SRV_MAC_DUTY_CYCLE_REQ:
@@ -2694,6 +2660,53 @@
                 return;
         }
     }
+
+    // Process accumulated Link ADR channel mask changes
+    if( validLinkAdrCmds > 0 ) 
+    {
+#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+        for(uint8_t i=0; i< 6; i++)
+        {
+            for( uint8_t j = 0; j < 16; j++ )
+            {
+                if( ( ( channelsMask[i] & ( 1 << j ) ) != 0 ) && ( Channels[i * 16 + j].Frequency == 0 ) )
+                {// Trying to enable an undefined channel
+                    linkAdrStatus &= 0xFE; // Channel mask KO
+                    break;
+                }
+            }
+        }
+
+        if( CountNbEnabled125kHzChannels( channelsMask ) < 6 )
+        {
+            linkAdrStatus &= 0xFE; // Channel mask KO
+        }
+
+#if defined( USE_BAND_915_HYBRID )
+        if( ValidateChannelMask( channelsMask ) == false )
+        {
+            linkAdrStatus &= 0xFE; // Channel mask KO
+        }
+#endif
+
+#endif
+        if( ( linkAdrStatus & 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;
+        }
+
+        AddMacCommand( MOTE_MAC_LINK_ADR_ANS, linkAdrStatus, 0 );
+    }
 }
 
 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )