diff --git a/include/openthread/thread.h b/include/openthread/thread.h index f86efafac84..6c5bf2b5e25 100644 --- a/include/openthread/thread.h +++ b/include/openthread/thread.h @@ -1142,7 +1142,7 @@ uint32_t otThreadGetStoreFrameCounterAhead(otInstance *aInstance); * @param[in] aWakeupIntervalUs An interval between consecutive wake-up frames (in microseconds). * @param[in] aWakeupDurationMs Duration of the wake-up sequence (in milliseconds). * @param[in] aCallback A pointer to function that is called when the wake-up succeeds or fails. - * @param[in] aCallbackContext A pointer to callback application-specific context. + * @param[in] aContext A pointer to callback application-specific context. * * @retval OT_ERROR_NONE Successfully started the wake-up. * @retval OT_ERROR_INVALID_STATE Another attachment request is still in progress. diff --git a/src/core/mac/data_poll_handler.cpp b/src/core/mac/data_poll_handler.cpp index b3d97597007..6eae5d0ae4c 100644 --- a/src/core/mac/data_poll_handler.cpp +++ b/src/core/mac/data_poll_handler.cpp @@ -255,7 +255,7 @@ void DataPollHandler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, OT_ASSERT(false); } - Get().HandleSentFrameToChild(aFrame, mFrameContext, aError, aChild); + Get().HandleSentFrameToCslNeighbor(aFrame, mFrameContext, aError, aChild); exit: return; diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index d5ccae34bfe..d25bba7a1ea 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -2488,15 +2488,15 @@ void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) #endif #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - if (neighbor == nullptr) - { - neighbor = Get().GetWakeupParent(); - VerifyOrExit(neighbor->GetExtAddress() == aSrcAddr.GetExtended()); - } + neighbor = neighbor == nullptr ? Get().GetWakeupParent() : neighbor; #endif VerifyOrExit(neighbor != nullptr); +#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE + VerifyOrExit(neighbor->GetExtAddress() == aSrcAddr.GetExtended()); +#endif + VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod); neighbor->SetCslPeriod(csl->GetPeriod()); diff --git a/src/core/thread/indirect_sender.cpp b/src/core/thread/indirect_sender.cpp index f4e14680413..9945ea6f08f 100644 --- a/src/core/thread/indirect_sender.cpp +++ b/src/core/thread/indirect_sender.cpp @@ -122,6 +122,168 @@ uint16_t IndirectSender::PrepareDataFrame(Mac::TxFrame &aFrame, CslNeighbor &aNe return nextOffset; } +void IndirectSender::HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, const FrameContext &aContext, Error aError, CslNeighbor &aNeighbor) +{ + Message *message = aNeighbor.GetIndirectMessage(); + uint16_t nextOffset = aContext.mMessageNextOffset; + +#if OPENTHREAD_FTD + Child *child = nullptr; +#endif + + VerifyOrExit(mEnabled); + +#if OPENTHREAD_FTD + if (IsChild(aNeighbor)) + { + child = static_cast(&aNeighbor); + } + + if (aError == kErrorNone && child != nullptr) + { + Get().UpdateOnSend(*child); + } + + // A zero `nextOffset` indicates that the sent frame is an empty + // frame generated by `PrepareFrameForChild()` when there was no + // indirect message in the send queue for the child. This can happen + // in the (not common) case where the radio platform does not + // support the "source address match" feature and always includes + // "frame pending" flag in acks to data poll frames. In such a case, + // `IndirectSender` prepares and sends an empty frame to the child + // after it sends a data poll. Here in `HandleSentFrameToCslNeighbor()` we + // exit quickly if we detect the "send done" is for the empty frame + // to ensure we do not update any newly added indirect message after + // preparing the empty frame. + + VerifyOrExit(nextOffset != 0); +#endif // OPENTHREAD_FTD + + switch (aError) + { + case kErrorNone: + break; + + case kErrorNoAck: + case kErrorChannelAccessFailure: + case kErrorAbort: + + aNeighbor.SetIndirectTxSuccess(false); + +#if OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE + // We set the nextOffset to end of message, since there is no need to + // send any remaining fragments in the message to the neighbor, if all tx + // attempts of current frame already failed. + + if (message != nullptr) + { + nextOffset = message->GetLength(); + } +#endif + break; + + default: + OT_ASSERT(false); + } + + if ((message != nullptr) && (nextOffset < message->GetLength())) + { + aNeighbor.SetIndirectFragmentOffset(nextOffset); +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + mCslTxScheduler.Update(); +#endif + ExitNow(); + } + + if (message != nullptr) + { + // The indirect tx of this message to the child is done. + + Error txError = aError; + Mac::Address macDest; + + aNeighbor.SetIndirectMessage(nullptr); + aNeighbor.GetLinkInfo().AddMessageTxStatus(aNeighbor.GetIndirectTxSuccess()); + +#if OPENTHREAD_FTD + if (child != nullptr) + { + // Enable short source address matching after the first indirect + // message transmission attempt to the child. We intentionally do + // not check for successful tx here to address the scenario where + // the child does receive "Child ID Response" but parent misses the + // 15.4 ack from child. If the "Child ID Response" does not make it + // to the child, then the child will need to send a new "Child ID + // Request" which will cause the parent to switch to using long + // address mode for source address matching. + + mSourceMatchController.SetSrcMatchAsShort(*child, true); + } +#endif + +#if !OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE + + // When `CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE` is + // disabled, all fragment frames of a larger message are + // sent even if the transmission of an earlier fragment fail. + // Note that `GetIndirectTxSuccess() tracks the tx success of + // the entire message to the neighbor, while `txError = aError` + // represents the error status of the last fragment frame + // transmission. + + if (!aNeighbor.GetIndirectTxSuccess() && (txError == kErrorNone)) + { + txError = kErrorFailed; + } +#endif + + if (!aFrame.IsEmpty()) + { + IgnoreError(aFrame.GetDstAddr(macDest)); + Get().LogMessage(MeshForwarder::kMessageTransmit, *message, txError, &macDest); + } + + if (message->GetType() == Message::kTypeIp6) + { + if (aNeighbor.GetIndirectTxSuccess()) + { + Get().mIpCounters.mTxSuccess++; + } + else + { + Get().mIpCounters.mTxFailure++; + } + } + +#if OPENTHREAD_FTD + if (child != nullptr) + { + uint16_t childIndex = Get().GetChildIndex(*child); + + if (message->GetIndirectTxChildMask().Has(childIndex)) + { + message->GetIndirectTxChildMask().Remove(childIndex); + mSourceMatchController.DecrementMessageCount(*child); + } + } +#endif + + Get().RemoveMessageIfNoPendingTx(*message); + } + + UpdateIndirectMessage(aNeighbor); + +exit: +#if OPENTHREAD_FTD + if (mEnabled && (child != nullptr)) + { + ClearMessagesForRemovedChildren(); + } +#endif + + return; +} + void IndirectSender::UpdateIndirectMessage(CslNeighbor &aNeighbor) { Message *message = nullptr; @@ -131,10 +293,10 @@ void IndirectSender::UpdateIndirectMessage(CslNeighbor &aNeighbor) { message = FindQueuedMessageForSleepyChild(static_cast(aNeighbor), AcceptAnyMessage); } - else #endif #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE + if (message == nullptr) { message = FindQueuedMessageForWedNeighbor(aNeighbor); } @@ -162,7 +324,7 @@ void IndirectSender::UpdateIndirectMessage(CslNeighbor &aNeighbor) #if OPENTHREAD_FTD bool IndirectSender::IsChild(const Neighbor &aNeighbor) const { - return Get().Contains(static_cast(aNeighbor)); + return Get().Contains(aNeighbor); } void IndirectSender::AddMessageForSleepyChild(Message &aMessage, Child &aChild) @@ -313,7 +475,7 @@ void IndirectSender::RequestMessageUpdate(Child &aChild) if ((curMessage != nullptr) && !curMessage->GetIndirectTxChildMask().Has(Get().GetChildIndex(aChild))) { // Set the indirect message for this child to `nullptr` to ensure - // it is not processed on `HandleSentFrameToChild()` callback. + // it is not processed on `HandleSentFrameToCslNeighbor()` callback. aChild.SetIndirectMessage(nullptr); @@ -392,7 +554,7 @@ Error IndirectSender::PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &a switch (message->GetType()) { case Message::kTypeIp6: - aContext.mMessageNextOffset = PrepareDataFrame(aFrame, aChild, *message); + aContext.mMessageNextOffset = PrepareDataFrameForSleepyChild(aFrame, aChild, *message); break; case Message::kTypeSupervision: @@ -408,16 +570,17 @@ Error IndirectSender::PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &a return error; } -uint16_t IndirectSender::PrepareDataFrame(Mac::TxFrame &aFrame, Child &aChild, Message &aMessage) +uint16_t IndirectSender::PrepareDataFrameForSleepyChild(Mac::TxFrame &aFrame, Child &aChild, Message &aMessage) { uint16_t nextOffset; - nextOffset = PrepareDataFrame(aFrame, static_cast(aChild), aMessage); + nextOffset = PrepareDataFrame(aFrame, aChild, aMessage); // Set `FramePending` if there are more queued messages (excluding // the current one being sent out) for the child (note `> 1` check). // The case where the current message itself requires fragmentation - // is already checked and handled in `PrepareDataFrame()` method. + // is already checked and handled in `PrepareDataFrameForSleepyChild()` + // method. if (aChild.GetIndirectMessageCount() > 1) { @@ -434,145 +597,6 @@ void IndirectSender::PrepareEmptyFrame(Mac::TxFrame &aFrame, Child &aChild, bool Get().PrepareEmptyFrame(aFrame, macDest, aAckRequest); } -void IndirectSender::HandleSentFrameToChild(const Mac::TxFrame &aFrame, - const FrameContext &aContext, - Error aError, - Child &aChild) -{ - Message *message = aChild.GetIndirectMessage(); - uint16_t nextOffset = aContext.mMessageNextOffset; - - VerifyOrExit(mEnabled); - - if (aError == kErrorNone) - { - Get().UpdateOnSend(aChild); - } - - // A zero `nextOffset` indicates that the sent frame is an empty - // frame generated by `PrepareFrameForChild()` when there was no - // indirect message in the send queue for the child. This can happen - // in the (not common) case where the radio platform does not - // support the "source address match" feature and always includes - // "frame pending" flag in acks to data poll frames. In such a case, - // `IndirectSender` prepares and sends an empty frame to the child - // after it sends a data poll. Here in `HandleSentFrameToChild()` we - // exit quickly if we detect the "send done" is for the empty frame - // to ensure we do not update any newly added indirect message after - // preparing the empty frame. - - VerifyOrExit(nextOffset != 0); - - switch (aError) - { - case kErrorNone: - break; - - case kErrorNoAck: - case kErrorChannelAccessFailure: - case kErrorAbort: - - aChild.SetIndirectTxSuccess(false); - -#if OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE - // We set the nextOffset to end of message, since there is no need to - // send any remaining fragments in the message to the child, if all tx - // attempts of current frame already failed. - - if (message != nullptr) - { - nextOffset = message->GetLength(); - } -#endif - break; - - default: - OT_ASSERT(false); - } - - if ((message != nullptr) && (nextOffset < message->GetLength())) - { - aChild.SetIndirectFragmentOffset(nextOffset); -#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - mCslTxScheduler.Update(); -#endif - ExitNow(); - } - - if (message != nullptr) - { - // The indirect tx of this message to the child is done. - - Error txError = aError; - uint16_t childIndex = Get().GetChildIndex(aChild); - Mac::Address macDest; - - aChild.SetIndirectMessage(nullptr); - aChild.GetLinkInfo().AddMessageTxStatus(aChild.GetIndirectTxSuccess()); - - // Enable short source address matching after the first indirect - // message transmission attempt to the child. We intentionally do - // not check for successful tx here to address the scenario where - // the child does receive "Child ID Response" but parent misses the - // 15.4 ack from child. If the "Child ID Response" does not make it - // to the child, then the child will need to send a new "Child ID - // Request" which will cause the parent to switch to using long - // address mode for source address matching. - - mSourceMatchController.SetSrcMatchAsShort(aChild, true); - -#if !OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE - - // When `CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE` is - // disabled, all fragment frames of a larger message are - // sent even if the transmission of an earlier fragment fail. - // Note that `GetIndirectTxSuccess() tracks the tx success of - // the entire message to the child, while `txError = aError` - // represents the error status of the last fragment frame - // transmission. - - if (!aChild.GetIndirectTxSuccess() && (txError == kErrorNone)) - { - txError = kErrorFailed; - } -#endif - - if (!aFrame.IsEmpty()) - { - IgnoreError(aFrame.GetDstAddr(macDest)); - Get().LogMessage(MeshForwarder::kMessageTransmit, *message, txError, &macDest); - } - - if (message->GetType() == Message::kTypeIp6) - { - if (aChild.GetIndirectTxSuccess()) - { - Get().mIpCounters.mTxSuccess++; - } - else - { - Get().mIpCounters.mTxFailure++; - } - } - - if (message->GetIndirectTxChildMask().Has(childIndex)) - { - message->GetIndirectTxChildMask().Remove(childIndex); - mSourceMatchController.DecrementMessageCount(aChild); - } - - Get().RemoveMessageIfNoPendingTx(*message); - } - - UpdateIndirectMessage(aChild); - -exit: - if (mEnabled) - { - ClearMessagesForRemovedChildren(); - } -} - void IndirectSender::ClearMessagesForRemovedChildren(void) { for (Child &child : Get().Iterate(Child::kInStateAnyExceptValidOrRestoring)) @@ -612,6 +636,7 @@ Error IndirectSender::PrepareFrameForEnhCslNeighbor(Mac::TxFrame &aFrame, FrameC { Error error = kErrorNone; Message *message = aNeighbor.GetIndirectMessage(); + VerifyOrExit(message != nullptr, error = kErrorInvalidState); switch (message->GetType()) @@ -646,104 +671,6 @@ Message *IndirectSender::FindQueuedMessageForWedNeighbor(CslNeighbor &aNeighbor) return match; } - -void IndirectSender::HandleSentFrameToWedNeighbor(const Mac::TxFrame &aFrame, - const FrameContext &aContext, - Error aError, - CslNeighbor &aNeighbor) -{ - Message *message = aNeighbor.GetIndirectMessage(); - uint16_t nextOffset = aContext.mMessageNextOffset; - - VerifyOrExit(mEnabled); - - switch (aError) - { - case kErrorNone: - break; - - case kErrorNoAck: - case kErrorChannelAccessFailure: - case kErrorAbort: - - aNeighbor.SetIndirectTxSuccess(false); - -#if OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE - // We set the nextOffset to end of message, since there is no need to - // send any remaining fragments in the message to the neighbor, if all tx - // attempts of current frame already failed. - - if (message != nullptr) - { - nextOffset = message->GetLength(); - } -#endif - break; - - default: - OT_ASSERT(false); - } - - if ((message != nullptr) && (nextOffset < message->GetLength())) - { - aNeighbor.SetIndirectFragmentOffset(nextOffset); -#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - mCslTxScheduler.Update(); -#endif - ExitNow(); - } - - if (message != nullptr) - { - // The indirect tx of this message to the neighbor is done. - - Error txError = aError; - Mac::Address macDest; - - aNeighbor.SetIndirectMessage(nullptr); - aNeighbor.GetLinkInfo().AddMessageTxStatus(aNeighbor.GetIndirectTxSuccess()); - -#if !OPENTHREAD_CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE - - // When `CONFIG_DROP_MESSAGE_ON_FRAGMENT_TX_FAILURE` is - // disabled, all fragment frames of a larger message are - // sent even if the transmission of an earlier fragment fail. - // Note that `GetIndirectTxSuccess() tracks the tx success of - // the entire message to the child, while `txError = aError` - // represents the error status of the last fragment frame - // transmission. - - if (!aNeighbor.GetIndirectTxSuccess() && (txError == kErrorNone)) - { - txError = kErrorFailed; - } -#endif - - if (!aFrame.IsEmpty()) - { - IgnoreError(aFrame.GetDstAddr(macDest)); - Get().LogMessage(MeshForwarder::kMessageTransmit, *message, txError, &macDest); - } - - if (message->GetType() == Message::kTypeIp6) - { - if (aNeighbor.GetIndirectTxSuccess()) - { - Get().mIpCounters.mTxSuccess++; - } - else - { - Get().mIpCounters.mTxFailure++; - } - } - - } - - UpdateIndirectMessage(aNeighbor); - -exit: - return; -} #endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE @@ -774,35 +701,7 @@ Error IndirectSender::PrepareFrameForCslNeighbor(Mac::TxFrame &aFrame, exit: return error; } - -void IndirectSender::HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, - const FrameContext &aContext, - Error aError, - CslNeighbor &aCslNeighbor) -{ -#if OPENTHREAD_FTD - if (IsChild(aCslNeighbor)) - { - HandleSentFrameToChild(aFrame, aContext, aError, static_cast(aCslNeighbor)); - ExitNow(); - } -#endif -#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - HandleSentFrameToWedNeighbor(aFrame, aContext, aError, aCslNeighbor); - ExitNow(); -#else - OT_UNUSED_VARIABLE(aFrame); - OT_UNUSED_VARIABLE(aContext); - OT_UNUSED_VARIABLE(aError); - OT_UNUSED_VARIABLE(aCslNeighbor); - ExitNow(); -#endif - -exit: - return; -} - -#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE +#endif // OPENTHREAD_CONFIG_CSL_TRANSMITTER_ENABLE #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE diff --git a/src/core/thread/indirect_sender.hpp b/src/core/thread/indirect_sender.hpp index 055614b1afa..fbc61e96c21 100644 --- a/src/core/thread/indirect_sender.hpp +++ b/src/core/thread/indirect_sender.hpp @@ -271,14 +271,10 @@ class IndirectSender : public InstanceLocator, public IndirectSenderBase, privat #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE // Callbacks from `CslTxScheduler` Error PrepareFrameForCslNeighbor(Mac::TxFrame &aFrame, FrameContext &aContext, CslNeighbor &aCslNeighbor); - void HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, - const FrameContext &aContext, - Error aError, - CslNeighbor &aCslNeighbor); #endif uint16_t PrepareDataFrame(Mac::TxFrame &aFrame, CslNeighbor &aNeighbor, Message &aMessage); - void HandleSentFrameToNeighbor(const Mac::TxFrame &aFrame, const FrameContext &aContext, Error aError, CslNeighbor &aNeighbor); + void HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, const FrameContext &aContext, Error aError, CslNeighbor &aNeighbor); void UpdateIndirectMessage(CslNeighbor &aNeighbor); #if OPENTHREAD_FTD @@ -286,11 +282,10 @@ class IndirectSender : public InstanceLocator, public IndirectSenderBase, privat // Callbacks from `DataPollHandler` Error PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &aContext, Child &aChild); - void HandleSentFrameToChild(const Mac::TxFrame &aFrame, const FrameContext &aContext, Error aError, Child &aChild); void HandleFrameChangeDone(Child &aChild); void RequestMessageUpdate(Child &aChild); - uint16_t PrepareDataFrame(Mac::TxFrame &aFrame, Child &aChild, Message &aMessage); + uint16_t PrepareDataFrameForSleepyChild(Mac::TxFrame &aFrame, Child &aChild, Message &aMessage); void PrepareEmptyFrame(Mac::TxFrame &aFrame, Child &aChild, bool aAckRequest); void ClearMessagesForRemovedChildren(void); @@ -302,10 +297,6 @@ class IndirectSender : public InstanceLocator, public IndirectSenderBase, privat #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE Error PrepareFrameForEnhCslNeighbor(Mac::TxFrame &aFrame, FrameContext &aContext, CslNeighbor &aNeighbor); Message *FindQueuedMessageForWedNeighbor(CslNeighbor &aNeighbor); - void HandleSentFrameToWedNeighbor(const Mac::TxFrame &aFrame, - const FrameContext &aContext, - Error aError, - CslNeighbor &aNeighbor); #endif bool mEnabled; diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 40af59bc666..af6b7a5312c 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -45,22 +45,11 @@ void MeshForwarder::SendMessage(OwnedPtr aMessagePtr) { Message &message = *aMessagePtr.Release(); -#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - CslNeighbor *cslNeighbor = Get().GetWakeupParent(); - - if ((cslNeighbor != nullptr) && cslNeighbor->IsCslSynchronized()) - { - mIndirectSender.AddMessageForEnhCslNeighbor(message, *cslNeighbor); - } - else -#endif - { - message.SetOffset(0); - message.SetDatagramTag(0); - message.SetTimestampToNow(); - } + message.SetOffset(0); + message.SetDatagramTag(0); + message.SetTimestampToNow(); -mSendQueue.Enqueue(message); + mSendQueue.Enqueue(message); switch (message.GetType()) { @@ -99,12 +88,33 @@ mSendQueue.Enqueue(message); mIndirectSender.AddMessageForSleepyChild(message, child); } } + +#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE + if (destinedForAll) + { + CslNeighbor *cslNeighbor = Get().GetWakeupParent(); + + if ((cslNeighbor != nullptr) && cslNeighbor->IsCslSynchronized()) + { + mIndirectSender.AddMessageForEnhCslNeighbor(message, *cslNeighbor); + } + } +#endif } } else // Destination is unicast { Neighbor *neighbor = Get().FindNeighbor(destination); +#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE + CslNeighbor *cslNeighbor = Get().GetWakeupParent(); + + if ((neighbor == nullptr) && (cslNeighbor != nullptr) && cslNeighbor->IsCslSynchronized()) + { + mIndirectSender.AddMessageForEnhCslNeighbor(message, *cslNeighbor); + } + else +#endif if ((neighbor != nullptr) && !neighbor->IsRxOnWhenIdle() && !message.IsDirectTransmission() && Get().Contains(*neighbor)) { diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 936fbf92ff1..a5c358744cb 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1386,7 +1386,7 @@ Error Mle::DetermineParentRequestType(ParentRequestType &aType) const #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE if (IsWakeupParentPresent()) { - aType = kToWakeupParent; + aType = kToWakeupCoordinator; VerifyOrExit(TimerMilli::GetNow() < mWakeupParentAttachTime + mWakeupParentAttachWindow, error = kErrorNotFound); ExitNow(); @@ -1570,7 +1570,7 @@ void Mle::HandleAttachTimer(void) delay = kParentRequestReedTimeout; break; #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - case kToWakeupParent: + case kToWakeupCoordinator: delay = kWakeupParentParentRespTimeout; delay += mWakeupParentAttachTime + mWakeupParentAttachWindow - TimerMilli::GetNow(); break; @@ -1745,7 +1745,7 @@ void Mle::SendParentRequest(ParentRequestType aType) break; #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - case kToWakeupParent: + case kToWakeupCoordinator: scanMask = ScanMaskTlv::kRouterFlag | ScanMaskTlv::kEndDeviceFlag; break; #endif @@ -1783,7 +1783,7 @@ void Mle::SendParentRequest(ParentRequestType aType) else #endif #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - if (aType == kToWakeupParent) + if (aType == kToWakeupCoordinator) { destination.SetToLinkLocalAddress(GetWakeupParent()->GetExtAddress()); SuccessOrExit(error = message->AppendCslClockAccuracyTlv()); @@ -1808,7 +1808,7 @@ void Mle::SendParentRequest(ParentRequestType aType) break; #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - case kToWakeupParent: + case kToWakeupCoordinator: Log(kMessageSend, kTypeParentRequestToWakeupCoord, destination); LogInfo("Sent Parent Request FC: %lu", ToUlong(Get().GetMleFrameCounter() - 1)); break; diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index c6c18c2f26e..0cbfd14ef0c 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -761,7 +761,7 @@ class Mle : public InstanceLocator, private NonCopyable * @retval TRUE If the Thread interface is communicating to a Wake-up Parent. * @retval FALSE If the Thread interface is not communicating to a Wake-up Parent. */ - bool IsWakeupParentPresent() const { return mWakeupParentAttachWindow > 0; } + bool IsWakeupParentPresent(void) const { return mWakeupParentAttachWindow > 0; } /** * Adds a Wake-up Parent to the list of potential parents. @@ -793,6 +793,7 @@ class Mle : public InstanceLocator, private NonCopyable // All time intervals are in milliseconds static constexpr uint32_t kParentRequestRouterTimeout = 750; // Wait time after tx of Parent Req to routers static constexpr uint32_t kParentRequestReedTimeout = 1250; // Wait timer after tx of Parent Req to REEDs + static constexpr uint32_t kWakeupParentParentRespTimeout = 500; // Max delay for receiving a Parent Response from WC static constexpr uint32_t kParentRequestDuplicateMargin = 50; // Margin to detect duplicate received Parent Req static constexpr uint32_t kChildIdResponseTimeout = 1250; // Wait time to receive Child ID Response static constexpr uint32_t kAttachStartJitter = 50; // Max jitter time added to start of attach @@ -923,7 +924,7 @@ class Mle : public InstanceLocator, private NonCopyable kToRoutersAndReeds, // Parent Request to all routers and REEDs. kToSelectedRouter, // Parent Request to a selected router (e.g., by `ParentSearch` module). #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE - kToWakeupParent, // Parent Request unicast to a known Wake-up Parent device. + kToWakeupCoordinator, // Unicast Parent Request to a known Wake-up Coordinator device. #endif }; diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index c266b999e25..8557c0e56b5 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -76,7 +76,6 @@ namespace Mle { constexpr uint16_t kUdpPort = 19788; ///< MLE UDP Port constexpr uint16_t kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN; ///< Maximum number of children -constexpr uint32_t kWakeupParentParentRespTimeout = 500; ///< Max delay for receiving a Parent Response from WC (ms) constexpr uint16_t kMinChildId = 1; ///< Minimum Child ID constexpr uint16_t kMaxChildId = 511; ///< Maximum Child ID constexpr uint8_t kMaxRouters = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS; ///< Maximum number of routers