Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

Branch:
v4.2.0
Revision:
9:ad93de20d720
Parent:
8:4816c8449bf2
Child:
10:be956b45a7ba
diff -r 4816c8449bf2 -r ad93de20d720 LoRaMac.cpp
--- a/LoRaMac.cpp	Mon Aug 22 20:30:06 2016 -0400
+++ b/LoRaMac.cpp	Fri Aug 26 11:32:12 2016 -0400
@@ -593,32 +593,9 @@
  */
 LoRaMacFlags_t LoRaMacFlags;
 
-/* LoRaWAN 1.1 Section 9 Retransmission back-off 
- *
- * Applies to  uplink frames that:
- * - Require acknowledgement or answer, and are 
- *   retransmitted by the device if the answer is not received
- * and
- * - Can be triggered by an external event causing synchronization
- *
- * Transmission duty-cylce for such messages shall respect the local regulations
- * and the following limits 
- * - Aggregated during the first hour                36 seconds
- * - Aggregated during the next 10 hours             36 seconds
- *  - After the first 11 hours aggregated over 24h    8.7seconds
+/*!
+ * Join Retransmission back-off configuration
  */
-#ifndef JOIN_RETRANSMISSION_DCYCLE1   
-#define JOIN_RETRANSMISSION_DCYCLE1   { 3600, 1000000 } // (period, onAirTimeMax)
-#endif
-
-#ifndef JOIN_RETRANSMISSION_DCYCLE2   
-#define JOIN_RETRANSMISSION_DCYCLE2   { 10*3600, 36000000 } // (period, onAirTimeMax)
-#endif
-
-#ifndef JOIN_RETRANSMISSION_DCYCLE3   
-#define JOIN_RETRANSMISSION_DCYCLE3   { 24*3600, 8700000 } // (period, onAirTimeMax)
-#endif
-
 LoRaMacRetransmissionDCycle_t JoinReTransmitDCycle[JOIN_NB_RETRANSMISSION_DCYCLES] = 
 {
     JOIN_RETRANSMISSION_DCYCLE1, 
@@ -1068,16 +1045,6 @@
                 // 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 )
@@ -3074,31 +3041,6 @@
     IsLoRaMacNetworkJoined = false;
     LoRaMacState = MAC_IDLE;
 
-    MulticastChannels = NULL;
-    IsUpLinkCounterFixed = false;
-    IsRxWindowsEnabled = true;
-    IsLoRaMacNetworkJoined = false;
-    AdrCtrlOn = false;
-    AdrAckCounter = 0;
-    NodeAckRequested = false;
-    SrvAckRequested = false;
-    MacCommandsInNextTx = false;
-    MacCommandsBufferIndex = 0;
-    AckTimeoutRetries = 1;
-    AckTimeoutRetriesCounter = 1;
-    AckTimeoutRetry = false;
-    TxTimeOnAir = 0;
-    RxSlot = 0;
-    //Rx2Channel = RX_WND_2_CHANNEL;
-    Rx1DrOffset = 0;
-    ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
-    ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
-    ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE;
-    ChannelsNbRep = 1;
-    ChannelsNbRepCounter = 0;
-    MaxDCycle = 0;
-    
-
 #if defined( USE_BAND_433 )
     ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
 #elif defined( USE_BAND_780 )
@@ -3613,7 +3555,19 @@
             if( ValueInRange( mibSet->Param.ChannelsTxPower,
                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
             {
+#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+                int8_t txPower = LimitTxPower( mibSet->Param.ChannelsTxPower );
+                if( txPower == mibSet->Param.ChannelsTxPower )
+                {
+                    ChannelsTxPower = mibSet->Param.ChannelsTxPower;
+                }
+                else
+                {
+                    status = LORAMAC_STATUS_PARAMETER_INVALID;
+                }
+#else
                 ChannelsTxPower = mibSet->Param.ChannelsTxPower;
+#endif
             }
             else
             {
@@ -4062,57 +4016,66 @@
     TimerTime_t prevDCycleEndTime; 
     TimerTime_t period;
     TimerTime_t onAirTimeMax;
-    uint8_t     dcycleNum;
-
-    // Check retransmit duty-cycle exists
+    TimerTime_t lastJoinTime;
+    TimerTime_t elapsedTime;
+    uint8_t     dcyclePeriod;
+
+    // Check retransmit duty-cycle is enabled 
     if ( JOIN_NB_RETRANSMISSION_DCYCLES == 0 )
         return 0;
 
-    uptime = TimerGetCurrentTime( ) / 1e6;
-
-    // Get uptime dutycycle 
+    // Normalize system time values to seconds
+    uptime = TimerGetCurrentTime( ) / 1e3;
+    lastJoinTime = LastJoinTxTime / 1e3;
+
+    // Get dutycycle for current time
     prevDCycleEndTime = 0;
     currDCycleEndTime = 0;
-    for(dcycleNum = 0; dcycleNum < JOIN_NB_RETRANSMISSION_DCYCLES; dcycleNum++)
+    for(dcyclePeriod = 0; dcyclePeriod < JOIN_NB_RETRANSMISSION_DCYCLES; dcyclePeriod++)
     {                
         prevDCycleEndTime  = currDCycleEndTime;
-        currDCycleEndTime += JoinReTransmitDCycle[dcycleNum].period;  
+        currDCycleEndTime += JoinReTransmitDCycle[dcyclePeriod].period;  
 
         bool isCurrentPeriod = uptime < currDCycleEndTime;
 
-        if( isCurrentPeriod || ( dcycleNum == ( JOIN_NB_RETRANSMISSION_DCYCLES-1 ) ) )
+        if( isCurrentPeriod || ( dcyclePeriod == ( JOIN_NB_RETRANSMISSION_DCYCLES-1 ) ) )
         {
-            period = JoinReTransmitDCycle[dcycleNum].period;
-            onAirTimeMax = JoinReTransmitDCycle[dcycleNum].onAirTimeMax;
+            period = JoinReTransmitDCycle[dcyclePeriod].period;
+            onAirTimeMax = JoinReTransmitDCycle[dcyclePeriod].onAirTimeMax;
             if( isCurrentPeriod == true ) 
                 break;
         }
     }
 
-    // Clear aggregate on air time if last join occured during a previous period 
-    if( LastJoinTxTime < prevDCycleEndTime ) 
+    // Clear aggregate on air time if dutycycle period of last join has elapsed 
+    if( lastJoinTime < prevDCycleEndTime ) 
     {
         JoinAggTimeOnAir = 0;
     }
-    // For last dutycyle, the current & previous period end time must be calculated 
-    else if( dcycleNum ==  JOIN_NB_RETRANSMISSION_DCYCLES )  
+    else 
     {
-        if( ( TimerGetElapsedTime( LastJoinTxTime )/1e6 ) >= period )
+        elapsedTime = ( uptime - prevDCycleEndTime ) % period;
+        
+        if( dcyclePeriod == JOIN_NB_RETRANSMISSION_DCYCLES )
         {
-            JoinAggTimeOnAir = 0;
+            if( ( ( uptime - prevDCycleEndTime ) / period ) > ( ( lastJoinTime - prevDCycleEndTime ) / period ) )
+            {
+                JoinAggTimeOnAir = 0;
+            }
         }
     }
 
     if ( JoinAggTimeOnAir >= onAirTimeMax ) 
     {
-        // current period elapsed time 
-        TimerTime_t elapsedTime =  ( uptime - prevDCycleEndTime ) % period; 
-
         // time off is remaining time until beginning of next period 
-        timeOff = ( period - elapsedTime ) * 1e6; 
+        timeOff = ( period - elapsedTime ); 
+
+        DEBUG_LOG("%s: timeOff=%u, onAir=%u/%u, period=%u, uptime=%u",
+                __func__, timeOff, JoinAggTimeOnAir, onAirTimeMax, period, uptime);
     }
 
-    return timeOff;
+
+    return ( timeOff * 1e6);
 }
 
 void LoRaMacTestRxWindowsOn( bool enable )