From f91610f3f3b49d5a4342e57145e73e36bf980d9c Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 28 Aug 2024 08:06:01 -0700 Subject: [PATCH] [mle] include Supervision TLV only from sleepy child (#10628) This commit updates the code to include the Supervision Interval TLV in MLE messages sent from a child only when the child mode indicates it is sleepy (`!IsRxOnWhenIdle()`). The Network Diagnostic Child TLV is also updated to use zero for the "Supervision Interval" field when the child is not sleepy. The `test-023-mesh-diag.py` is updated to validate this new behavior. The parent node still tracks the received supervision interval from a child in the `Child` entry. This parameter indicates the interval that would be used if the child were to be supervised. --- src/core/thread/mle.cpp | 17 ++++++++++++++--- src/core/thread/mle.hpp | 1 + src/core/thread/network_diagnostic_tlvs.cpp | 2 +- tests/toranj/cli/test-023-mesh-diag.py | 4 ++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 6b64959f1..e2a48f240 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1776,7 +1776,7 @@ Error Mle::SendChildIdRequest(void) SuccessOrExit(error = message->AppendModeTlv(mDeviceMode)); SuccessOrExit(error = message->AppendTimeoutTlv(mTimeout)); SuccessOrExit(error = message->AppendVersionTlv()); - SuccessOrExit(error = message->AppendSupervisionIntervalTlv(Get().GetInterval())); + SuccessOrExit(error = message->AppendSupervisionIntervalTlvIfSleepyChild()); if (!IsFullThreadDevice()) { @@ -2056,7 +2056,7 @@ Error Mle::SendChildUpdateRequest(ChildUpdateRequestMode aMode) SuccessOrExit(error = message->AppendSourceAddressTlv()); SuccessOrExit(error = message->AppendLeaderDataTlv()); SuccessOrExit(error = message->AppendTimeoutTlv((aMode == kAppendZeroTimeout) ? 0 : mTimeout)); - SuccessOrExit(error = message->AppendSupervisionIntervalTlv(Get().GetInterval())); + SuccessOrExit(error = message->AppendSupervisionIntervalTlvIfSleepyChild()); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE if (Get().IsCslEnabled()) { @@ -2152,7 +2152,7 @@ Error Mle::SendChildUpdateResponse(const TlvList &aTlvList, break; case Tlv::kSupervisionInterval: - SuccessOrExit(error = message->AppendSupervisionIntervalTlv(Get().GetInterval())); + SuccessOrExit(error = message->AppendSupervisionIntervalTlvIfSleepyChild()); break; #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -4690,6 +4690,17 @@ exit: return error; } +Error Mle::TxMessage::AppendSupervisionIntervalTlvIfSleepyChild(void) +{ + Error error = kErrorNone; + + VerifyOrExit(!Get().IsRxOnWhenIdle()); + error = AppendSupervisionIntervalTlv(Get().GetInterval()); + +exit: + return error; +} + Error Mle::TxMessage::AppendSupervisionIntervalTlv(uint16_t aInterval) { return Tlv::Append(*this, aInterval); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 24afe67a9..2c49f5900 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1036,6 +1036,7 @@ private: Error AppendLinkMarginTlv(uint8_t aLinkMargin); Error AppendVersionTlv(void); Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses); + Error AppendSupervisionIntervalTlvIfSleepyChild(void); Error AppendSupervisionIntervalTlv(uint16_t aInterval); Error AppendXtalAccuracyTlv(void); Error AppendActiveTimestampTlv(void); diff --git a/src/core/thread/network_diagnostic_tlvs.cpp b/src/core/thread/network_diagnostic_tlvs.cpp index 715730f2d..9d4fc6651 100644 --- a/src/core/thread/network_diagnostic_tlvs.cpp +++ b/src/core/thread/network_diagnostic_tlvs.cpp @@ -58,7 +58,7 @@ void ChildTlv::InitFrom(const Child &aChild) mTimeout = BigEndian::HostSwap32(aChild.GetTimeout()); mAge = BigEndian::HostSwap32(Time::MsecToSec(TimerMilli::GetNow() - aChild.GetLastHeard())); mConnectionTime = BigEndian::HostSwap32(aChild.GetConnectionTime()); - mSupervisionInterval = BigEndian::HostSwap16(aChild.GetSupervisionInterval()); + mSupervisionInterval = aChild.IsRxOnWhenIdle() ? 0 : BigEndian::HostSwap16(aChild.GetSupervisionInterval()); mLinkMargin = aChild.GetLinkInfo().GetLinkMargin(); mAverageRssi = aChild.GetLinkInfo().GetAverageRss(); mLastRssi = aChild.GetLinkInfo().GetLastRss(); diff --git a/tests/toranj/cli/test-023-mesh-diag.py b/tests/toranj/cli/test-023-mesh-diag.py index a62475c25..418813e43 100755 --- a/tests/toranj/cli/test-023-mesh-diag.py +++ b/tests/toranj/cli/test-023-mesh-diag.py @@ -136,9 +136,13 @@ r1.cli('meshdiag topology children') childtable = r2.cli('meshdiag childtable', r1_rloc) verify(len([line for line in childtable if line.startswith('rloc16')]) == 2) +verify(len([line for line in childtable if ' supvn:0 ' in line]) == 1) +verify(len([line for line in childtable if ' supvn:' in line and 'supvn:0' not in line]) == 1) childtable = r1.cli('meshdiag childtable', r3_rloc) verify(len([line for line in childtable if line.startswith('rloc16')]) == 3) +verify(len([line for line in childtable if ' supvn:0 ' in line]) == 1) +verify(len([line for line in childtable if ' supvn:' in line and 'supvn:0' not in line]) == 2) childtable = r1.cli('meshdiag childtable', r2_rloc) verify(len([line for line in childtable if line.startswith('rloc16')]) == 0)