[mle] simplify graceful detach mechanism and reuse mAttachTimer (#10800)

This commit updates the graceful detach mechanism in `Mle`. A boolean
`mDetachingGracefully` is added to track when the device is
performing a "graceful detach". The `mAttachTimer` is reused for
scheduling the detach delay, as any attach operation can be stopped
during detach, and the timer can be reused. This simplifies the code
and removes the need to use a specific timer for the graceful detach
process.
This commit is contained in:
Abtin Keshavarzian
2024-10-10 08:07:48 -07:00
committed by GitHub
parent 16d7c2a468
commit e7ca8b1aa1
2 changed files with 25 additions and 20 deletions
+17 -11
View File
@@ -50,6 +50,7 @@ Mle::Mle(Instance &aInstance)
, mRequestRouteTlv(false)
, mHasRestored(false)
, mReceivedResponseFromParent(false)
, mDetachingGracefully(false)
, mInitiallyAttachedAsSleepy(false)
#if OPENTHREAD_FTD
, mWasLeader(false)
@@ -89,7 +90,6 @@ Mle::Mle(Instance &aInstance)
#endif
, mAttachTimer(aInstance)
, mMessageTransmissionTimer(aInstance)
, mDetachGracefullyTimer(aInstance)
{
mParent.Init(aInstance);
mParentCandidate.Init(aInstance);
@@ -231,8 +231,11 @@ void Mle::Stop(StopMode aMode)
SetRole(kRoleDisabled);
exit:
mDetachGracefullyTimer.Stop();
mDetachGracefullyCallback.InvokeAndClearIfSet();
if (mDetachingGracefully)
{
mDetachingGracefully = false;
mDetachGracefullyCallback.InvokeAndClearIfSet();
}
}
void Mle::ResetCounters(void)
@@ -1384,6 +1387,12 @@ void Mle::HandleAttachTimer(void)
bool shouldAnnounce = true;
ParentRequestType type;
if (mDetachingGracefully)
{
Stop();
ExitNow();
}
// First, check if we are waiting to receive parent responses and
// found an acceptable parent candidate.
@@ -3492,7 +3501,7 @@ void Mle::HandleChildUpdateResponseOnChild(RxInfo &aRxInfo)
switch (Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout))
{
case kErrorNone:
if (timeout == 0 && IsDetachingGracefully())
if (timeout == 0 && mDetachingGracefully)
{
Stop();
}
@@ -4232,14 +4241,12 @@ uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const
}
#endif
Error Mle::DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext)
Error Mle::DetachGracefully(DetachCallback aCallback, void *aContext)
{
Error error = kErrorNone;
uint32_t timeout = kDetachGracefullyTimeout;
VerifyOrExit(!IsDetachingGracefully(), error = kErrorBusy);
OT_ASSERT(!mDetachGracefullyCallback.IsSet());
VerifyOrExit(!mDetachingGracefully, error = kErrorBusy);
mDetachGracefullyCallback.Set(aCallback, aContext);
@@ -4272,14 +4279,13 @@ Error Mle::DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext
break;
}
mDetachGracefullyTimer.Start(timeout);
mDetachingGracefully = true;
mAttachTimer.Start(timeout);
exit:
return error;
}
void Mle::HandleDetachGracefullyTimer(void) { Stop(); }
//---------------------------------------------------------------------------------------------------------------------
// TlvList
+8 -9
View File
@@ -118,6 +118,8 @@ class Mle : public InstanceLocator, private NonCopyable
friend class ot::UnitTester;
public:
typedef otDetachGracefullyCallback DetachCallback; ///< Callback to signal end of graceful detach.
/**
* Initializes the MLE object.
*
@@ -201,7 +203,7 @@ public:
* @retval kErrorNone Successfully started detaching.
* @retval kErrorBusy Detaching is already in progress.
*/
Error DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext);
Error DetachGracefully(DetachCallback aCallback, void *aContext);
/**
* Indicates whether or not the Thread device is attached to a Thread network.
@@ -1240,8 +1242,6 @@ private:
void HandleNotifierEvents(Events aEvents);
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void ReestablishLinkWithNeighbor(Neighbor &aNeighbor);
void HandleDetachGracefullyTimer(void);
bool IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); }
Error SendChildUpdateRequest(ChildUpdateRequestMode aMode);
Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
Error SendChildUpdateRequest(void);
@@ -1361,10 +1361,9 @@ private:
//------------------------------------------------------------------------------------------------------------------
// Variables
using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>;
using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>;
using MsgTxTimer = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>;
using MleSocket = Ip6::Udp::SocketIn<Mle, &Mle::HandleUdpReceive>;
using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>;
using MsgTxTimer = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>;
using MleSocket = Ip6::Udp::SocketIn<Mle, &Mle::HandleUdpReceive>;
static const otMeshLocalPrefix kMeshLocalPrefixInit;
@@ -1372,6 +1371,7 @@ private:
bool mRequestRouteTlv : 1;
bool mHasRestored : 1;
bool mReceivedResponseFromParent : 1;
bool mDetachingGracefully : 1;
bool mInitiallyAttachedAsSleepy : 1;
#if OPENTHREAD_FTD
bool mWasLeader : 1;
@@ -1423,13 +1423,12 @@ private:
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
ServiceAloc mServiceAlocs[kMaxServiceAlocs];
#endif
Callback<otDetachGracefullyCallback> mDetachGracefullyCallback;
Callback<DetachCallback> mDetachGracefullyCallback;
#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
Callback<otThreadParentResponseCallback> mParentResponseCallback;
#endif
AttachTimer mAttachTimer;
MsgTxTimer mMessageTransmissionTimer;
DetachGracefullyTimer mDetachGracefullyTimer;
Ip6::NetworkPrefix mMeshLocalPrefix;
Ip6::Netif::UnicastAddress mLinkLocalAddress;
Ip6::Netif::UnicastAddress mMeshLocalEid;