Skip to content

Commit b6f383c

Browse files
Daniel Jaecklemluis1
authored andcommitted
Issue #1315 - Refactored and improved the way the duty-cycle is managed.
1 parent 23bb8cf commit b6f383c

File tree

1 file changed

+46
-100
lines changed

1 file changed

+46
-100
lines changed

src/mac/region/RegionCommon.c

Lines changed: 46 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
#include "systime.h"
3636

3737
#define BACKOFF_DC_1_HOUR 100
38-
#define BACKOFF_DC_10_HOURS 1000
39-
#define BACKOFF_DC_24_HOURS 10000
4038

4139
#define BACKOFF_DUTY_CYCLE_1_HOUR_IN_S 3600
4240
#define BACKOFF_DUTY_CYCLE_10_HOURS_IN_S ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S + ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 10 ) )
@@ -45,13 +43,16 @@
4543

4644
#ifndef DUTY_CYCLE_TIME_PERIOD
4745
/*!
48-
* Default duty cycle observation time period
49-
*
50-
* \remark The ETSI observation time period is 1 hour (3600000 ms) but, the implemented algorithm may violate the
51-
* defined duty-cycle restrictions. In order to ensure that these restrictions never get violated we changed the
52-
* default duty cycle observation time period to 1/2 hour (1800000 ms).
46+
* Default duty cycle observation time period is 1 hour (3600000 ms) according to ETSI.
5347
*/
54-
#define DUTY_CYCLE_TIME_PERIOD 1800000
48+
#define DUTY_CYCLE_TIME_PERIOD 3600000
49+
#endif
50+
51+
#ifndef DUTY_CYCLE_TIME_PERIOD_JOIN_BACKOFF_24H
52+
/*!
53+
* Time credits for the join backoff algorithm for the 24H period.
54+
*/
55+
#define DUTY_CYCLE_TIME_PERIOD_JOIN_BACKOFF_24H 870000
5556
#endif
5657

