[message] simplify accessing of indirect tx ChildMask bit-set (#10824)

This commit renames the `BitVector<>` class to `BitSet<>` and updates
its methods, introducing simpler methods such as `Add()`, `Remove()`,
and `IsEmpty()`. This aligns better with the intended use of this
class as a bit-set, e.g., as a `ChildMask` to track the set of
sleepy children to which a message is scheduled for indirect
transmission.

The `Message` class now provides the `GetIndirectTxChildMask()`
method, which returns a reference to the `ChildMask` bit-set.
This commit is contained in:
Abtin Keshavarzian
2024-10-14 12:12:09 -07:00
committed by GitHub
parent 358b0a3e18
commit 072e53740b
12 changed files with 197 additions and 210 deletions
+1 -1
View File
@@ -391,7 +391,7 @@ openthread_core_files = [
"common/as_core_type.hpp",
"common/binary_search.cpp",
"common/binary_search.hpp",
"common/bit_vector.hpp",
"common/bit_set.hpp",
"common/callback.hpp",
"common/clearable.hpp",
"common/code_utils.hpp",
+140
View File
@@ -0,0 +1,140 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for a bit-set.
*/
#ifndef BIT_SET_HPP_
#define BIT_SET_HPP_
#include "openthread-core-config.h"
#include "common/clearable.hpp"
#include "common/equatable.hpp"
#include "common/numeric_limits.hpp"
namespace ot {
/**
* @addtogroup core-bit-set
*
* @brief
* This module includes definitions for bit-set.
*
* @{
*/
/**
* Represents a bit-set.
*
* @tparam kNumBits Specifies the number of bits.
*/
template <uint16_t kNumBits> class BitSet : public Equatable<BitSet<kNumBits>>, public Clearable<BitSet<kNumBits>>
{
public:
/**
* Indicates whether a given bit index is contained in the set.
*
* The caller MUST ensure that @p aIndex is smaller than `kNumBits`. Otherwise, the behavior of this method is
* undefined.
*
* @param[in] aIndex The bit index to check
*
* @retval TRUE If the bit index @p aIndex is contained in the set.
* @retval FALSE If the bit index @p aIndex is not contained in the set.
*/
bool Has(uint16_t aIndex) const { return (mMask[aIndex / 8] & BitMaskFor(aIndex)) != 0; }
/**
* Adds the given bit index to the set.
*
* The caller MUST ensure that @p aIndex is smaller than `kNumBits`. Otherwise, the behavior of this method is
* undefined.
*
* @param[in] aIndex The bit index to add.
*/
void Add(uint16_t aIndex) { mMask[aIndex / 8] |= BitMaskFor(aIndex); }
/**
* Removes the given bit index from the set.
*
* The caller MUST ensure that @p aIndex is smaller than `kNumBits`. Otherwise, the behavior of this method is
* undefined.
*
* @param[in] aIndex The bit index to remove.
*/
void Remove(uint16_t aIndex) { mMask[aIndex / 8] &= ~BitMaskFor(aIndex); }
/**
* Updates the set by either adding or removing the given bit index.
*
* The caller MUST ensure that @p aIndex is smaller than `kNumBits`. Otherwise, the behavior of this method is
* undefined.
*
* @param[in] aIndex The bit index.
* @param[in] aToAdd Boolean indicating whether to add (when set to TRUE) or to remove (when set to FALSE).
*/
void Update(uint16_t aIndex, bool aToAdd) { aToAdd ? Add(aIndex) : Remove(aIndex); }
/**
* Indicates whether or not the set is empty.
*
* @retval TRUE If the set is empty.
* @retval FALSE If the set is not empty.
*/
bool IsEmpty(void) const
{
bool isEmpty = true;
for (uint8_t byte : mMask)
{
if (byte != 0)
{
isEmpty = false;
break;
}
}
return isEmpty;
}
private:
static uint8_t BitMaskFor(uint16_t aIndex) { return (0x80 >> (aIndex & 7)); }
uint8_t mMask[BytesForBitSize(kNumBits)];
};
/**
* @}
*/
} // namespace ot
#endif // BIT_SET_HPP_
-130
View File
@@ -1,130 +0,0 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for a bit-vector.
*/
#ifndef BIT_VECTOR_HPP_
#define BIT_VECTOR_HPP_
#include "openthread-core-config.h"
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "common/numeric_limits.hpp"
namespace ot {
/**
* @addtogroup core-bit-vector
*
* @brief
* This module includes definitions for bit-vector.
*
* @{
*/
/**
* Represents a bit-vector.
*
* @tparam N Specifies the number of bits.
*/
template <uint16_t N> class BitVector : public Equatable<BitVector<N>>, public Clearable<BitVector<N>>
{
public:
/**
* Indicates whether a given index is included in the mask.
*
* @param[in] aIndex The index.
*
* @retval TRUE If the given index is set.
* @retval FALSE If the given index is clear.
*/
bool Get(uint16_t aIndex) const
{
OT_ASSERT(aIndex < N);
return (mMask[aIndex / 8] & (0x80 >> (aIndex % 8))) != 0;
}
/**
* Sets the mask of a given index.
*
* @param[in] aIndex The index.
* @param[in] aValue TRUE to set the mask, or FALSE to clear the mask.
*/
void Set(uint16_t aIndex, bool aValue)
{
OT_ASSERT(aIndex < N);
if (aValue)
{
mMask[aIndex / 8] |= 0x80 >> (aIndex % 8);
}
else
{
mMask[aIndex / 8] &= ~(0x80 >> (aIndex % 8));
};
}
/**
* Returns if any mask is set.
*
* @retval TRUE If any index is set.
* @retval FALSE If all indexes are clear.
*/
bool HasAny(void) const
{
bool rval = false;
for (uint8_t b : mMask)
{
if (b != 0)
{
ExitNow(rval = true);
}
}
exit:
return rval;
}
private:
uint8_t mMask[BytesForBitSize(N)];
};
/**
* @}
*/
} // namespace ot
#endif // BIT_VECTOR_HPP_
-10
View File
@@ -792,16 +792,6 @@ exit:
return messageCopy;
}
#if OPENTHREAD_FTD
bool Message::GetChildMask(uint16_t aChildIndex) const { return GetMetadata().mChildMask.Get(aChildIndex); }
void Message::ClearChildMask(uint16_t aChildIndex) { GetMetadata().mChildMask.Set(aChildIndex, false); }
void Message::SetChildMask(uint16_t aChildIndex) { GetMetadata().mChildMask.Set(aChildIndex, true); }
bool Message::IsChildPending(void) const { return GetMetadata().mChildMask.HasAny(); }
#endif
Error Message::GetLinkInfo(ThreadLinkInfo &aLinkInfo) const
{
Error error = kErrorNone;
+9 -23
View File
@@ -1053,37 +1053,23 @@ public:
#if OPENTHREAD_FTD
/**
* Returns whether or not the message forwarding is scheduled for the child.
* Gets the indirect transmission `ChildMask` associated with this `Message`.
*
* @param[in] aChildIndex The index into the child table.
* The `ChildMask` indicates the set of children for which this message is scheduled for indirect transmission.
*
* @retval TRUE If the message is scheduled to be forwarded to the child.
* @retval FALSE If the message is not scheduled to be forwarded to the child.
* @returns A reference to the indirect transmission `ChildMask`.
*/
bool GetChildMask(uint16_t aChildIndex) const;
ChildMask &GetIndirectTxChildMask(void) { return GetMetadata().mChildMask; }
/**
* Unschedules forwarding of the message to the child.
* Gets the indirect transmission `ChildMask` associated with this `Message`.
*
* @param[in] aChildIndex The index into the child table.
*/
void ClearChildMask(uint16_t aChildIndex);
/**
* Schedules forwarding of the message to the child.
* The `ChildMask` indicates the set of children for which this message is scheduled for indirect transmission.
*
* @param[in] aChildIndex The index into the child table.
* @returns A reference to the indirect transmission `ChildMask`.
*/
void SetChildMask(uint16_t aChildIndex);
/**
* Returns whether or not the message forwarding is scheduled for at least one child.
*
* @retval TRUE If message forwarding is scheduled for at least one child.
* @retval FALSE If message forwarding is not scheduled for any child.
*/
bool IsChildPending(void) const;
#endif // OPENTHREAD_FTD
const ChildMask &GetIndirectTxChildMask(void) const { return GetMetadata().mChildMask; }
#endif
/**
* Returns the RLOC16 of the mesh destination.
+10 -10
View File
@@ -87,11 +87,11 @@ MlrState Child::Ip6AddrEntry::GetMlrState(const Child &aChild) const
index = aChild.mIp6Addresses.IndexOf(*this);
if (aChild.mMlrToRegisterMask.Get(index))
if (aChild.mMlrToRegisterSet.Has(index))
{
state = kMlrStateToRegister;
}
else if (aChild.mMlrRegisteredMask.Get(index))
else if (aChild.mMlrRegisteredSet.Has(index))
{
state = kMlrStateRegistered;
}
@@ -108,8 +108,8 @@ void Child::Ip6AddrEntry::SetMlrState(MlrState aState, Child &aChild)
index = aChild.mIp6Addresses.IndexOf(*this);
aChild.mMlrToRegisterMask.Set(index, aState == kMlrStateToRegister);
aChild.mMlrRegisteredMask.Set(index, aState == kMlrStateRegistered);
aChild.mMlrToRegisterSet.Update(index, aState == kMlrStateToRegister);
aChild.mMlrRegisteredSet.Update(index, aState == kMlrStateRegistered);
}
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
@@ -130,8 +130,8 @@ void Child::ClearIp6Addresses(void)
mMeshLocalIid.Clear();
mIp6Addresses.Clear();
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
mMlrToRegisterMask.Clear();
mMlrRegisteredMask.Clear();
mMlrToRegisterSet.Clear();
mMlrRegisteredSet.Clear();
#endif
}
@@ -232,11 +232,11 @@ Error Child::RemoveIp6Address(const Ip6::Address &aAddress)
uint16_t entryIndex = mIp6Addresses.IndexOf(*entry);
uint16_t lastIndex = mIp6Addresses.GetLength() - 1;
mMlrToRegisterMask.Set(entryIndex, mMlrToRegisterMask.Get(lastIndex));
mMlrToRegisterMask.Set(lastIndex, false);
mMlrToRegisterSet.Update(entryIndex, mMlrToRegisterSet.Has(lastIndex));
mMlrToRegisterSet.Remove(lastIndex);
mMlrRegisteredMask.Set(entryIndex, mMlrRegisteredMask.Get(lastIndex));
mMlrRegisteredMask.Set(lastIndex, false);
mMlrRegisteredSet.Update(entryIndex, mMlrRegisteredSet.Has(lastIndex));
mMlrRegisteredSet.Remove(lastIndex);
}
#endif
+6 -5
View File
@@ -36,6 +36,7 @@
#include "openthread-core-config.h"
#include "common/bit_set.hpp"
#include "thread/neighbor.hpp"
namespace ot {
@@ -358,7 +359,7 @@ public:
* @retval true If the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
* @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`.
*/
bool HasAnyMlrRegisteredAddress(void) const { return mMlrRegisteredMask.HasAny(); }
bool HasAnyMlrRegisteredAddress(void) const { return !mMlrRegisteredSet.IsEmpty(); }
/**
* Returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
@@ -366,19 +367,19 @@ public:
* @retval true If the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
* @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`.
*/
bool HasAnyMlrToRegisterAddress(void) const { return mMlrToRegisterMask.HasAny(); }
bool HasAnyMlrToRegisterAddress(void) const { return !mMlrToRegisterSet.IsEmpty(); }
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
private:
typedef BitVector<kNumIp6Addresses> ChildIp6AddressMask;
typedef BitSet<kNumIp6Addresses> ChildIp6AddressSet;
uint32_t mTimeout;
Ip6::InterfaceIdentifier mMeshLocalIid;
Ip6AddressArray mIp6Addresses;
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
ChildIp6AddressMask mMlrToRegisterMask;
ChildIp6AddressMask mMlrRegisteredMask;
ChildIp6AddressSet mMlrToRegisterSet;
ChildIp6AddressSet mMlrRegisteredSet;
#endif
uint8_t mNetworkDataVersion;
+3 -3
View File
@@ -36,7 +36,7 @@
#include "openthread-core-config.h"
#include "common/bit_vector.hpp"
#include "common/bit_set.hpp"
namespace ot {
@@ -50,9 +50,9 @@ namespace ot {
*/
/**
* Represents a bit-vector of child mask.
* Represents a bit-set of child mask.
*/
typedef BitVector<OPENTHREAD_CONFIG_MLE_MAX_CHILDREN> ChildMask;
typedef BitSet<OPENTHREAD_CONFIG_MLE_MAX_CHILDREN> ChildMask;
/**
* @}
+15 -15
View File
@@ -81,7 +81,7 @@ void DuaManager::HandleDomainPrefixUpdate(BackboneRouter::DomainPrefixEvent aEve
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
if (mChildDuaMask.HasAny())
if (!mChildDuaMask.IsEmpty())
{
mChildDuaMask.Clear();
mChildDuaRegisteredMask.Clear();
@@ -451,7 +451,7 @@ void DuaManager::PerformNextRegistration(void)
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
needReg = needReg || (mChildDuaMask.HasAny() && mChildDuaMask != mChildDuaRegisteredMask);
needReg = needReg || (!mChildDuaMask.IsEmpty() && mChildDuaMask != mChildDuaRegisteredMask);
#endif
VerifyOrExit(needReg, error = kErrorNotFound);
}
@@ -482,7 +482,7 @@ void DuaManager::PerformNextRegistration(void)
{
uint16_t childIndex = Get<ChildTable>().GetChildIndex(iter);
if (mChildDuaMask.Get(childIndex) && !mChildDuaRegisteredMask.Get(childIndex))
if (mChildDuaMask.Has(childIndex) && !mChildDuaRegisteredMask.Has(childIndex))
{
mChildIndexDuaRegistering = childIndex;
break;
@@ -677,21 +677,21 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage)
{
case ThreadStatusTlv::kDuaSuccess:
// Mark as Registered
if (mChildDuaMask.Get(childIndex))
if (mChildDuaMask.Has(childIndex))
{
mChildDuaRegisteredMask.Set(childIndex, true);
mChildDuaRegisteredMask.Add(childIndex);
}
break;
case ThreadStatusTlv::kDuaReRegister:
// Parent stops registering for the Child's DUA until next Child Update Request
mChildDuaMask.Set(childIndex, false);
mChildDuaRegisteredMask.Set(childIndex, false);
mChildDuaMask.Remove(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
break;
case ThreadStatusTlv::kDuaInvalid:
case ThreadStatusTlv::kDuaDuplicate:
IgnoreError(child->RemoveIp6Address(target));
mChildDuaMask.Set(childIndex, false);
mChildDuaRegisteredMask.Set(childIndex, false);
mChildDuaMask.Remove(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
break;
case ThreadStatusTlv::kDuaNoResources:
case ThreadStatusTlv::kDuaNotPrimary:
@@ -750,7 +750,7 @@ void DuaManager::HandleChildDuaAddressEvent(const Child &aChild, ChildDuaAddress
{
uint16_t childIndex = Get<ChildTable>().GetChildIndex(aChild);
if ((aEvent == kAddressRemoved || aEvent == kAddressChanged) && mChildDuaMask.Get(childIndex))
if ((aEvent == kAddressRemoved || aEvent == kAddressChanged) && mChildDuaMask.Has(childIndex))
{
// Abort on going proxy DUA.req for this child
if (mChildIndexDuaRegistering == childIndex)
@@ -758,20 +758,20 @@ void DuaManager::HandleChildDuaAddressEvent(const Child &aChild, ChildDuaAddress
IgnoreError(Get<Tmf::Agent>().AbortTransaction(&DuaManager::HandleDuaResponse, this));
}
mChildDuaMask.Set(childIndex, false);
mChildDuaRegisteredMask.Set(childIndex, false);
mChildDuaMask.Remove(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
}
if (aEvent == kAddressAdded || aEvent == kAddressChanged ||
(aEvent == kAddressUnchanged && !mChildDuaMask.Get(childIndex)))
(aEvent == kAddressUnchanged && !mChildDuaMask.Has(childIndex)))
{
if (mChildDuaMask == mChildDuaRegisteredMask)
{
UpdateCheckDelay(Random::NonCrypto::GetUint8InRange(1, BackboneRouter::kParentAggregateDelay));
}
mChildDuaMask.Set(childIndex, true);
mChildDuaRegisteredMask.Set(childIndex, false);
mChildDuaMask.Add(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
}
}
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
+11 -11
View File
@@ -90,9 +90,9 @@ void IndirectSender::AddMessageForSleepyChild(Message &aMessage, Child &aChild)
OT_ASSERT(!aChild.IsRxOnWhenIdle());
childIndex = Get<ChildTable>().GetChildIndex(aChild);
VerifyOrExit(!aMessage.GetChildMask(childIndex));
VerifyOrExit(!aMessage.GetIndirectTxChildMask().Has(childIndex));
aMessage.SetChildMask(childIndex);
aMessage.GetIndirectTxChildMask().Add(childIndex);
mSourceMatchController.IncrementMessageCount(aChild);
if ((aMessage.GetType() != Message::kTypeSupervision) && (aChild.GetIndirectMessageCount() > 1))
@@ -117,9 +117,9 @@ Error IndirectSender::RemoveMessageFromSleepyChild(Message &aMessage, Child &aCh
Error error = kErrorNone;
uint16_t childIndex = Get<ChildTable>().GetChildIndex(aChild);
VerifyOrExit(aMessage.GetChildMask(childIndex), error = kErrorNotFound);
VerifyOrExit(aMessage.GetIndirectTxChildMask().Has(childIndex), error = kErrorNotFound);
aMessage.ClearChildMask(childIndex);
aMessage.GetIndirectTxChildMask().Remove(childIndex);
mSourceMatchController.DecrementMessageCount(aChild);
RequestMessageUpdate(aChild);
@@ -134,7 +134,7 @@ void IndirectSender::ClearAllMessagesForSleepyChild(Child &aChild)
for (Message &message : Get<MeshForwarder>().mSendQueue)
{
message.ClearChildMask(Get<ChildTable>().GetChildIndex(aChild));
message.GetIndirectTxChildMask().Remove(Get<ChildTable>().GetChildIndex(aChild));
Get<MeshForwarder>().RemoveMessageIfNoPendingTx(message);
}
@@ -158,7 +158,7 @@ const Message *IndirectSender::FindQueuedMessageForSleepyChild(const Child &aChi
for (const Message &message : Get<MeshForwarder>().mSendQueue)
{
if (message.GetChildMask(childIndex) && aChecker(message))
if (message.GetIndirectTxChildMask().Has(childIndex) && aChecker(message))
{
match = &message;
break;
@@ -194,9 +194,9 @@ void IndirectSender::HandleChildModeChange(Child &aChild, Mle::DeviceMode aOldMo
for (Message &message : Get<MeshForwarder>().mSendQueue)
{
if (message.GetChildMask(childIndex))
if (message.GetIndirectTxChildMask().Has(childIndex))
{
message.ClearChildMask(childIndex);
message.GetIndirectTxChildMask().Remove(childIndex);
message.SetDirectTransmission();
}
}
@@ -228,7 +228,7 @@ void IndirectSender::RequestMessageUpdate(Child &aChild)
// case where we have a pending "replace frame" request and while
// waiting for the callback, the current message is removed.
if ((curMessage != nullptr) && !curMessage->GetChildMask(Get<ChildTable>().GetChildIndex(aChild)))
if ((curMessage != nullptr) && !curMessage->GetIndirectTxChildMask().Has(Get<ChildTable>().GetChildIndex(aChild)))
{
// Set the indirect message for this child to `nullptr` to ensure
// it is not processed on `HandleSentFrameToChild()` callback.
@@ -523,9 +523,9 @@ void IndirectSender::HandleSentFrameToChild(const Mac::TxFrame &aFrame,
}
}
if (message->GetChildMask(childIndex))
if (message->GetIndirectTxChildMask().Has(childIndex))
{
message->ClearChildMask(childIndex);
message->GetIndirectTxChildMask().Remove(childIndex);
mSourceMatchController.DecrementMessageCount(aChild);
}
+1 -1
View File
@@ -1366,7 +1366,7 @@ bool MeshForwarder::RemoveMessageIfNoPendingTx(Message &aMessage)
bool didRemove = false;
#if OPENTHREAD_FTD
VerifyOrExit(!aMessage.IsDirectTransmission() && !aMessage.IsChildPending());
VerifyOrExit(!aMessage.IsDirectTransmission() && aMessage.GetIndirectTxChildMask().IsEmpty());
#else
VerifyOrExit(!aMessage.IsDirectTransmission());
#endif
+1 -1
View File
@@ -244,7 +244,7 @@ Error MeshForwarder::EvictMessage(Message::Priority aPriority)
continue;
}
if (message->IsChildPending())
if (!message->GetIndirectTxChildMask().IsEmpty())
{
evict = message;
ExitNow(error = kErrorNone);