diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 41a53067e..b580d7b08 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -52,21 +52,12 @@ Mle::Mle(Instance &aInstance) , mRetrieveNewNetworkData(false) , mRequestRouteTlv(false) , mHasRestored(false) - , mReceivedResponseFromParent(false) , mInitiallyAttachedAsSleepy(false) , mRole(kRoleDisabled) , mLastSavedRole(kRoleDisabled) , mDeviceMode(DeviceMode::kModeRxOnWhenIdle) - , mAttachState(kAttachStateIdle) - , mReattachState(kReattachStop) - , mAttachMode(kAnyPartition) - , mAddressRegistrationMode(kAppendAllAddresses) - , mParentRequestCounter(0) - , mAnnounceChannel(0) , mRloc16(kInvalidRloc16) , mPreviousParentRloc(kInvalidRloc16) - , mAttachCounter(0) - , mAnnounceDelay(kAnnounceTimeout) , mStoreFrameCounterAhead(kDefaultStoreFrameCounterAhead) , mTimeout(kDefaultChildTimeout) #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -76,13 +67,13 @@ Mle::Mle(Instance &aInstance) , mDelayedSender(aInstance) , mSocket(aInstance, *this) , mPrevRoleRestorer(aInstance) + , mAttacher(aInstance) , mDetacher(aInstance) , mRetxTracker(aInstance) , mAnnounceHandler(aInstance) #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE , mParentSearch(aInstance) #endif - , mAttachTimer(aInstance) #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE , mWakeupTxScheduler(aInstance) , mWedAttachState(kWedDetached) @@ -118,11 +109,9 @@ Mle::Mle(Instance &aInstance) #endif // OPENTHREAD_FTD { mParent.Init(aInstance); - mParentCandidate.Init(aInstance); mLeaderData.Clear(); mParent.Clear(); - mParentCandidate.Clear(); ResetCounters(); mLinkLocalAddress.InitAsThreadOrigin(); @@ -221,27 +210,9 @@ Error Mle::Start(StartMode aMode) SetRloc16(GetRloc16()); - mAttachCounter = 0; - Get().Start(); - switch (aMode) - { - case kNormalAttach: - mReattachState = - (Get().Restore() == kErrorNone) ? kReattachActive : kReattachStop; - - if (mPrevRoleRestorer.Start() == kErrorNone) - { - ExitNow(); - } - break; - - case kAnnounceAttach: - break; - } - - Attach(kAnyPartition); + mAttacher.Start(aMode); exit: return error; @@ -383,11 +354,11 @@ exit: return; } -void Mle::SetAttachState(AttachState aState) +void Mle::Attacher::SetState(State aState) { - VerifyOrExit(aState != mAttachState); - LogInfo("AttachState %s -> %s", AttachStateToString(mAttachState), AttachStateToString(aState)); - mAttachState = aState; + VerifyOrExit(aState != mState); + LogInfo("AttachState %s -> %s", StateToString(mState), StateToString(aState)); + mState = aState; exit: return; @@ -558,7 +529,7 @@ Error Mle::BecomeDetached(void) VerifyOrExit(!IsDisabled(), error = kErrorInvalidState); - if (IsDetached() && (mAttachState == kAttachStateStart)) + if (IsDetached() && mAttacher.WillStartAttachSoon()) { // Already detached and waiting to start an attach attempt, so // there is not need to make any changes. @@ -566,7 +537,7 @@ Error Mle::BecomeDetached(void) } // Not in reattach stage after reset - if (mReattachState == kReattachStop) + if (mAttacher.IsReattachWithDatasetDone()) { IgnoreError(Get().Restore()); } @@ -578,7 +549,7 @@ Error Mle::BecomeDetached(void) SetStateDetached(); mParent.SetState(Neighbor::kStateInvalid); SetRloc16(kInvalidRloc16); - Attach(kAnyPartition); + mAttacher.Attach(kAnyPartition); exit: return error; @@ -591,7 +562,7 @@ Error Mle::BecomeChild(void) VerifyOrExit(!IsDisabled(), error = kErrorInvalidState); VerifyOrExit(!IsAttaching(), error = kErrorBusy); - Attach(kAnyPartition); + mAttacher.Attach(kAnyPartition); exit: return error; @@ -602,42 +573,44 @@ Error Mle::SearchForBetterParent(void) Error error = kErrorNone; VerifyOrExit(IsChild(), error = kErrorInvalidState); - Attach(kBetterParent); + mAttacher.Attach(kBetterParent); exit: return error; } -void Mle::Attach(AttachMode aMode) +void Mle::Attacher::Attach(AttachMode aMode) { - VerifyOrExit(!IsDisabled() && !IsAttaching()); + VerifyOrExit(!Get().IsDisabled()); - if (!IsDetached()) + VerifyOrExit(!IsAttaching()); + + if (!Get().IsDetached()) { mAttachCounter = 0; } mParentCandidate.Clear(); - SetAttachState(kAttachStateStart); - mAttachMode = aMode; + SetState(kStateStart); + mMode = aMode; if (aMode != kBetterPartition) { #if OPENTHREAD_FTD - if (IsFullThreadDevice()) + if (Get().IsFullThreadDevice()) { - StopAdvertiseTrickleTimer(); + Get().StopAdvertiseTrickleTimer(); } #endif } else { - mCounters.mBetterPartitionAttachAttempts++; + Get().mCounters.mBetterPartitionAttachAttempts++; } - mAttachTimer.Start(GetAttachStartDelay()); + mTimer.Start(GetStartDelay()); - if (IsDetached()) + if (Get().IsDetached()) { mAttachCounter++; @@ -646,9 +619,9 @@ void Mle::Attach(AttachMode aMode) mAttachCounter--; } - mCounters.mAttachAttempts++; + Get().mCounters.mAttachAttempts++; - if (!IsRxOnWhenIdle()) + if (!Get().IsRxOnWhenIdle()) { Get().SetRxOnWhenIdle(false); } @@ -658,16 +631,16 @@ exit: return; } -uint32_t Mle::GetAttachStartDelay(void) const +uint32_t Mle::Attacher::GetStartDelay(void) const { uint32_t delay = 1; uint32_t jitter; - VerifyOrExit(IsDetached()); + VerifyOrExit(Get().IsDetached()); if (mAttachCounter == 0) { - delay = GenerateRandomDelay(kParentRequestRouterTimeout); + delay = Get().GenerateRandomDelay(kParentRequestRouterTimeout); ExitNow(); } #if OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE @@ -723,8 +696,7 @@ void Mle::SetStateDetached(void) #endif SetRole(kRoleDetached); - SetAttachState(kAttachStateIdle); - mAttachTimer.Stop(); + mAttacher.CancelAttachOnRoleChange(); mDelayedSender.RemoveScheduledChildUpdateRequestToParent(); mRetxTracker.Stop(); mInitiallyAttachedAsSleepy = false; @@ -747,9 +719,7 @@ void Mle::SetStateChild(uint16_t aRloc16) SetRloc16(aRloc16); SetRole(kRoleChild); - SetAttachState(kAttachStateIdle); - mAttachTimer.Start(kAttachBackoffDelayToResetCounter); - mReattachState = kReattachStop; + mAttacher.CancelAttachOnRoleChange(); Get().SetBeaconEnabled(false); mRetxTracker.UpdateOnRoleChangeToChild(); mPrevRoleRestorer.Stop(); @@ -757,7 +727,7 @@ void Mle::SetStateChild(uint16_t aRloc16) #if OPENTHREAD_FTD if (IsFullThreadDevice()) { - HandleChildStart(mAttachMode); + HandleChildStart(); } #endif @@ -878,7 +848,7 @@ Error Mle::SetDeviceMode(DeviceMode aDeviceMode) if (shouldReattach) { - mAttachCounter = 0; + mAttacher.ResetAttachCounter(); IgnoreError(BecomeDetached()); ExitNow(); } @@ -886,9 +856,9 @@ Error Mle::SetDeviceMode(DeviceMode aDeviceMode) if (IsDetached()) { - mAttachCounter = 0; + mAttacher.ResetAttachCounter(); SetStateDetached(); - Attach(kAnyPartition); + mAttacher.Attach(kAnyPartition); } else if (IsChild()) { @@ -1124,20 +1094,6 @@ void Mle::HandleNotifierEvents(Events aEvents) { VerifyOrExit(!IsDisabled()); - if (aEvents.Contains(kEventThreadRoleChanged)) - { - if (mAddressRegistrationMode == kAppendMeshLocalOnly) - { - // If only mesh-local address was registered in the "Child - // ID Request" message, after device is attached, trigger a - // "Child Update Request" to register the remaining - // addresses. - - mAddressRegistrationMode = kAppendAllAddresses; - ScheduleChildUpdateRequestIfMtdChild(); - } - } - if (aEvents.ContainsAny(kEventIp6AddressAdded | kEventIp6AddressRemoved)) { if (!Get().HasUnicastAddress(mMeshLocalEid.GetAddress())) @@ -1221,10 +1177,10 @@ exit: return; } -Error Mle::DetermineParentRequestType(ParentRequestType &aType) const +Error Mle::Attacher::DetermineParentRequestType(ParentRequestType &aType) const { // This method determines the Parent Request type to use during an - // attach cycle based on `mAttachMode`, `mAttachCounter` and + // attach cycle based on `mMode`, `mAttachCounter` and // `mParentRequestCounter`. This method MUST be used while in // `kAttachStateParentRequest` state. // @@ -1236,9 +1192,9 @@ Error Mle::DetermineParentRequestType(ParentRequestType &aType) const Error error = kErrorNone; - OT_ASSERT(mAttachState == kAttachStateParentRequest); + OT_ASSERT(mState == kStateParentRequest); - if (mAttachMode == kSelectedParent) + if (mMode == kSelectedParent) { aType = kToSelectedRouter; VerifyOrExit(mParentRequestCounter <= 1, error = kErrorNotFound); @@ -1254,14 +1210,14 @@ Error Mle::DetermineParentRequestType(ParentRequestType &aType) const // router trying to attach to a better partition, or a child trying // to find a better parent. - if ((mAttachCounter <= 1) && (mAttachMode != kBetterParent)) + if ((mAttachCounter <= 1) && (mMode != kBetterParent)) { VerifyOrExit(mParentRequestCounter <= kFirstAttachCycleTotalParentRequests, error = kErrorNotFound); // During reattach to the same partition all the Parent // Request are sent to Routers and REEDs. - if ((mAttachMode != kSamePartition) && (mParentRequestCounter <= kFirstAttachCycleNumParentRequestToRouters)) + if ((mMode != kSamePartition) && (mParentRequestCounter <= kFirstAttachCycleNumParentRequestToRouters)) { aType = kToRouters; } @@ -1280,20 +1236,20 @@ exit: return error; } -bool Mle::HasAcceptableParentCandidate(void) const +bool Mle::Attacher::HasAcceptableParentCandidate(void) const { bool hasAcceptableParent = false; ParentRequestType parentReqType; VerifyOrExit(mParentCandidate.IsStateParentResponse()); - switch (mAttachState) + switch (mState) { - case kAttachStateAnnounce: + case kStateAnnounce: VerifyOrExit(!HasMoreChannelsToAnnounce()); break; - case kAttachStateParentRequest: + case kStateParentRequest: SuccessOrAssert(DetermineParentRequestType(parentReqType)); if (parentReqType == kToRouters) @@ -1311,9 +1267,9 @@ bool Mle::HasAcceptableParentCandidate(void) const ExitNow(); } - if (IsChild()) + if (Get().IsChild()) { - switch (mAttachMode) + switch (mMode) { case kBetterPartition: break; @@ -1338,7 +1294,7 @@ exit: return hasAcceptableParent; } -void Mle::HandleAttachTimer(void) +void Mle::Attacher::HandleTimer(void) { uint32_t delay = 0; bool shouldAnnounce = true; @@ -1349,22 +1305,22 @@ void Mle::HandleAttachTimer(void) if (HasAcceptableParentCandidate() && (SendChildIdRequest() == kErrorNone)) { - SetAttachState(kAttachStateChildIdRequest); + SetState(kStateChildIdRequest); delay = kChildIdResponseTimeout; ExitNow(); } - switch (mAttachState) + switch (mState) { - case kAttachStateIdle: + case kStateIdle: mAttachCounter = 0; break; - case kAttachStateStart: - LogNote("Attach attempt %d, %s %s", mAttachCounter, AttachModeToString(mAttachMode), - ReattachStateToString(mReattachState)); + case kStateStart: + LogNote("Attach attempt %d, %s %s", mAttachCounter, AttachModeToString(mMode), + ReattachModeToString(mReattachMode)); - SetAttachState(kAttachStateParentRequest); + SetState(kStateParentRequest); mParentCandidate.SetState(Neighbor::kStateInvalid); mReceivedResponseFromParent = false; mParentRequestCounter = 0; @@ -1372,7 +1328,7 @@ void Mle::HandleAttachTimer(void) OT_FALL_THROUGH; - case kAttachStateParentRequest: + case kStateParentRequest: mParentRequestCounter++; if (DetermineParentRequestType(type) == kErrorNone) { @@ -1397,14 +1353,14 @@ void Mle::HandleAttachTimer(void) if (shouldAnnounce) { // We send an extra "Parent Request" as we switch to - // `kAttachStateAnnounce` and start sending Announce on + // `kStateAnnounce` and start sending Announce on // all channels. This gives an additional chance to find // a parent during this phase. Note that we can stay in - // `kAttachStateAnnounce` for multiple iterations, each + // `kStateAnnounce` for multiple iterations, each // time sending an Announce on a different channel // (with `mAnnounceDelay` wait between them). - SetAttachState(kAttachStateAnnounce); + SetState(kStateAnnounce); SendParentRequest(kToRoutersAndReeds); mAnnounceChannel = Mac::ChannelMask::kChannelIteratorFirst; delay = mAnnounceDelay; @@ -1413,18 +1369,18 @@ void Mle::HandleAttachTimer(void) OT_FALL_THROUGH; - case kAttachStateAnnounce: + case kStateAnnounce: if (shouldAnnounce && (GetNextAnnounceChannel(mAnnounceChannel) == kErrorNone)) { - SendAnnounce(mAnnounceChannel, kOrphanAnnounce); + Get().SendAnnounce(mAnnounceChannel, kOrphanAnnounce); delay = mAnnounceDelay; break; } OT_FALL_THROUGH; - case kAttachStateChildIdRequest: - SetAttachState(kAttachStateIdle); + case kStateChildIdRequest: + SetState(kStateIdle); mParentCandidate.Clear(); delay = Reattach(); break; @@ -1434,17 +1390,17 @@ exit: if (delay != 0) { - mAttachTimer.Start(delay); + mTimer.Start(delay); } } -bool Mle::PrepareAnnounceState(void) +bool Mle::Attacher::PrepareAnnounceState(void) { bool shouldAnnounce = false; Mac::ChannelMask channelMask; - VerifyOrExit(!IsChild() && (mReattachState == kReattachStop) && - (Get().IsPartiallyComplete() || !IsFullThreadDevice())); + VerifyOrExit(!Get().IsChild() && (mReattachMode == kReattachModeStop) && + (Get().IsPartiallyComplete() || !Get().IsFullThreadDevice())); if (Get().GetChannelMask(channelMask) != kErrorNone) { @@ -1459,51 +1415,51 @@ exit: return shouldAnnounce; } -uint32_t Mle::Reattach(void) +uint32_t Mle::Attacher::Reattach(void) { uint32_t delay = 0; - // First, check `mReattachState`. If an attach attempt failed + // First, check `mReattachMode`. If an attach attempt failed // while using the Active Dataset, start a new attach cycle with // the Pending Dataset (if available). If attaching with the // Pending Dataset fails, switch back to the Active Dataset. - switch (mReattachState) + switch (mReattachMode) { - case kReattachActive: + case kReattachModeActive: if (Get().Restore() == kErrorNone) { IgnoreError(Get().ApplyConfiguration()); - mReattachState = kReattachPending; - SetAttachState(kAttachStateStart); - delay = GenerateRandomDelay(kAttachStartJitter); + mReattachMode = kReattachModePending; + SetState(kStateStart); + delay = Get().GenerateRandomDelay(kAttachStartJitter); ExitNow(); } - mReattachState = kReattachStop; + mReattachMode = kReattachModeStop; break; - case kReattachPending: + case kReattachModePending: IgnoreError(Get().Restore()); - mReattachState = kReattachStop; + mReattachMode = kReattachModeStop; break; - case kReattachStop: + case kReattachModeStop: break; } - switch (mAttachMode) + switch (mMode) { case kAnyPartition: case kBetterParent: case kSelectedParent: - if (IsChild()) + if (Get().IsChild()) { // If already attached (e.g., trying to find a better // parent or partition), and attach fails, we revert to // sleepy operation if needed and stop the attach process. - if (!IsRxOnWhenIdle()) + if (!Get().IsRxOnWhenIdle()) { Get().SetAttachMode(false); Get().SetRxOnWhenIdle(false); @@ -1512,21 +1468,21 @@ uint32_t Mle::Reattach(void) ExitNow(); } - if (mAnnounceHandler.IsAnnounceAttaching()) + if (Get().mAnnounceHandler.IsAnnounceAttaching()) { - mAnnounceHandler.HandleAnnounceAttachFailure(); - IgnoreError(BecomeDetached()); + Get().mAnnounceHandler.HandleAnnounceAttachFailure(); + IgnoreError(Get().BecomeDetached()); ExitNow(); } #if OPENTHREAD_FTD - if (IsFullThreadDevice() && BecomeLeader(kIgnoreLeaderWeight) == kErrorNone) + if (Get().IsFullThreadDevice() && Get().BecomeLeader(kIgnoreLeaderWeight) == kErrorNone) { ExitNow(); } #endif - IgnoreError(BecomeDetached()); + IgnoreError(Get().BecomeDetached()); break; case kSamePartition: @@ -1542,7 +1498,7 @@ exit: return delay; } -void Mle::SendParentRequest(ParentRequestType aType) +void Mle::Attacher::SendParentRequest(ParentRequestType aType) { Error error = kErrorNone; TxMessage *message; @@ -1563,8 +1519,8 @@ void Mle::SendParentRequest(ParentRequestType aType) break; } - VerifyOrExit((message = NewMleMessage(kCommandParentRequest)) != nullptr, error = kErrorNoBufs); - SuccessOrExit(error = message->AppendModeTlv(mDeviceMode)); + VerifyOrExit((message = Get().NewMleMessage(kCommandParentRequest)) != nullptr, error = kErrorNoBufs); + SuccessOrExit(error = message->AppendModeTlv(Get().mDeviceMode)); SuccessOrExit(error = message->AppendChallengeTlv(mParentRequestChallenge)); SuccessOrExit(error = message->AppendScanMaskTlv(scanMask)); SuccessOrExit(error = message->AppendVersionTlv()); @@ -1579,7 +1535,7 @@ void Mle::SendParentRequest(ParentRequestType aType) VerifyOrExit(messageToCurParent != nullptr, error = kErrorNoBufs); - destination.SetToLinkLocalAddress(mParent.GetExtAddress()); + destination.SetToLinkLocalAddress(Get().mParent.GetExtAddress()); error = messageToCurParent->SendTo(destination); if (error != kErrorNone) @@ -1590,7 +1546,7 @@ void Mle::SendParentRequest(ParentRequestType aType) Log(kMessageSend, kTypeParentRequestToRouters, destination); - destination.SetToLinkLocalAddress(mParentSearch.GetSelectedParent().GetExtAddress()); + destination.SetToLinkLocalAddress(Get().mParentSearch.GetSelectedParent().GetExtAddress()); } else #endif @@ -1616,22 +1572,22 @@ exit: FreeMessageOnError(message, error); } -void Mle::HandleChildIdRequestTxDone(const otMessage *aMessage, otError aError, void *aContext) +void Mle::Attacher::HandleChildIdRequestTxDone(const otMessage *aMessage, otError aError, void *aContext) { OT_UNUSED_VARIABLE(aError); - static_cast(aContext)->HandleChildIdRequestTxDone(AsCoreType(aMessage)); + static_cast(aContext)->HandleChildIdRequestTxDone(AsCoreType(aMessage)); } -void Mle::HandleChildIdRequestTxDone(const Message &aMessage) +void Mle::Attacher::HandleChildIdRequestTxDone(const Message &aMessage) { - if (aMessage.GetTxSuccess() && !IsRxOnWhenIdle()) + if (aMessage.GetTxSuccess() && !Get().IsRxOnWhenIdle()) { Get().SetAttachMode(true); Get().SetRxOnWhenIdle(false); } - if (aMessage.IsLinkSecurityEnabled() && (mAttachState == kAttachStateChildIdRequest)) + if (aMessage.IsLinkSecurityEnabled() && (mState == kStateChildIdRequest)) { // If the Child ID Request requires fragmentation and therefore // link layer security, the frame transmission will be aborted. @@ -1646,7 +1602,7 @@ void Mle::HandleChildIdRequestTxDone(const Message &aMessage) } } -Error Mle::SendChildIdRequest(void) +Error Mle::Attacher::SendChildIdRequest(void) { static const uint8_t kTlvs[] = {Tlv::kAddress16, Tlv::kNetworkData, Tlv::kRoute}; @@ -1655,9 +1611,9 @@ Error Mle::SendChildIdRequest(void) TxMessage *message = nullptr; Ip6::Address destination; - if (mParent.GetExtAddress() == mParentCandidate.GetExtAddress()) + if (Get().mParent.GetExtAddress() == mParentCandidate.GetExtAddress()) { - if (IsChild()) + if (Get().IsChild()) { LogInfo("Already attached to candidate parent"); ExitNow(error = kErrorAlready); @@ -1673,19 +1629,19 @@ Error Mle::SendChildIdRequest(void) // `FindNeighbor()` returns `mParentCandidate` when // processing the Child ID Response. - mParent.SetState(Neighbor::kStateInvalid); + Get().mParent.SetState(Neighbor::kStateInvalid); } } - VerifyOrExit((message = NewMleMessage(kCommandChildIdRequest)) != nullptr, error = kErrorNoBufs); + VerifyOrExit((message = Get().NewMleMessage(kCommandChildIdRequest)) != nullptr, error = kErrorNoBufs); SuccessOrExit(error = message->AppendResponseTlv(mParentCandidate.mRxChallenge)); SuccessOrExit(error = message->AppendLinkAndMleFrameCounterTlvs()); - SuccessOrExit(error = message->AppendModeTlv(mDeviceMode)); - SuccessOrExit(error = message->AppendTimeoutTlv(mTimeout)); + SuccessOrExit(error = message->AppendModeTlv(Get().mDeviceMode)); + SuccessOrExit(error = message->AppendTimeoutTlv(Get().mTimeout)); SuccessOrExit(error = message->AppendVersionTlv()); SuccessOrExit(error = message->AppendSupervisionIntervalTlvIfSleepyChild()); - if (!IsFullThreadDevice()) + if (!Get().IsFullThreadDevice()) { SuccessOrExit(error = message->AppendAddressRegistrationTlv(mAddressRegistrationMode)); @@ -2011,7 +1967,7 @@ exit: FreeMessageOnError(message, error); } -Error Mle::GetNextAnnounceChannel(uint8_t &aChannel) const +Error Mle::Attacher::GetNextAnnounceChannel(uint8_t &aChannel) const { // This method gets the next channel to send announce on after // `aChannel`. Returns `kErrorNotFound` if no more channel in the @@ -2027,7 +1983,7 @@ Error Mle::GetNextAnnounceChannel(uint8_t &aChannel) const return channelMask.GetNextChannel(aChannel); } -bool Mle::HasMoreChannelsToAnnounce(void) const +bool Mle::Attacher::HasMoreChannelsToAnnounce(void) const { uint8_t channel = mAnnounceChannel; @@ -2351,11 +2307,11 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn break; case kCommandParentResponse: - HandleParentResponse(rxInfo); + mAttacher.HandleParentResponse(rxInfo); break; case kCommandChildIdResponse: - HandleChildIdResponse(rxInfo); + mAttacher.HandleChildIdResponse(rxInfo); break; case kCommandAnnounce: @@ -2813,11 +2769,11 @@ exit: return error; } -bool Mle::IsBetterParent(uint16_t aRloc16, - uint8_t aTwoWayLinkMargin, - const ConnectivityTlv &aConnectivityTlv, - uint16_t aVersion, - const Mac::CslAccuracy &aCslAccuracy) +bool Mle::Attacher::IsBetterParent(uint16_t aRloc16, + uint8_t aTwoWayLinkMargin, + const ConnectivityTlv &aConnectivityTlv, + uint16_t aVersion, + const Mac::CslAccuracy &aCslAccuracy) { int rval; @@ -2855,10 +2811,10 @@ bool Mle::IsBetterParent(uint16_t aRloc16, #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE // CSL metric - if (!IsRxOnWhenIdle()) + if (!Get().IsRxOnWhenIdle()) { - uint64_t cslMetric = CalcParentCslMetric(aCslAccuracy); - uint64_t candidateCslMetric = CalcParentCslMetric(mParentCandidate.GetCslAccuracy()); + uint64_t cslMetric = Get().CalcParentCslMetric(aCslAccuracy); + uint64_t candidateCslMetric = Get().CalcParentCslMetric(mParentCandidate.GetCslAccuracy()); // Smaller metric is better. rval = ThreeWayCompare(candidateCslMetric, cslMetric); @@ -2874,7 +2830,7 @@ exit: return (rval > 0); } -void Mle::HandleParentResponse(RxInfo &aRxInfo) +void Mle::Attacher::HandleParentResponse(RxInfo &aRxInfo) { Error error = kErrorNone; int8_t rss = aRxInfo.mMessage.GetAverageRss(); @@ -2902,7 +2858,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) extAddress.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid()); - if (IsChild() && mParent.GetExtAddress() == extAddress) + if (Get().IsChild() && Get().mParent.GetExtAddress() == extAddress) { mReceivedResponseFromParent = true; } @@ -2942,7 +2898,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) parentinfo.mLinkQuality3 = connectivityTlv.GetLinkQuality3(); parentinfo.mLinkQuality2 = connectivityTlv.GetLinkQuality2(); parentinfo.mLinkQuality1 = connectivityTlv.GetLinkQuality1(); - parentinfo.mIsAttached = IsAttached(); + parentinfo.mIsAttached = Get().IsAttached(); mParentResponseCallback.Invoke(&parentinfo); } @@ -2951,14 +2907,14 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) aRxInfo.mClass = RxInfo::kAuthoritativeMessage; #if OPENTHREAD_FTD - if (IsFullThreadDevice() && !IsDetached()) + if (Get().IsFullThreadDevice() && !Get().IsDetached()) { - bool isPartitionIdSame = (leaderData.GetPartitionId() == mLeaderData.GetPartitionId()); + bool isPartitionIdSame = (leaderData.GetPartitionId() == Get().mLeaderData.GetPartitionId()); bool isIdSequenceSame = (connectivityTlv.GetIdSequence() == Get().GetRouterIdSequence()); bool isIdSequenceGreater = SerialNumber::IsGreater(connectivityTlv.GetIdSequence(), Get().GetRouterIdSequence()); - switch (mAttachMode) + switch (mMode) { case kAnyPartition: VerifyOrExit(!isPartitionIdSame || isIdSequenceGreater); @@ -2975,8 +2931,8 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) case kBetterPartition: VerifyOrExit(!isPartitionIdSame); - VerifyOrExit(Mle::ComparePartitions(connectivityTlv.IsSingleton(), leaderData, IsSingleton(), mLeaderData) > - 0); + VerifyOrExit(ComparePartitions(connectivityTlv.IsSingleton(), leaderData, Get().IsSingleton(), + Get().mLeaderData) > 0); break; case kBetterParent: @@ -2996,10 +2952,10 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) int compare = 0; #if OPENTHREAD_FTD - if (IsFullThreadDevice()) + if (Get().IsFullThreadDevice()) { - compare = Mle::ComparePartitions(connectivityTlv.IsSingleton(), leaderData, mParentCandidate.mIsSingleton, - mParentCandidate.mLeaderData); + compare = ComparePartitions(connectivityTlv.IsSingleton(), leaderData, mParentCandidate.mIsSingleton, + mParentCandidate.mLeaderData); } // Only consider partitions that are the same or better @@ -3037,7 +2993,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(mParentCandidate.mRxChallenge)); - InitNeighbor(mParentCandidate, aRxInfo); + Get().InitNeighbor(mParentCandidate, aRxInfo); mParentCandidate.SetRloc16(sourceAddress); mParentCandidate.GetLinkFrameCounters().SetAll(linkFrameCounter); mParentCandidate.SetLinkAckFrameCounter(linkFrameCounter); @@ -3067,7 +3023,7 @@ exit: LogProcessError(kTypeParentResponse, error); } -void Mle::HandleChildIdResponse(RxInfo &aRxInfo) +void Mle::Attacher::HandleChildIdResponse(RxInfo &aRxInfo) { Error error = kErrorNone; LeaderData leaderData; @@ -3081,7 +3037,7 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) VerifyOrExit(aRxInfo.IsNeighborStateValid(), error = kErrorSecurity); - VerifyOrExit(mAttachState == kAttachStateChildIdRequest); + VerifyOrExit(mState == kStateChildIdRequest); SuccessOrExit(error = Tlv::Find(aRxInfo.mMessage, shortAddress)); VerifyOrExit(RouterIdMatch(sourceAddress, shortAddress), error = kErrorRejected); @@ -3106,7 +3062,7 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) } // Clear Pending Dataset if device succeed to reattach using stored Pending Dataset - if (mReattachState == kReattachPending) + if (mReattachMode == kReattachModePending) { Get().Clear(); } @@ -3134,28 +3090,28 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) // Parent Attach Success - SetStateDetached(); + Get().SetStateDetached(); - SetLeaderData(leaderData); + Get().SetLeaderData(leaderData); #if OPENTHREAD_FTD - SuccessOrExit(error = ReadAndProcessRouteTlvOnFtdChild(aRxInfo, RouterIdFromRloc16(sourceAddress))); + SuccessOrExit(error = Get().ReadAndProcessRouteTlvOnFtdChild(aRxInfo, RouterIdFromRloc16(sourceAddress))); #endif - mParentCandidate.CopyTo(mParent); + mParentCandidate.CopyTo(Get().mParent); mParentCandidate.Clear(); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - Get().SetCslParentAccuracy(mParent.GetCslAccuracy()); + Get().SetCslParentAccuracy(Get().mParent.GetCslAccuracy()); #endif - mParent.SetRloc16(sourceAddress); + Get().mParent.SetRloc16(sourceAddress); IgnoreError(aRxInfo.mMessage.ReadAndSetNetworkDataTlv(leaderData)); - SetStateChild(shortAddress); + Get().SetStateChild(shortAddress); - if (!IsRxOnWhenIdle()) + if (!Get().IsRxOnWhenIdle()) { Get().SetAttachMode(false); Get().SetRxOnWhenIdle(false); @@ -3654,7 +3610,7 @@ void Mle::ParentSearch::HandleTimer(void) } Get().mCounters.mBetterParentAttachAttempts++; - Get().Attach(attachMode); + Get().mAttacher.Attach(attachMode); exit: StartTimer(); @@ -3978,7 +3934,7 @@ const char *Mle::MessageTypeActionToSuffixString(MessageType aType, MessageActio #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) -const char *Mle::AttachModeToString(AttachMode aMode) +const char *Mle::Attacher::AttachModeToString(AttachMode aMode) { static const char *const kAttachModeStrings[] = { "AnyPartition", // (0) kAnyPartition @@ -4003,46 +3959,46 @@ const char *Mle::AttachModeToString(AttachMode aMode) return kAttachModeStrings[aMode]; } -const char *Mle::AttachStateToString(AttachState aState) +const char *Mle::Attacher::StateToString(State aState) { - static const char *const kAttachStateStrings[] = { - "Idle", // (0) kAttachStateIdle - "Start", // (1) kAttachStateStart - "ParentReq", // (2) kAttachStateParent - "Announce", // (3) kAttachStateAnnounce - "ChildIdReq", // (4) kAttachStateChildIdRequest + static const char *const kStateStrings[] = { + "Idle", // (0) kStateIdle + "Start", // (1) kStateStart + "ParentReq", // (2) kStateParent + "Announce", // (3) kStateAnnounce + "ChildIdReq", // (4) kStateChildIdRequest }; struct EnumCheck { InitEnumValidatorCounter(); - ValidateNextEnum(kAttachStateIdle); - ValidateNextEnum(kAttachStateStart); - ValidateNextEnum(kAttachStateParentRequest); - ValidateNextEnum(kAttachStateAnnounce); - ValidateNextEnum(kAttachStateChildIdRequest); + ValidateNextEnum(kStateIdle); + ValidateNextEnum(kStateStart); + ValidateNextEnum(kStateParentRequest); + ValidateNextEnum(kStateAnnounce); + ValidateNextEnum(kStateChildIdRequest); }; - return kAttachStateStrings[aState]; + return kStateStrings[aState]; } -const char *Mle::ReattachStateToString(ReattachState aState) +const char *Mle::Attacher::ReattachModeToString(ReattachMode aMode) { - static const char *const kReattachStateStrings[] = { - "", // (0) kReattachStop - "reattaching with Active Dataset", // (1) kReattachActive - "reattaching with Pending Dataset", // (2) kReattachPending + static const char *const kReattachModeStrings[] = { + "", // (0) kReattachModeStop + "reattaching with Active Dataset", // (1) kReattachModeActive + "reattaching with Pending Dataset", // (2) kReattachModePending }; struct EnumCheck { InitEnumValidatorCounter(); - ValidateNextEnum(kReattachStop); - ValidateNextEnum(kReattachActive); - ValidateNextEnum(kReattachPending); + ValidateNextEnum(kReattachModeStop); + ValidateNextEnum(kReattachModeActive); + ValidateNextEnum(kReattachModePending); }; - return kReattachStateStrings[aState]; + return kReattachModeStrings[aMode]; } #endif // OT_SHOULD_LOG_AT( OT_LOG_LEVEL_NOTE) @@ -5352,6 +5308,80 @@ void Mle::PrevRoleRestorer::SendMulticastLinkRequest(void) #endif // OPENTHREAD_FTD +//--------------------------------------------------------------------------------------------------------------------- +// Attacher + +Mle::Attacher::Attacher(Instance &aInstance) + : InstanceLocator(aInstance) + , mReceivedResponseFromParent(false) + , mState(kStateIdle) + , mMode(kAnyPartition) + , mReattachMode(kReattachModeStop) + , mAddressRegistrationMode(kAppendAllAddresses) + , mParentRequestCounter(0) + , mAnnounceChannel(0) + , mAttachCounter(0) + , mAnnounceDelay(kAnnounceTimeout) + , mTimer(aInstance) +{ + mParentCandidate.Init(aInstance); + mParentCandidate.Clear(); +} + +void Mle::Attacher::Start(StartMode aMode) +{ + mAttachCounter = 0; + + switch (aMode) + { + case kNormalAttach: + mReattachMode = + (Get().Restore() == kErrorNone) ? kReattachModeActive : kReattachModeStop; + + if (Get().mPrevRoleRestorer.Start() == kErrorNone) + { + ExitNow(); + } + + break; + + case kAnnounceAttach: + break; + } + + Get().mAttacher.Attach(kAnyPartition); + +exit: + return; +} + +void Mle::Attacher::CancelAttachOnRoleChange(void) +{ + SetState(kStateIdle); + mTimer.Stop(); + + if (Get().IsChild()) + { + mTimer.Start(kAttachBackoffDelayToResetCounter); + mReattachMode = kReattachModeStop; + + if (mAddressRegistrationMode == kAppendMeshLocalOnly) + { + // If only mesh-local address was registered in the "Child + // ID Request" message, after device is attached, trigger a + // "Child Update Request" to register the remaining + // addresses. + + mAddressRegistrationMode = kAppendAllAddresses; + Get().ScheduleChildUpdateRequestIfMtdChild(); + } + } + else if (Get().IsRouterOrLeader()) + { + mAttachCounter = 0; + } +} + //--------------------------------------------------------------------------------------------------------------------- // Detacher diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index b1e21b017..16ead4937 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -233,7 +233,7 @@ public: * @retval TRUE Device is currently trying to attach. * @retval FALSE Device is not in middle of attach process. */ - bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); } + bool IsAttaching(void) const { return mAttacher.IsAttaching(); } /** * Returns the current Thread device role. @@ -432,7 +432,7 @@ public: * * The parent candidate is valid when attempting to attach to a new parent. */ - Parent &GetParentCandidate(void) { return mParentCandidate; } + Parent &GetParentCandidate(void) { return mAttacher.GetParentCandidate(); } /** * Starts the process for child to search for a better parent while staying attached to its current @@ -628,7 +628,7 @@ public: */ void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) { - mParentResponseCallback.Set(aCallback, aContext); + mAttacher.mParentResponseCallback.Set(aCallback, aContext); } #endif @@ -1779,6 +1779,90 @@ private: //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + void HandleAttacherTimer(void) { mAttacher.HandleTimer(); } + + class Attacher : public InstanceLocator + { + public: + explicit Attacher(Instance &aInstance); + + bool IsAttaching(void) const { return mState != kStateIdle; } + bool WillStartAttachSoon(void) const { return mState == kStateStart; } + bool IsReattachWithDatasetDone(void) const { return mReattachMode == kReattachModeStop; } + void Start(StartMode aMode); + void Attach(AttachMode aMode); + void CancelAttachOnRoleChange(void); + void ResetAttachCounter(void) { mAttachCounter = 0; } + AttachMode GetAttachMode(void) const { return mMode; } + ParentCandidate &GetParentCandidate(void) { return mParentCandidate; } + void ClearParentCandidate(void) { mParentCandidate.Clear(); } + void HandleParentResponse(RxInfo &aRxInfo); + void HandleChildIdResponse(RxInfo &aRxInfo); + void HandleTimer(void); + +#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE + Callback mParentResponseCallback; +#endif + private: + enum State : uint8_t + { + kStateIdle, // Not currently searching for a parent. + kStateStart, // Starting to look for a parent. + kStateParentRequest, // Send Parent Request (current number tracked by `mParentRequestCounter`). + kStateAnnounce, // Send Announce messages + kStateChildIdRequest, // Sending a Child ID Request message. + }; + + enum ReattachMode : uint8_t + { + kReattachModeStop, // Reattach process is disabled or finished + kReattachModeActive, // Reattach using stored Active Dataset + kReattachModePending, // Reattach using stored Pending Dataset + }; + + void SetState(State aState); + uint32_t GetStartDelay(void) const; + bool HasAcceptableParentCandidate(void) const; + uint32_t Reattach(void); + + Error DetermineParentRequestType(ParentRequestType &aType) const; + Error GetNextAnnounceChannel(uint8_t &aChannel) const; + bool HasMoreChannelsToAnnounce(void) const; + void SendParentRequest(ParentRequestType aType); + Error SendChildIdRequest(void); + void HandleChildIdRequestTxDone(const Message &aMessage); + bool PrepareAnnounceState(void); + bool IsBetterParent(uint16_t aRloc16, + uint8_t aTwoWayLinkMargin, + const ConnectivityTlv &aConnectivityTlv, + uint16_t aVersion, + const Mac::CslAccuracy &aCslAccuracy); + + static void HandleChildIdRequestTxDone(const otMessage *aMessage, otError aError, void *aContext); + + static const char *StateToString(State aState); +#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) + static const char *AttachModeToString(AttachMode aMode); + static const char *ReattachModeToString(ReattachMode aMode); +#endif + using AttachTimer = TimerMilliIn; + + bool mReceivedResponseFromParent : 1; + State mState; + AttachMode mMode; + ReattachMode mReattachMode; + AddressRegistrationMode mAddressRegistrationMode; + uint8_t mParentRequestCounter; + uint8_t mAnnounceChannel; + uint16_t mAttachCounter; + uint16_t mAnnounceDelay; + TxChallenge mParentRequestChallenge; + ParentCandidate mParentCandidate; + AttachTimer mTimer; + }; + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + void HandleDetacherTimer(void) { mDetacher.HandleTimer(); } class Detacher : public InstanceLocator @@ -2016,10 +2100,7 @@ private: Error RestorePrevRole(void); TxMessage *NewMleMessage(Command aCommand); void SetRole(DeviceRole aRole); - void Attach(AttachMode aMode); - void SetAttachState(AttachState aState); void InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo); - void ClearParentCandidate(void) { mParentCandidate.Clear(); } Error SendDataRequestToParent(void); Error SendDataRequest(const Ip6::Address &aDestination); void HandleNotifierEvents(Events aEvents); @@ -2038,35 +2119,18 @@ private: uint32_t GenerateRandomDelay(uint32_t aMaxDelay) const; void InformPreviousChannel(void); void ScheduleMessageTransmissionTimer(void); - void HandleAttachTimer(void); void ProcessKeySequence(RxInfo &aRxInfo); void HandleAdvertisement(RxInfo &aRxInfo); - void HandleChildIdResponse(RxInfo &aRxInfo); void HandleChildUpdateRequest(RxInfo &aRxInfo); void HandleChildUpdateRequestOnChild(RxInfo &aRxInfo); void HandleChildUpdateResponse(RxInfo &aRxInfo); void HandleChildUpdateResponseOnChild(RxInfo &aRxInfo); void HandleDataResponse(RxInfo &aRxInfo); - void HandleParentResponse(RxInfo &aRxInfo); Error HandleLeaderData(RxInfo &aRxInfo); bool HasUnregisteredAddress(void); uint32_t GetAttachStartDelay(void) const; - void SendParentRequest(ParentRequestType aType); - Error SendChildIdRequest(void); - void HandleChildIdRequestTxDone(const Message &aMessage); - Error GetNextAnnounceChannel(uint8_t &aChannel) const; - bool HasMoreChannelsToAnnounce(void) const; - bool PrepareAnnounceState(void); void SendAnnounce(uint8_t aChannel, AnnounceMode aMode); void SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce); - uint32_t Reattach(void); - bool HasAcceptableParentCandidate(void) const; - Error DetermineParentRequestType(ParentRequestType &aType) const; - bool IsBetterParent(uint16_t aRloc16, - uint8_t aTwoWayLinkMargin, - const ConnectivityTlv &aConnectivityTlv, - uint16_t aVersion, - const Mac::CslAccuracy &aCslAccuracy); bool IsNetworkDataNewer(const LeaderData &aLeaderData); Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, Message &aMessage, @@ -2074,8 +2138,6 @@ private: uint16_t aCmdOffset, const SecurityHeader &aHeader); - static void HandleChildIdRequestTxDone(const otMessage *aMessage, otError aError, void *aContext); - #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH void InformPreviousParent(void); #endif @@ -2122,12 +2184,6 @@ private: void HandleWedAttachTimer(void); #endif -#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) - static const char *AttachModeToString(AttachMode aMode); - static const char *AttachStateToString(AttachState aState); - static const char *ReattachStateToString(ReattachState aState); -#endif - #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) static void LogError(MessageAction aAction, MessageType aType, Error aError); static const char *MessageActionToString(MessageAction aAction); @@ -2146,7 +2202,7 @@ private: uint8_t SelectLeaderId(void) const; uint32_t SelectPartitionId(void) const; void HandleDetachStart(void); - void HandleChildStart(AttachMode aMode); + void HandleChildStart(void); void HandleSecurityPolicyChanged(void); void HandleLinkRequest(RxInfo &aRxInfo); void HandleLinkAccept(RxInfo &aRxInfo); @@ -2219,61 +2275,43 @@ private: //------------------------------------------------------------------------------------------------------------------ // Variables - using AttachTimer = TimerMilliIn; - using MleSocket = Ip6::Udp::SocketIn; + using MleSocket = Ip6::Udp::SocketIn; #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE using WedAttachTimer = TimerMicroIn; #endif static const otMeshLocalPrefix kMeshLocalPrefixInit; - bool mRetrieveNewNetworkData : 1; - bool mRequestRouteTlv : 1; - bool mHasRestored : 1; - bool mReceivedResponseFromParent : 1; - bool mInitiallyAttachedAsSleepy : 1; - - DeviceRole mRole; - DeviceRole mLastSavedRole; - DeviceMode mDeviceMode; - AttachState mAttachState; - ReattachState mReattachState; - AttachMode mAttachMode; - AddressRegistrationMode mAddressRegistrationMode; - - uint8_t mParentRequestCounter; - uint8_t mAnnounceChannel; - uint16_t mRloc16; - uint16_t mPreviousParentRloc; - uint16_t mAttachCounter; - uint16_t mAnnounceDelay; - uint32_t mStoreFrameCounterAhead; - uint32_t mTimeout; + bool mRetrieveNewNetworkData : 1; + bool mRequestRouteTlv : 1; + bool mHasRestored : 1; + bool mInitiallyAttachedAsSleepy : 1; + DeviceRole mRole; + DeviceRole mLastSavedRole; + DeviceMode mDeviceMode; + uint16_t mRloc16; + uint16_t mPreviousParentRloc; + uint32_t mStoreFrameCounterAhead; + uint32_t mTimeout; #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE uint32_t mCslTimeout; #endif - uint32_t mLastAttachTime; - uint64_t mLastUpdatedTimestamp; - + uint32_t mLastAttachTime; + uint64_t mLastUpdatedTimestamp; LeaderData mLeaderData; Parent mParent; NeighborTable mNeighborTable; DelayedSender mDelayedSender; - TxChallenge mParentRequestChallenge; - ParentCandidate mParentCandidate; MleSocket mSocket; Counters mCounters; PrevRoleRestorer mPrevRoleRestorer; + Attacher mAttacher; Detacher mDetacher; RetxTracker mRetxTracker; AnnounceHandler mAnnounceHandler; #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE ParentSearch mParentSearch; #endif -#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE - Callback mParentResponseCallback; -#endif - AttachTimer mAttachTimer; Ip6::NetworkPrefix mMeshLocalPrefix; Ip6::Netif::UnicastAddress mLinkLocalAddress; Ip6::Netif::UnicastAddress mMeshLocalEid; @@ -2297,7 +2335,6 @@ private: bool mCcmEnabled : 1; bool mThreadVersionCheckEnabled : 1; #endif - uint8_t mRouterId; uint8_t mPreviousRouterId; uint8_t mNetworkIdTimeout; @@ -2317,7 +2354,6 @@ private: #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE uint32_t mPreferredLeaderPartitionId; #endif - TrickleTimer mAdvertiseTrickleTimer; ChildTable mChildTable; RouterTable mRouterTable; diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index e7deff5d2..36b87fd7e 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -305,7 +305,7 @@ void Mle::HandleDetachStart(void) Get().UnregisterReceiver(TimeTicker::kMle); } -void Mle::HandleChildStart(AttachMode aMode) +void Mle::HandleChildStart(void) { mAddressSolicitRejected = false; @@ -323,7 +323,7 @@ void Mle::HandleChildStart(AttachMode aMode) VerifyOrExit(IsRouterIdValid(mPreviousRouterId)); - switch (aMode) + switch (mAttacher.GetAttachMode()) { case kDowngradeToReed: SendAddressRelease(); @@ -411,10 +411,8 @@ void Mle::SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStart SetRole(aRole); mPrevRoleRestorer.Stop(); + mAttacher.CancelAttachOnRoleChange(); - SetAttachState(kAttachStateIdle); - mAttachCounter = 0; - mAttachTimer.Stop(); mRetxTracker.Stop(); StopAdvertiseTrickleTimer(); ResetAdvertiseInterval(); @@ -1213,7 +1211,7 @@ Error Mle::HandleAdvertisementOnFtd(RxInfo &aRxInfo, uint16_t aSourceAddress, co #endif ) { - Attach(kBetterPartition); + mAttacher.Attach(kBetterPartition); } ExitNow(error = kErrorDrop); @@ -1590,13 +1588,13 @@ void Mle::HandleTimeTick(void) if ((mRouterTable.GetActiveRouterCount() > 0) && (mRouterTable.GetLeaderAge() >= mNetworkIdTimeout)) { LogInfo("Leader age timeout"); - Attach(kSamePartition); + mAttacher.Attach(kSamePartition); } if (roleTransitionTimeoutExpired && mRouterTable.GetActiveRouterCount() > mRouterDowngradeThreshold) { LogNote("Downgrade to REED"); - Attach(kDowngradeToReed); + mAttacher.Attach(kDowngradeToReed); } OT_FALL_THROUGH; @@ -3220,7 +3218,7 @@ void Mle::RemoveNeighbor(Neighbor &aNeighbor) } else if (&aNeighbor == &GetParentCandidate()) { - ClearParentCandidate(); + mAttacher.ClearParentCandidate(); } else if (IsChildRloc16(aNeighbor.GetRloc16())) {