5758
/*!
@@ -78,20 +79,8 @@ static uint16_t GetDutyCycle( Band_t* band, bool joined, SysTime_t elapsedTimeSi
7879

7980
if( joined == false )
8081
{
81-
uint16_t joinDutyCycle = BACKOFF_DC_24_HOURS;
82+
uint16_t joinDutyCycle = BACKOFF_DC_1_HOUR;
8283

83-
if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_1_HOUR_IN_S )
84-
{
85-
joinDutyCycle = BACKOFF_DC_1_HOUR;
86-
}
87-
else if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_10_HOURS_IN_S )
88-
{
89-
joinDutyCycle = BACKOFF_DC_10_HOURS;
90-
}
91-
else
92-
{
93-
joinDutyCycle = BACKOFF_DC_24_HOURS;
94-
}
9584
// Take the most restrictive duty cycle
9685
dutyCycle = MAX( dutyCycle, joinDutyCycle );
9786
}
@@ -110,48 +99,24 @@ static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedT
11099
{
111100
uint16_t dutyCycle = band->DCycle;
112101
TimerTime_t maxCredits = DUTY_CYCLE_TIME_PERIOD;
113-
TimerTime_t elapsedTime = SysTimeToMs( elapsedTimeSinceStartup );
114-
SysTime_t timeDiff = { 0 };
115102

116103
// Get the band duty cycle. If not joined, the function either returns the join duty cycle
117104
// or the band duty cycle, whichever is more restrictive.
118105
dutyCycle = GetDutyCycle( band, joined, elapsedTimeSinceStartup );
119106

120107
if( joined == false )
121108
{
122-
if( dutyCycle == BACKOFF_DC_1_HOUR )
109+
if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_1_HOUR_IN_S )
123110
{
124111
maxCredits = DUTY_CYCLE_TIME_PERIOD;
125-
band->LastMaxCreditAssignTime = elapsedTime;
126112
}
127-
else if( dutyCycle == BACKOFF_DC_10_HOURS )
113+
else if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_10_HOURS_IN_S )
128114
{
129-
maxCredits = DUTY_CYCLE_TIME_PERIOD * 10;
130-
band->LastMaxCreditAssignTime = elapsedTime;
115+
maxCredits = DUTY_CYCLE_TIME_PERIOD;
131116
}
132117
else
133118
{
134-
maxCredits = DUTY_CYCLE_TIME_PERIOD * 24;
135-
}
136-
137-
timeDiff = SysTimeSub( elapsedTimeSinceStartup, SysTimeFromMs( band->LastMaxCreditAssignTime ) );
138-
139-
// Verify if we have to assign the maximum credits in cases
140-
// of the preconditions have changed.
141-
if( ( ( dutyCycleEnabled == false ) && ( lastTxIsJoinRequest == false ) ) ||
142-
( band->MaxTimeCredits != maxCredits ) ||
143-
( timeDiff.Seconds >= BACKOFF_24_HOURS_IN_S ) )
144-
{
145-
band->TimeCredits = maxCredits;
146-
147-
if( elapsedTimeSinceStartup.Seconds >= BACKOFF_DUTY_CYCLE_24_HOURS_IN_S )
148-
{
149-
timeDiff.Seconds = ( elapsedTimeSinceStartup.Seconds - BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) / BACKOFF_24_HOURS_IN_S;
150-
timeDiff.Seconds *= BACKOFF_24_HOURS_IN_S;
151-
timeDiff.Seconds += BACKOFF_DUTY_CYCLE_24_HOURS_IN_S;
152-
timeDiff.SubSeconds = 0;
153-
band->LastMaxCreditAssignTime = SysTimeToMs( timeDiff );
154-
}
119+
maxCredits = DUTY_CYCLE_TIME_PERIOD_JOIN_BACKOFF_24H;
155120
}
156121
}
157122
else
@@ -163,12 +128,6 @@ static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedT
163128
}
164129
}
165130

166-
// Assign the max credits if its the first time
167-
if( band->LastBandUpdateTime == 0 )
168-
{
169-
band->TimeCredits = maxCredits;
170-
}
171-
172131
// Setup the maximum allowed credits. We can assign them
173132
// safely all the time.
174133
band->MaxTimeCredits = maxCredits;
@@ -178,27 +137,37 @@ static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedT
178137

179138
static uint16_t UpdateTimeCredits( Band_t* band, bool joined, bool dutyCycleEnabled,
180139
bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup,
181-
TimerTime_t currentTime )
140+
TimerTime_t currentTime, TimerTime_t lastBandUpdateTime )
182141
{
183142
uint16_t dutyCycle = SetMaxTimeCredits( band, joined, elapsedTimeSinceStartup,
184143
dutyCycleEnabled, lastTxIsJoinRequest );
144+
TimerTime_t observation = DUTY_CYCLE_TIME_PERIOD;
185145

186-
if( joined == true )
146+
if( joined == false )
187147
{
188-
// Apply a sliding window for the duty cycle with collection and speding
189-
// credits.
190-
band->TimeCredits += TimerGetElapsedTime( band->LastBandUpdateTime );
148+
if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_1_HOUR_IN_S )
149+
{
150+
observation = BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 1000;
151+
}
152+
else if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_10_HOURS_IN_S )
153+
{
154+
observation = ( BACKOFF_DUTY_CYCLE_10_HOURS_IN_S * 1000 );
155+
}
156+
else
157+
{
158+
observation = ( BACKOFF_DUTY_CYCLE_24_HOURS_IN_S * 1000 );
159+
}
191160
}
192161

193-
// Limit band credits to maximum
194-
if( band->TimeCredits > band->MaxTimeCredits )
162+
// Apply new credits only if the observation period has been elapsed.
163+
if( ( observation <= lastBandUpdateTime ) ||
164+
( band->LastMaxCreditAssignTime != observation ) ||
165+
( band->LastBandUpdateTime == 0 ) )
195166
{
196167
band->TimeCredits = band->MaxTimeCredits;
168+
band->LastBandUpdateTime = currentTime;
169+
band->LastMaxCreditAssignTime = observation;
197170
}
198-
199-
// Synchronize update time
200-
band->LastBandUpdateTime = currentTime;
201-
202171
return dutyCycle;
203172
}
204173

@@ -324,10 +293,12 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
324293

325294
for( uint8_t i = 0; i < nbBands; i++ )
326295
{
296+
TimerTime_t elapsedTime = TimerGetElapsedTime( bands[i].LastBandUpdateTime );
297+
327298
// Synchronization of bands and credits
328299
dutyCycle = UpdateTimeCredits( &bands[i], joined, dutyCycleEnabled,
329300
lastTxIsJoinRequest, elapsedTimeSinceStartup,
330-
currentTime );
301+
currentTime, elapsedTime );
331302

332303
// Calculate the credit costs for the next transmission
333304
// with the duty cycle and the expected time on air
@@ -336,7 +307,7 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
336307
// Check if the band is ready for transmission. Its ready,
337308
// when the duty cycle is off, or the TimeCredits of the band
338309
// is higher than the credit costs for the transmission.
339-
if( ( bands[i].TimeCredits >= creditCosts ) ||
310+
if( ( bands[i].TimeCredits > creditCosts ) ||
340311
( ( dutyCycleEnabled == false ) && ( joined == true ) ) )
341312
{
342313
bands[i].ReadyForTransmission = true;
@@ -350,49 +321,24 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
350321
// for the next transmission.
351322
bands[i].ReadyForTransmission = false;
352323

353-
if( bands[i].MaxTimeCredits >= creditCosts )
324+
if( bands[i].MaxTimeCredits > creditCosts )
354325
{
355326
// The band can only be taken into account, if the maximum credits
356327
// of the band are higher than the credit costs.
357328
// We calculate the minTimeToWait among the bands which are not
358329
// ready for transmission and which are potentially available
359330
// for a transmission in the future.
360-
minTimeToWait = MIN( minTimeToWait, ( creditCosts - bands[i].TimeCredits ) );
331+
TimerTime_t observationTimeDiff = 0;
332+
if( bands[i].LastMaxCreditAssignTime >= elapsedTime )
333+
{
334+
observationTimeDiff = bands[i].LastMaxCreditAssignTime - elapsedTime;
335+
}
336+
minTimeToWait = MIN( minTimeToWait, observationTimeDiff );
361337
// This band is a potential candidate for an
362338
// upcoming transmission (even if its time credits are not enough
363339
// at the moment), so increase the counter.
364340
validBands++;
365341
}
366-
367-
// Apply a special calculation if the device is not joined.
368-
if( joined == false )
369-
{
370-
SysTime_t backoffTimeRange = {
371-
.Seconds = 0,
372-
.SubSeconds = 0,
373-
};
374-
// Get the backoff time range based on the duty cycle definition
375-
if( dutyCycle == BACKOFF_DC_1_HOUR )
376-
{
377-
backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_1_HOUR_IN_S;
378-
}
379-
else if( dutyCycle == BACKOFF_DC_10_HOURS )
380-
{
381-
backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_10_HOURS_IN_S;
382-
}
383-
else
384-
{
385-
backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_24_HOURS_IN_S;
386-
}
387-
// Calculate the time to wait.
388-
if( elapsedTimeSinceStartup.Seconds > BACKOFF_DUTY_CYCLE_24_HOURS_IN_S )
389-
{
390-
backoffTimeRange.Seconds += BACKOFF_24_HOURS_IN_S * ( ( ( elapsedTimeSinceStartup.Seconds - BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) / BACKOFF_24_HOURS_IN_S ) + 1 );
391-
}
392-
// Calculate the time difference between now and the next range
393-
backoffTimeRange = SysTimeSub( backoffTimeRange, elapsedTimeSinceStartup );
394-
minTimeToWait = SysTimeToMs( backoffTimeRange );
395-
}
396342
}
397343
}
398344

0 commit comments

Comments
 (0)