Skip to content

Commit bc54d67

Browse files
authored
[mle] clamp child timeout to min/max range (openthread#11278)
This commit updates `SetTimeout()` to ensure the child timeout remains within the minimum and maximum allowed values (per the specification, the maximum value of 8 hours is used). These limits are also enforced when the parent requests a different timeout value in an MLE Child Update Response to the child's request.
1 parent e1adb71 commit bc54d67

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

src/core/common/time.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,17 @@ namespace ot {
5959
class Time : public Unequatable<Time>
6060
{
6161
public:
62-
static constexpr uint32_t kOneSecondInMsec = 1000u; ///< One second interval in msec.
63-
static constexpr uint32_t kOneMinuteInMsec = kOneSecondInMsec * 60; ///< One minute interval in msec.
64-
static constexpr uint32_t kOneHourInMsec = kOneMinuteInMsec * 60; ///< One hour interval in msec.
65-
static constexpr uint32_t kOneDayInMsec = kOneHourInMsec * 24; ///< One day interval in msec.
66-
static constexpr uint32_t kOneMsecInUsec = 1000u; ///< One millisecond in microseconds.
67-
static constexpr uint32_t kOneSecondInUsec = 1000000u; ///< One second interval in microseconds.
62+
static constexpr uint32_t kOneMinuteInSec = 60; ///< One minute interval in sec.
63+
static constexpr uint32_t kOneHourInSec = 60 * kOneMinuteInSec; ///< One hour interval in sec.
64+
static constexpr uint32_t kOneDayInSec = 24 * kOneHourInSec; ///< One day interval in sec.
65+
66+
static constexpr uint32_t kOneSecondInMsec = 1000u; ///< One second interval in msec.
67+
static constexpr uint32_t kOneMinuteInMsec = kOneMinuteInSec * kOneSecondInMsec; ///< One minute interval in msec.
68+
static constexpr uint32_t kOneHourInMsec = kOneHourInSec * kOneSecondInMsec; ///< One hour interval in msec.
69+
static constexpr uint32_t kOneDayInMsec = kOneDayInSec * kOneSecondInMsec; ///< One day interval in msec.
70+
71+
static constexpr uint32_t kOneMsecInUsec = 1000u; ///< One millisecond in microseconds.
72+
static constexpr uint32_t kOneSecondInUsec = 1000000u; ///< One second interval in microseconds.
6873

6974
/**
7075
* This constant defines a maximum time duration ensured to be longer than any other duration.

src/core/thread/mle.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -791,24 +791,31 @@ void Mle::InformPreviousChannel(void)
791791
return;
792792
}
793793

794-
void Mle::SetTimeout(uint32_t aTimeout)
794+
void Mle::SetTimeout(uint32_t aTimeout, TimeoutAction aAction)
795795
{
796-
// Determine `kMinTimeout` based on other parameters
796+
// Determine `kMinTimeout` based on other parameters. `kMaxTimeout`
797+
// is set (per spec) to minimum Delay Timer value for a Pending
798+
// Operational Dataset when updating the Network Key which is 8
799+
// hours.
800+
797801
static constexpr uint32_t kMinPollPeriod = OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD;
798802
static constexpr uint32_t kRetxPollPeriod = OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD;
799803
static constexpr uint32_t kMinTimeoutDataPoll = kMinPollPeriod + kFailedChildTransmissions * kRetxPollPeriod;
800804
static constexpr uint32_t kMinTimeoutKeepAlive = (kMaxChildKeepAliveAttempts + 1) * kUnicastRetxDelay;
801805
static constexpr uint32_t kMinTimeout = Time::MsecToSec(OT_MAX(kMinTimeoutKeepAlive, kMinTimeoutDataPoll));
806+
static constexpr uint32_t kMaxTimeout = (8 * Time::kOneHourInSec);
807+
808+
static_assert(kMinTimeout <= kMaxTimeout, "Min timeout MUST be less than Max timeout");
802809

803-
aTimeout = Max(aTimeout, kMinTimeout);
810+
aTimeout = Clamp(aTimeout, kMinTimeout, kMaxTimeout);
804811

805812
VerifyOrExit(mTimeout != aTimeout);
806813

807814
mTimeout = aTimeout;
808815

809816
Get<DataPollSender>().RecalculatePollPeriod();
810817

811-
if (IsChild())
818+
if (IsChild() && (aAction == kSendChildUpdateToParent))
812819
{
813820
IgnoreError(SendChildUpdateRequestToParent());
814821
}
@@ -3578,7 +3585,7 @@ void Mle::HandleChildUpdateResponseOnChild(RxInfo &aRxInfo)
35783585
}
35793586
else
35803587
{
3581-
mTimeout = timeout;
3588+
SetTimeout(timeout, kDoNotSendChildUpdateToParent);
35823589
}
35833590
break;
35843591
case kErrorNotFound:

src/core/thread/mle.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ class Mle : public InstanceLocator, private NonCopyable
472472
*
473473
* @param[in] aTimeout The Timeout value in seconds.
474474
*/
475-
void SetTimeout(uint32_t aTimeout);
475+
void SetTimeout(uint32_t aTimeout) { SetTimeout(aTimeout, kSendChildUpdateToParent); }
476476

477477
/**
478478
* Returns the RLOC16 assigned to the Thread interface.
@@ -904,6 +904,12 @@ class Mle : public InstanceLocator, private NonCopyable
904904
kNoSecurity = 255, // Security suite value indicating that MLE message is secured.
905905
};
906906

907+
enum TimeoutAction : uint8_t // Used as input in `SetTimeout()` to determine whether or not to update the parent.
908+
{
909+
kSendChildUpdateToParent,
910+
kDoNotSendChildUpdateToParent,
911+
};
912+
907913
enum MessageAction : uint8_t
908914
{
909915
kMessageSend,
@@ -1330,6 +1336,7 @@ class Mle : public InstanceLocator, private NonCopyable
13301336
void SetStateChild(uint16_t aRloc16);
13311337
void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId);
13321338
void SetLeaderData(const LeaderData &aLeaderData);
1339+
void SetTimeout(uint32_t aTimeout, TimeoutAction aAction);
13331340
void InformPreviousChannel(void);
13341341
bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; }
13351342
void ScheduleMessageTransmissionTimer(void);

0 commit comments

Comments
 (0)