diff options
author | Abtin Keshavarzian <abtink@google.com> | 2024-03-27 14:36:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-27 14:36:46 -0700 |
commit | 34a0b0dd7ecf9d4ebfd7e67ce18b775debc1f3a5 (patch) | |
tree | 8a0eb29bd209b28d50968ec77bf832451baa6623 | |
parent | 7271b199d3115878e6d2b3d1aa1d6bd133863bb5 (diff) | |
download | openthread-34a0b0dd7ecf9d4ebfd7e67ce18b775debc1f3a5.tar.gz |
[mle] improve MLE module comments (#9972)
This commit streamlines MLE module comments by simplifying
explanations and removing redundant ones that are clear from source
code.
-rw-r--r-- | src/core/thread/mle.cpp | 112 | ||||
-rw-r--r-- | src/core/thread/mle_router.cpp | 168 |
2 files changed, 96 insertions, 184 deletions
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index bac427a95..234f405d9 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -454,7 +454,8 @@ void Mle::Restore(void) mWasLeader = networkInfo.GetRole() == kRoleLeader; #endif - // Successfully restored the network information from non-volatile settings after boot. + // Successfully restored the network information from + // non-volatile settings after boot. mHasRestored = true; exit: @@ -533,7 +534,7 @@ Error Mle::BecomeDetached(void) VerifyOrExit(!IsDetached() || mAttachState != kAttachStateStart); - // not in reattach stage after reset + // Not in reattach stage after reset if (mReattachState == kReattachStop) { Get<MeshCoP::PendingDatasetManager>().HandleDetach(); @@ -1120,7 +1121,6 @@ void Mle::HandleNotifierEvents(Events aEvents) { if (!Get<ThreadNetif>().HasUnicastAddress(mMeshLocal64.GetAddress())) { - // Mesh Local EID was removed, choose a new one and add it back mMeshLocal64.GetAddress().GetIid().GenerateRandom(); Get<ThreadNetif>().AddUnicastAddress(mMeshLocal64); @@ -1135,9 +1135,12 @@ void Mle::HandleNotifierEvents(Events aEvents) if (aEvents.ContainsAny(kEventIp6MulticastSubscribed | kEventIp6MulticastUnsubscribed)) { - // When multicast subscription changes, SED always notifies its parent as it depends on its - // parent for indirect transmission. Since Thread 1.2, MED MAY also notify its parent of 1.2 - // or higher version as it could depend on its parent to perform Multicast Listener Report. + // When multicast subscription changes, SED always notifies + // its parent as it depends on its parent for indirect + // transmission. Since Thread 1.2, MED MAY also notify its + // parent of 1.2 or higher version as it could depend on its + // parent to perform Multicast Listener Report. + if (IsChild() && !IsFullThreadDevice() && (!IsRxOnWhenIdle() #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) @@ -1577,7 +1580,7 @@ uint32_t Mle::Reattach(void) } else if (!IsRxOnWhenIdle()) { - // return to sleepy operation + // Return to sleepy operation Get<DataPollSender>().SetAttachMode(false); Get<MeshForwarder>().SetRxOnWhenIdle(false); } @@ -1653,7 +1656,6 @@ void Mle::SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata exit: if (error != kErrorNone) { - // do not use `FreeMessageOnError()` to avoid null check on nonnull pointer aMessage.Free(); } } @@ -1782,9 +1784,13 @@ Error Mle::SendChildIdRequest(void) { // Invalidate stale parent state. // - // Parent state is not normally invalidated after becoming a Router/Leader (see #1875). When trying to - // attach to a better partition, invalidating old parent state (especially when in kStateRestored) ensures - // that FindNeighbor() returns mParentCandidate when processing the Child ID Response. + // Parent state is not normally invalidated after becoming + // a Router/Leader (see #1875). When trying to attach to + // a better partition, invalidating old parent state + // (especially when in `kStateRestored`) ensures that + // `FindNeighbor()` returns `mParentCandidate` when + // processing the Child ID Response. + mParent.SetState(Neighbor::kStateInvalid); } } @@ -1802,7 +1808,7 @@ Error Mle::SendChildIdRequest(void) { SuccessOrExit(error = message->AppendAddressRegistrationTlv(mAddressRegistrationMode)); - // no need to request the last Route64 TLV for MTD + // No need to request the last Route64 TLV for MTD tlvsLen -= 1; } @@ -2011,9 +2017,8 @@ void Mle::HandleMessageTransmissionTimer(void) case kChildUpdateRequestPending: if (Get<Notifier>().IsPending()) { - // Here intentionally delay another kChildUpdateRequestPendingDelay - // cycle to ensure we only send a Child Update Request after we - // know there are no more pending changes. + // Add another delay to ensures the Child Update Request is sent + // only after all pending changes are incorporated. ScheduleMessageTransmissionTimer(); ExitNow(); } @@ -2880,11 +2885,8 @@ void Mle::HandleDataResponse(RxInfo &aRxInfo) if (mDataRequestState == kDataRequestNone && !IsRxOnWhenIdle()) { - // Here simply stops fast data poll request by Mle Data Request. - // Note that in some cases fast data poll may continue after below stop operation until - // running out the specified number. E.g. other component also trigger fast poll, and - // is waiting for response; or the corner case where multiple Mle Data Request attempts - // happened due to the retransmission mechanism. + // Stop fast data poll request by MLE since we received + // the response. Get<DataPollSender>().StopFastPolls(); } @@ -2918,7 +2920,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) uint16_t pendingDatasetLength = 0; bool dataRequest = false; - // Leader Data SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)); if ((leaderData.GetPartitionId() != mLeaderData.GetPartitionId()) || @@ -2939,7 +2940,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) VerifyOrExit(IsNetworkDataNewer(leaderData)); } - // Active Timestamp switch (Tlv::Find<ActiveTimestampTlv>(aRxInfo.mMessage, activeTimestamp)) { case kErrorNone: @@ -2947,8 +2947,9 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) timestamp = Get<MeshCoP::ActiveDatasetManager>().GetTimestamp(); - // if received timestamp does not match the local value and message does not contain the dataset, - // send MLE Data Request + // Send an MLE Data Request if the received timestamp + // mismatches the local value and the message does not + // include the dataset. if (!IsLeader() && (MeshCoP::Timestamp::Compare(&activeTimestamp, timestamp) != 0) && (Tlv::FindTlvValueOffset(aRxInfo.mMessage, Tlv::kActiveDataset, activeDatasetOffset, activeDatasetLength) != kErrorNone)) @@ -2965,7 +2966,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Pending Timestamp switch (Tlv::Find<PendingTimestampTlv>(aRxInfo.mMessage, pendingTimestamp)) { case kErrorNone: @@ -2973,8 +2973,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) timestamp = Get<MeshCoP::PendingDatasetManager>().GetTimestamp(); - // if received timestamp does not match the local value and message does not contain the dataset, - // send MLE Data Request if (!IsLeader() && (MeshCoP::Timestamp::Compare(&pendingTimestamp, timestamp) != 0) && (Tlv::FindTlvValueOffset(aRxInfo.mMessage, Tlv::kPendingDataset, pendingDatasetOffset, pendingDatasetLength) != kErrorNone)) @@ -3012,7 +3010,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) else #endif { - // Active Dataset if (hasActiveTimestamp) { if (activeDatasetOffset > 0) @@ -3022,7 +3019,6 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo) } } - // Pending Dataset if (hasPendingTimestamp) { if (pendingDatasetOffset > 0) @@ -3154,16 +3150,13 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) TimeParameterTlv timeParameterTlv; #endif - // Source Address SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)); Log(kMessageReceive, kTypeParentResponse, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress); - // Version SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version)); VerifyOrExit(version >= kThreadVersion1p1, error = kErrorParse); - // Response SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response)); VerifyOrExit(response == mParentRequestChallenge, error = kErrorParse); @@ -3174,20 +3167,16 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) mReceivedResponseFromParent = true; } - // Leader Data SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)); - // Link Margin SuccessOrExit(error = Tlv::Find<LinkMarginTlv>(aRxInfo.mMessage, linkMarginFromTlv)); linkMargin = Min(Get<Mac::Mac>().ComputeLinkMargin(rss), linkMarginFromTlv); linkQuality = LinkQualityForLinkMargin(linkMargin); - // Connectivity SuccessOrExit(error = Tlv::FindTlv(aRxInfo.mMessage, connectivityTlv)); VerifyOrExit(connectivityTlv.IsValid(), error = kErrorParse); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - // CSL Accuracy switch (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy)) { case kErrorNone: @@ -3260,7 +3249,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) if (mParentCandidate.IsStateParentResponse() && (mParentCandidate.GetExtAddress() != extAddress)) { - // if already have a candidate parent, only seek a better parent + // If already have a candidate parent, only seek a better parent int compare = 0; @@ -3271,23 +3260,21 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) mParentCandidate.mIsSingleton, mParentCandidate.mLeaderData); } - // only consider partitions that are the same or better + // Only consider partitions that are the same or better VerifyOrExit(compare >= 0); #endif - // only consider better parents if the partitions are the same + // Only consider better parents if the partitions are the same if (compare == 0) { VerifyOrExit(IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivityTlv, version, cslAccuracy)); } } - // Link/MLE Frame Counters SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter)); #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - // Time Parameter if (Tlv::FindTlv(aRxInfo.mMessage, timeParameterTlv) == kErrorNone) { VerifyOrExit(timeParameterTlv.IsValid()); @@ -3299,14 +3286,13 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) #if OPENTHREAD_CONFIG_TIME_SYNC_REQUIRED else { - // If the time sync feature is required, don't choose the parent which doesn't support it. + // If the time sync feature is required, don't choose the + // parent which doesn't support it. ExitNow(); } - -#endif // OPENTHREAD_CONFIG_TIME_SYNC_REQUIRED +#endif #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - // Challenge SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(mParentCandidate.mRxChallenge)); InitNeighbor(mParentCandidate, aRxInfo); @@ -3351,7 +3337,6 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) uint16_t offset; uint16_t length; - // Source Address SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)); Log(kMessageReceive, kTypeChildIdResponse, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress); @@ -3360,22 +3345,17 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) VerifyOrExit(mAttachState == kAttachStateChildIdRequest); - // ShortAddress SuccessOrExit(error = Tlv::Find<Address16Tlv>(aRxInfo.mMessage, shortAddress)); VerifyOrExit(RouterIdMatch(sourceAddress, shortAddress), error = kErrorRejected); - // Leader Data SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)); - // Network Data SuccessOrExit( error = Tlv::FindTlvValueOffset(aRxInfo.mMessage, Tlv::kNetworkData, networkDataOffset, networkDataLength)); - // Active Timestamp switch (Tlv::Find<ActiveTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: - // Active Dataset if (Tlv::FindTlvValueOffset(aRxInfo.mMessage, Tlv::kActiveDataset, offset, length) == kErrorNone) { SuccessOrExit(error = @@ -3390,17 +3370,15 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // clear Pending Dataset if device succeed to reattach using stored Pending Dataset + // Clear Pending Dataset if device succeed to reattach using stored Pending Dataset if (mReattachState == kReattachPending) { Get<MeshCoP::PendingDatasetManager>().Clear(); } - // Pending Timestamp switch (Tlv::Find<PendingTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: - // Pending Dataset if (Tlv::FindTlvValueOffset(aRxInfo.mMessage, Tlv::kPendingDataset, offset, length) == kErrorNone) { IgnoreError(Get<MeshCoP::PendingDatasetManager>().Save(timestamp, aRxInfo.mMessage, offset, length)); @@ -3416,7 +3394,6 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo) } #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - // Sync to Thread network time if (aRxInfo.mMessage.GetTimeSyncSeq() != OT_TIME_SYNC_INVALID_SEQ) { Get<TimeSync>().HandleTimeSyncMessage(aRxInfo.mMessage); @@ -3472,12 +3449,10 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) TlvList requestedTlvList; TlvList tlvList; - // Source Address SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)); Log(kMessageReceive, kTypeChildUpdateRequestAsChild, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress); - // Challenge switch (aRxInfo.mMessage.ReadChallengeTlv(challenge)) { case kErrorNone: @@ -3513,7 +3488,6 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) ExitNow(); } - // Leader Data, Network Data, Active Timestamp, Pending Timestamp SuccessOrExit(error = HandleLeaderData(aRxInfo)); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -3522,7 +3496,8 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) if (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy) == kErrorNone) { - // MUST include CSL timeout TLV when request includes CSL accuracy + // MUST include CSL timeout TLV when request includes + // CSL accuracy tlvList.Add(Tlv::kCslTimeout); } } @@ -3530,11 +3505,10 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) } else { - // this device is not a child of the Child Update Request source + // This device is not a child of the Child Update Request source tlvList.Add(Tlv::kStatus); } - // TLV Request switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList)) { case kErrorNone: @@ -3556,7 +3530,8 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) } #endif - // Send the response to the requester, regardless if it's this device's parent or not + // Send the response to the requester, regardless if it's this + // device's parent or not. SuccessOrExit(error = SendChildUpdateResponse(tlvList, challenge, aRxInfo.mMessageInfo.GetPeerAddr())); exit: @@ -3601,14 +3576,12 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) OT_ASSERT(false); } - // Status if (Tlv::Find<StatusTlv>(aRxInfo.mMessage, status) == kErrorNone) { IgnoreError(BecomeDetached()); ExitNow(); } - // Mode SuccessOrExit(error = Tlv::Find<ModeTlv>(aRxInfo.mMessage, mode)); VerifyOrExit(DeviceMode(mode) == mDeviceMode, error = kErrorDrop); @@ -3636,7 +3609,6 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) OT_FALL_THROUGH; case kRoleChild: - // Source Address SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)); if (RouterIdFromRloc16(sourceAddress) != RouterIdFromRloc16(GetRloc16())) @@ -3645,10 +3617,8 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(); } - // Leader Data, Network Data, Active Timestamp, Pending Timestamp SuccessOrExit(error = HandleLeaderData(aRxInfo)); - // Timeout optional switch (Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout)) { case kErrorNone: @@ -3671,7 +3641,6 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) { Mac::CslAccuracy cslAccuracy; - // CSL Accuracy switch (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy)) { case kErrorNone: @@ -3820,8 +3789,7 @@ void Mle::HandleLinkMetricsManagementRequest(RxInfo &aRxInfo) exit: LogProcessError(kTypeLinkMetricsManagementRequest, error); } - -#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE +#endif #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE void Mle::HandleLinkMetricsManagementResponse(RxInfo &aRxInfo) @@ -3840,7 +3808,7 @@ void Mle::HandleLinkMetricsManagementResponse(RxInfo &aRxInfo) exit: LogProcessError(kTypeLinkMetricsManagementResponse, error); } -#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE +#endif #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE void Mle::HandleLinkProbe(RxInfo &aRxInfo) @@ -3861,7 +3829,7 @@ void Mle::HandleLinkProbe(RxInfo &aRxInfo) exit: LogProcessError(kTypeLinkProbe, error); } -#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE +#endif void Mle::ProcessAnnounce(void) { diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index fcca088b0..40894798a 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -363,15 +363,22 @@ void MleRouter::HandleChildStart(AttachMode aMode) case kAnyPartition: case kBetterParent: - // If attach was started due to receiving MLE Announce Messages, all rx-on-when-idle devices would - // start attach immediately when receiving such Announce message as in Thread 1.1 specification, - // Section 4.8.1, - // "If the received value is newer and the channel and/or PAN ID in the Announce message differ - // from those currently in use, the receiving device attempts to attach using the channel and - // PAN ID received from the Announce message." + + // If attach was initiated due to receiving an MLE Announce + // message, all rx-on-when-idle devices will immediately + // attempt to attach as well. This aligns with the Thread 1.1 + // specification (Section 4.8.1): + // + // "If the received value is newer and the channel and/or PAN + // ID in the Announce message differ from those currently in + // use, the receiving device attempts to attach using the + // channel and PAN ID received from the Announce message." // - // That is, Parent-child relationship is highly unlikely to be kept in the new partition, so here - // removes all children, leaving whether to become router according to the new partition status. + // Since parent-child relationships are unlikely to persist in + // the new partition, we remove all children here. The + // decision to become router is determined based on the new + // partition's status. + if (IsAnnounceAttach() && HasChildren()) { RemoveChildren(); @@ -442,7 +449,7 @@ void MleRouter::SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, Leade Get<AddressResolver>().Clear(); } - // Remove children that do not have matching RLOC16 + // Remove children that do not have a matching RLOC16 for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring)) { if (RouterIdFromRloc16(child.GetRloc16()) != mRouterId) @@ -521,17 +528,19 @@ void MleRouter::SendAdvertisement(void) Ip6::Address destination; TxMessage *message = nullptr; - // Suppress MLE Advertisements when trying to attach to a better partition. - // - // Without this suppression, a device may send an MLE Advertisement before receiving the MLE Child ID Response. - // The candidate parent then removes the attaching device because the Source Address TLV includes an RLOC16 that - // indicates a Router role (i.e. a Child ID equal to zero). + // Suppress MLE Advertisements when trying to attach to a better + // partition. Without this, a candidate parent might incorrectly + // interpret this advertisement (Source Address TLV containing an + // RLOC16 indicating device is acting as router) and reject the + // attaching device. + VerifyOrExit(!IsAttaching()); - // Suppress MLE Advertisements when transitioning to the router role. - // - // When trying to attach to a new partition, sending out advertisements as a REED can cause already-attached - // children to detach. + // Suppress MLE Advertisements when attempting to transition to + // router role. Advertisements as a REED while attaching to a new + // partition can cause existing children to detach + // unnecessarily. + VerifyOrExit(!mAddressSolicitPending); VerifyOrExit((message = NewMleMessage(kCommandAdvertisement)) != nullptr, error = kErrorNoBufs); @@ -665,14 +674,11 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo) VerifyOrExit(!IsAttaching(), error = kErrorInvalidState); - // Challenge SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge)); - // Version SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version)); VerifyOrExit(version >= kThreadVersion1p1, error = kErrorParse); - // Leader Data switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)) { case kErrorNone: @@ -684,7 +690,6 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Source Address switch (Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)) { case kErrorNone: @@ -711,7 +716,8 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo) break; case kErrorNotFound: - // lack of source address indicates router coming out of reset + // A missing source address indicates that the router was + // recently reset. VerifyOrExit(aRxInfo.IsNeighborStateValid() && IsActiveRouter(aRxInfo.mNeighbor->GetRloc16()), error = kErrorDrop); neighbor = aRxInfo.mNeighbor; @@ -721,7 +727,6 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // TLV Request switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList)) { case kErrorNone: @@ -775,9 +780,7 @@ Error MleRouter::SendLinkAccept(const RxInfo &aRxInfo, SuccessOrExit(error = message->AppendLinkFrameCounterTlv()); SuccessOrExit(error = message->AppendMleFrameCounterTlv()); - // always append a link margin, regardless of whether or not it was requested linkMargin = Get<Mac::Mac>().ComputeLinkMargin(aRxInfo.mMessage.GetAverageRss()); - SuccessOrExit(error = message->AppendLinkMarginTlv(linkMargin)); if (aNeighbor != nullptr && IsActiveRouter(aNeighbor->GetRloc16())) @@ -874,7 +877,6 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) LeaderData leaderData; uint8_t linkMargin; - // Source Address SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)); Log(kMessageReceive, aRequest ? kTypeLinkAcceptAndRequest : kTypeLinkAccept, aRxInfo.mMessageInfo.GetPeerAddr(), @@ -886,10 +888,8 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) router = mRouterTable.FindRouterById(routerId); neighborState = (router != nullptr) ? router->GetState() : Neighbor::kStateInvalid; - // Response SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response)); - // verify response switch (neighborState) { case Neighbor::kStateLinkRequest: @@ -915,22 +915,20 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) RemoveNeighbor(*aRxInfo.mNeighbor); } - // Version SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version)); VerifyOrExit(version >= kThreadVersion1p1, error = kErrorParse); - // Link and MLE Frame Counters SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter)); - // Link Margin switch (Tlv::Find<LinkMarginTlv>(aRxInfo.mMessage, linkMargin)) { case kErrorNone: break; case kErrorNotFound: - // Link Margin TLV may be skipped in Router Synchronization process after Reset + // The Link Margin TLV may be omitted after a reset. We wait + // for MLE Advertisements to establish the routing cost to + // the neighbor VerifyOrExit(IsDetached(), error = kErrorNotFound); - // Wait for an MLE Advertisement to establish a routing cost to the neighbor linkMargin = 0; break; default: @@ -940,15 +938,12 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) switch (mRole) { case kRoleDetached: - // Address16 SuccessOrExit(error = Tlv::Find<Address16Tlv>(aRxInfo.mMessage, address16)); VerifyOrExit(GetRloc16() == address16, error = kErrorDrop); - // Leader Data SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)); SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId()); - // Route mRouterTable.Clear(); SuccessOrExit(error = aRxInfo.mMessage.ReadRouteTlv(routeTlv)); SuccessOrExit(error = ProcessRouteTlv(routeTlv, aRxInfo)); @@ -964,7 +959,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) SetStateRouter(GetRloc16()); } - mLinkRequestAttempts = 0; // completed router sync after reset, no more link request to retransmit + mLinkRequestAttempts = 0; mRetrieveNewNetworkData = true; IgnoreError(SendDataRequest(aRxInfo.mMessageInfo.GetPeerAddr())); @@ -981,7 +976,6 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) case kRoleLeader: VerifyOrExit(router != nullptr); - // Leader Data SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)); VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId()); @@ -992,7 +986,6 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) IgnoreError(SendDataRequest(aRxInfo.mMessageInfo.GetPeerAddr())); } - // Route (optional) switch (aRxInfo.mMessage.ReadRouteTlv(routeTlv)) { case kErrorNone: @@ -1026,7 +1019,6 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) OT_ASSERT(false); } - // finish link synchronization InitNeighbor(*router, aRxInfo); router->SetRloc16(sourceAddress); router->GetLinkFrameCounters().SetAll(linkFrameCounter); @@ -1049,10 +1041,8 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest) RxChallenge challenge; TlvList requestedTlvList; - // Challenge SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge)); - // TLV Request switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList)) { case kErrorNone: @@ -1218,7 +1208,7 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, c if (ComparePartitions(routeTlv.IsSingleton(), aLeaderData, IsSingleton(), mLeaderData) > 0 #if OPENTHREAD_CONFIG_TIME_SYNC_REQUIRED - // if time sync is required, it will only migrate to a better network which also enables time sync. + // Allow a better partition if it also enables time sync. && aRxInfo.mMessage.GetTimeSyncSeq() != OT_TIME_SYNC_INVALID_SEQ #endif ) @@ -1333,7 +1323,9 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, c Get<AddressResolver>().ReplaceEntriesForRloc16(aRxInfo.mNeighbor->GetRloc16(), router->GetRloc16()); } - // Send unicast link request if no link to router and no unicast/multicast link request in progress + // Send unicast link request if no link to router and no + // unicast/multicast link request in progress + if (!router->IsStateValid() && !router->IsStateLinkRequest() && (mChallengeTimeout == 0) && (linkMargin >= kLinkRequestMinMargin)) { @@ -1350,7 +1342,6 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, c exit: if (aRxInfo.mNeighbor && aRxInfo.mNeighbor->GetRloc16() != aSourceAddress) { - // Remove stale neighbors RemoveNeighbor(*aRxInfo.mNeighbor); } @@ -1395,11 +1386,9 @@ void MleRouter::HandleParentRequest(RxInfo &aRxInfo) aRxInfo.mMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr); - // Version SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version)); VerifyOrExit(version >= kThreadVersion1p1, error = kErrorParse); - // Scan Mask SuccessOrExit(error = Tlv::Find<ScanMaskTlv>(aRxInfo.mMessage, scanMask)); switch (mRole) @@ -1419,7 +1408,6 @@ void MleRouter::HandleParentRequest(RxInfo &aRxInfo) break; } - // Challenge SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge)); child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid); @@ -1428,7 +1416,6 @@ void MleRouter::HandleParentRequest(RxInfo &aRxInfo) { VerifyOrExit((child = mChildTable.GetNewChild()) != nullptr, error = kErrorNoBufs); - // MAC Address InitNeighbor(*child, aRxInfo); child->SetState(Neighbor::kStateParentRequest); #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE @@ -1510,6 +1497,9 @@ void MleRouter::HandleTimeTick(void) mPreviousPartitionIdTimeout--; } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Role transitions + roleTransitionTimeoutExpired = mRouterRoleTransition.HandleTimeTick(); switch (mRole) @@ -1532,7 +1522,6 @@ void MleRouter::HandleTimeTick(void) } else { - // send announce after decided to stay in REED if needed InformPreviousChannel(); } @@ -1578,7 +1567,9 @@ void MleRouter::HandleTimeTick(void) OT_ASSERT(false); } - // update children state + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Update `ChildTable` + for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid)) { uint32_t timeout = 0; @@ -1622,7 +1613,9 @@ void MleRouter::HandleTimeTick(void) } } - // update router state + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Update `RouterTable` + for (Router &router : Get<RouterTable>()) { uint32_t age; @@ -1789,7 +1782,6 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) #endif #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE - // Retrieve registered multicast addresses of the Child if (aChild.HasAnyMlrRegisteredAddress()) { OT_ASSERT(aChild.IsStateValid()); @@ -1853,7 +1845,8 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE if (mMaxChildIpAddresses > 0 && storedCount >= mMaxChildIpAddresses) { - // Skip remaining address registration entries but keep logging skipped addresses. + // Skip remaining address registration entries but keep logging + // skipped addresses. error = kErrorNoBufs; } else @@ -1899,7 +1892,7 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) } else { - // if not able to store DUA, then assume child does not have one + // It cannot store DUA, then assume child does not have one. hasNewDua = false; } } @@ -1981,43 +1974,33 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) VerifyOrExit(IsRouterEligible(), error = kErrorInvalidState); - // only process message when operating as a child, router, or leader VerifyOrExit(IsAttached(), error = kErrorInvalidState); - // Find Child aRxInfo.mMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr); child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid); VerifyOrExit(child != nullptr, error = kErrorAlready); - // Version SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version)); VerifyOrExit(version >= kThreadVersion1p1, error = kErrorParse); - // Response SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response)); VerifyOrExit(response == child->GetChallenge(), error = kErrorSecurity); - // Remove existing MLE messages Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleGeneral); Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleChildIdRequest); Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleChildUpdateRequest); Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleDataResponse); - // Link-Layer and MLE Frame Counters SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter)); - // Mode SuccessOrExit(error = Tlv::Find<ModeTlv>(aRxInfo.mMessage, modeBitmask)); mode.Set(modeBitmask); - // Timeout SuccessOrExit(error = Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout)); - // Requested TLVs SuccessOrExit(error = aRxInfo.mMessage.ReadTlvRequestTlv(tlvList)); - // Supervision interval switch (Tlv::Find<SupervisionIntervalTlv>(aRxInfo.mMessage, supervisionInterval)) { case kErrorNone: @@ -2030,7 +2013,6 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Active Timestamp switch (Tlv::Find<ActiveTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: @@ -2049,7 +2031,6 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Pending Timestamp switch (Tlv::Find<PendingTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: @@ -2075,12 +2056,10 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) SuccessOrExit(error = ProcessAddressRegistrationTlv(aRxInfo, *child)); } - // Remove from router table router = mRouterTable.FindRouter(extAddr); if (router != nullptr) { - // The `router` here can be invalid RemoveNeighbor(*router); } @@ -2161,11 +2140,9 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) Log(kMessageReceive, kTypeChildUpdateRequestOfChild, aRxInfo.mMessageInfo.GetPeerAddr()); - // Mode SuccessOrExit(error = Tlv::Find<ModeTlv>(aRxInfo.mMessage, modeBitmask)); mode.Set(modeBitmask); - // Challenge switch (aRxInfo.mMessage.ReadChallengeTlv(challenge)) { case kErrorNone: @@ -2218,7 +2195,6 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) tlvList.Add(Tlv::kLinkFrameCounter); } - // IPv6 Address TLV switch (ProcessAddressRegistrationTlv(aRxInfo, *child)) { case kErrorNone: @@ -2230,7 +2206,6 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Leader Data switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)) { case kErrorNone: @@ -2242,7 +2217,6 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Timeout switch (Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout)) { case kErrorNone: @@ -2262,7 +2236,6 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Supervision interval switch (Tlv::Find<SupervisionIntervalTlv>(aRxInfo.mMessage, supervisionInterval)) { case kErrorNone: @@ -2280,7 +2253,6 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) child->SetSupervisionInterval(supervisionInterval); - // TLV Request switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList)) { case kErrorNone: @@ -2390,7 +2362,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) child = static_cast<Child *>(aRxInfo.mNeighbor); - // Response switch (aRxInfo.mMessage.ReadResponseTlv(response)) { case kErrorNone: @@ -2406,7 +2377,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) Log(kMessageReceive, kTypeChildUpdateResponseOfChild, aRxInfo.mMessageInfo.GetPeerAddr(), child->GetRloc16()); - // Source Address switch (Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress)) { case kErrorNone: @@ -2425,7 +2395,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Status switch (Tlv::Find<StatusTlv>(aRxInfo.mMessage, status)) { case kErrorNone: @@ -2437,8 +2406,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Link-Layer Frame Counter - switch (Tlv::Find<LinkFrameCounterTlv>(aRxInfo.mMessage, linkFrameCounter)) { case kErrorNone: @@ -2451,7 +2418,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // MLE Frame Counter switch (Tlv::Find<MleFrameCounterTlv>(aRxInfo.mMessage, mleFrameCounter)) { case kErrorNone: @@ -2463,7 +2429,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(error = kErrorNone); } - // Timeout switch (Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout)) { case kErrorNone: @@ -2490,7 +2455,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) } } - // IPv6 Address switch (ProcessAddressRegistrationTlv(aRxInfo, *child)) { case kErrorNone: @@ -2500,7 +2464,6 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Leader Data switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData)) { case kErrorNone: @@ -2533,10 +2496,8 @@ void MleRouter::HandleDataRequest(RxInfo &aRxInfo) VerifyOrExit(aRxInfo.IsNeighborStateValid(), error = kErrorSecurity); - // TLV Request SuccessOrExit(error = aRxInfo.mMessage.ReadTlvRequestTlv(tlvList)); - // Active Timestamp switch (Tlv::Find<ActiveTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: @@ -2555,7 +2516,6 @@ void MleRouter::HandleDataRequest(RxInfo &aRxInfo) ExitNow(error = kErrorParse); } - // Pending Timestamp switch (Tlv::Find<PendingTimestampTlv>(aRxInfo.mMessage, timestamp)) { case kErrorNone: @@ -2667,7 +2627,6 @@ void MleRouter::HandleDiscoveryRequest(RxInfo &aRxInfo) discoveryRequestTlv.SetLength(0); - // only Routers and REEDs respond VerifyOrExit(IsRouterEligible(), error = kErrorInvalidState); SuccessOrExit(error = Tlv::FindTlvValueStartEndOffsets(aRxInfo.mMessage, Tlv::kDiscovery, offset, end)); @@ -2749,13 +2708,11 @@ Error MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, const M message->SetRadioType(aDiscoverRequestMessage.GetRadioType()); #endif - // Discovery TLV tlv.SetType(Tlv::kDiscovery); SuccessOrExit(error = message->Append(tlv)); startOffset = message->GetLength(); - // Discovery Response TLV discoveryResponseTlv.Init(); discoveryResponseTlv.SetVersion(kThreadVersion); @@ -2780,11 +2737,9 @@ Error MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, const M SuccessOrExit(error = discoveryResponseTlv.AppendTo(*message)); - // Extended PAN ID TLV SuccessOrExit( error = Tlv::Append<MeshCoP::ExtendedPanIdTlv>(*message, Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId())); - // Network Name TLV networkNameTlv.Init(); networkNameTlv.SetNetworkName(Get<MeshCoP::NetworkNameManager>().GetNetworkName().GetAsData()); SuccessOrExit(error = networkNameTlv.AppendTo(*message)); @@ -2825,7 +2780,7 @@ Error MleRouter::SendChildIdResponse(Child &aChild) { uint16_t rloc16; - // pick next Child ID that is not being used + // Pick next Child ID that is not being used do { mNextChildId++; @@ -2839,7 +2794,6 @@ Error MleRouter::SendChildIdResponse(Child &aChild) } while (mChildTable.FindChild(rloc16, Child::kInStateAnyExceptInvalid) != nullptr); - // allocate Child ID aChild.SetRloc16(rloc16); } @@ -2919,14 +2873,16 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild) { if (msg.GetChildMask(childIndex) && msg.GetSubType() == Message::kSubTypeMleChildUpdateRequest) { - // No need to send the resync "Child Update Request" to the sleepy child - // if there is one already queued. + // No need to send the resync "Child Update Request" + // to the sleepy child if there is one already + // queued. if (aChild.IsStateRestoring()) { ExitNow(); } - // Remove queued outdated "Child Update Request" when there is newer Network Data is to send. + // Remove queued outdated "Child Update Request" when + // there is newer Network Data is to send. Get<MeshForwarder>().RemoveMessages(aChild, Message::kSubTypeMleChildUpdateRequest); break; } @@ -3137,10 +3093,8 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination, if (aDelay) { - // Remove MLE Data Responses from Send Message Queue. Get<MeshForwarder>().RemoveDataResponseMessages(); - // Remove multicast MLE Data Response from Delayed Message Queue. RemoveDelayedDataResponseMessage(); SuccessOrExit(error = message->SendAfterDelay(aDestination, aDelay)); @@ -3222,7 +3176,6 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor) if (aNeighbor.IsFullThreadDevice()) { - // Clear all EID-to-RLOC entries associated with the child. Get<AddressResolver>().RemoveEntriesForRloc16(aNeighbor.GetRloc16()); } @@ -3273,11 +3226,9 @@ void MleRouter::ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16) ExitNow(); } - // loop exists router = mRouterTable.FindRouterByRloc16(aDestRloc16); VerifyOrExit(router != nullptr); - // invalidate next hop router->SetNextHopToInvalid(); ResetAdvertiseInterval(); @@ -3297,7 +3248,6 @@ Error MleRouter::CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6He if (aMeshDest == Get<Mac::Mac>().GetShortAddress()) { - // mesh destination is this device if (Get<ThreadNetif>().HasUnicastAddress(aIp6Header.GetDestination())) { // IPv6 destination is this device @@ -3311,15 +3261,14 @@ Error MleRouter::CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6He } else if (RouterIdFromRloc16(aMeshDest) == mRouterId) { - // mesh destination is a child of this device if (mChildTable.FindChild(aMeshDest, Child::kInStateValidOrRestoring)) { + // Mesh destination is a child of this device ExitNow(); } } else if (GetNextHop(aMeshDest) != Mac::kShortAddrInvalid) { - // forwarding to another router and route is known ExitNow(); } @@ -3440,7 +3389,6 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage, SuccessOrExit(Tlv::FindTlv(*aMessage, routerMaskTlv)); VerifyOrExit(routerMaskTlv.IsValid()); - // assign short address SetRouterId(routerId); SetStateRouter(Rloc16FromRouterId(mRouterId)); @@ -3503,7 +3451,6 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage, } exit: - // Send announce after received address solicit reply if needed InformPreviousChannel(); } @@ -3564,7 +3511,6 @@ template <> void MleRouter::HandleTmf<kUriAddressSolicit>(Coap::Message &aMessag } #endif - // Check if allocation already exists router = mRouterTable.FindRouter(extAddress); if (router != nullptr) @@ -3746,13 +3692,11 @@ void MleRouter::FillConnectivityTlv(ConnectivityTlv &aTlv) { if (router.GetRloc16() == GetRloc16()) { - // skip self continue; } if (!router.IsStateValid()) { - // skip non-neighbor routers continue; } |