mirror of
https://github.com/espressif/openthread.git
synced 2026-09-06 17:20:09 +00:00
[topology] adding 'Neighbor::AddressMatcher' (#5354)
This commit adds new a type `Neighbor::AddressMactehr` which is used to filter and find a neighbor (child/router) with a given MAC address matching a given `Neighbor::StateFilter`. This new type helps simplify related code in `ChildTable`/`RouterTbale`.
This commit is contained in:
committed by
Jonathan Hui
parent
5bac12f9d6
commit
6c75a53bdc
@@ -105,13 +105,23 @@ exit:
|
||||
|
||||
Child *ChildTable::GetNewChild(void)
|
||||
{
|
||||
Child *child = mChildren;
|
||||
Child *child = FindChild(Child::AddressMatcher(Child::kInStateInvalid));
|
||||
|
||||
VerifyOrExit(child != nullptr, OT_NOOP);
|
||||
child->Clear();
|
||||
|
||||
exit:
|
||||
return child;
|
||||
}
|
||||
|
||||
const Child *ChildTable::FindChild(const Child::AddressMatcher &aMatcher) const
|
||||
{
|
||||
const Child *child = mChildren;
|
||||
|
||||
for (uint16_t num = mMaxChildrenAllowed; num != 0; num--, child++)
|
||||
{
|
||||
if (child->IsStateInvalid())
|
||||
if (child->Matches(aMatcher))
|
||||
{
|
||||
child->Clear();
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
@@ -124,76 +134,22 @@ exit:
|
||||
|
||||
Child *ChildTable::FindChild(uint16_t aRloc16, Child::StateFilter aFilter)
|
||||
{
|
||||
Child *child = mChildren;
|
||||
|
||||
for (uint16_t num = mMaxChildrenAllowed; num != 0; num--, child++)
|
||||
{
|
||||
if (child->MatchesFilter(aFilter) && (child->GetRloc16() == aRloc16))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
child = nullptr;
|
||||
|
||||
exit:
|
||||
return child;
|
||||
return FindChild(Child::AddressMatcher(aRloc16, aFilter));
|
||||
}
|
||||
|
||||
Child *ChildTable::FindChild(const Mac::ExtAddress &aAddress, Child::StateFilter aFilter)
|
||||
Child *ChildTable::FindChild(const Mac::ExtAddress &aExtAddress, Child::StateFilter aFilter)
|
||||
{
|
||||
Child *child = mChildren;
|
||||
|
||||
for (uint16_t num = mMaxChildrenAllowed; num != 0; num--, child++)
|
||||
{
|
||||
if (child->MatchesFilter(aFilter) && (child->GetExtAddress() == aAddress))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
child = nullptr;
|
||||
|
||||
exit:
|
||||
return child;
|
||||
return FindChild(Child::AddressMatcher(aExtAddress, aFilter));
|
||||
}
|
||||
|
||||
Child *ChildTable::FindChild(const Mac::Address &aAddress, Child::StateFilter aFilter)
|
||||
Child *ChildTable::FindChild(const Mac::Address &aMacAddress, Child::StateFilter aFilter)
|
||||
{
|
||||
Child *child = nullptr;
|
||||
|
||||
switch (aAddress.GetType())
|
||||
{
|
||||
case Mac::Address::kTypeShort:
|
||||
child = FindChild(aAddress.GetShort(), aFilter);
|
||||
break;
|
||||
|
||||
case Mac::Address::kTypeExtended:
|
||||
child = FindChild(aAddress.GetExtended(), aFilter);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return child;
|
||||
return FindChild(Child::AddressMatcher(aMacAddress, aFilter));
|
||||
}
|
||||
|
||||
bool ChildTable::HasChildren(Child::StateFilter aFilter) const
|
||||
{
|
||||
bool rval = false;
|
||||
const Child *child = mChildren;
|
||||
|
||||
for (uint16_t num = mMaxChildrenAllowed; num != 0; num--, child++)
|
||||
{
|
||||
if (child->MatchesFilter(aFilter))
|
||||
{
|
||||
ExitNow(rval = true);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
return (FindChild(Child::AddressMatcher(aFilter)) != nullptr);
|
||||
}
|
||||
|
||||
uint16_t ChildTable::GetNumChildren(Child::StateFilter aFilter) const
|
||||
|
||||
@@ -397,7 +397,13 @@ private:
|
||||
Child::StateFilter mFilter;
|
||||
};
|
||||
|
||||
void RefreshStoredChildren(void);
|
||||
Child *FindChild(const Child::AddressMatcher &aMatcher)
|
||||
{
|
||||
return const_cast<Child *>(const_cast<const ChildTable *>(this)->FindChild(aMatcher));
|
||||
}
|
||||
|
||||
const Child *FindChild(const Child::AddressMatcher &aMatcher) const;
|
||||
void RefreshStoredChildren(void);
|
||||
|
||||
uint16_t mMaxChildrenAllowed;
|
||||
Child mChildren[kMaxChildren];
|
||||
|
||||
@@ -342,19 +342,27 @@ uint8_t RouterTable::GetActiveLinkCount(void) const
|
||||
return activeLinks;
|
||||
}
|
||||
|
||||
const Router *RouterTable::FindRouter(const Router::AddressMatcher &aMatcher) const
|
||||
{
|
||||
const Router *router;
|
||||
|
||||
for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
|
||||
{
|
||||
if (router->Matches(aMatcher))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
Router *RouterTable::GetNeighbor(uint16_t aRloc16)
|
||||
{
|
||||
Router *router = nullptr;
|
||||
|
||||
VerifyOrExit(aRloc16 != Get<Mle::MleRouter>().GetRloc16(), OT_NOOP);
|
||||
|
||||
for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
|
||||
{
|
||||
if (router->IsStateValid() && router->GetRloc16() == aRloc16)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
router = FindRouter(Router::AddressMatcher(aRloc16, Router::kInStateValid));
|
||||
|
||||
exit:
|
||||
return router;
|
||||
@@ -362,20 +370,7 @@ exit:
|
||||
|
||||
Router *RouterTable::GetNeighbor(const Mac::ExtAddress &aExtAddress)
|
||||
{
|
||||
Router *router = nullptr;
|
||||
|
||||
VerifyOrExit(aExtAddress != Get<Mac::Mac>().GetExtAddress(), OT_NOOP);
|
||||
|
||||
for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
|
||||
{
|
||||
if (router->IsStateValid() && router->GetExtAddress() == aExtAddress)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return router;
|
||||
return FindRouter(Router::AddressMatcher(aExtAddress, Router::kInStateValid));
|
||||
}
|
||||
|
||||
const Router *RouterTable::GetRouter(uint8_t aRouterId) const
|
||||
@@ -387,14 +382,7 @@ const Router *RouterTable::GetRouter(uint8_t aRouterId) const
|
||||
VerifyOrExit(aRouterId < Mle::kInvalidRouterId, OT_NOOP);
|
||||
|
||||
rloc16 = Mle::Mle::Rloc16FromRouterId(aRouterId);
|
||||
|
||||
for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
|
||||
{
|
||||
if (router->GetRloc16() == rloc16)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
router = FindRouter(Router::AddressMatcher(rloc16, Router::kInStateAny));
|
||||
|
||||
exit:
|
||||
return router;
|
||||
@@ -402,17 +390,7 @@ exit:
|
||||
|
||||
Router *RouterTable::GetRouter(const Mac::ExtAddress &aExtAddress)
|
||||
{
|
||||
Router *router = nullptr;
|
||||
|
||||
for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
|
||||
{
|
||||
if (router->GetExtAddress() == aExtAddress)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return router;
|
||||
return FindRouter(Router::AddressMatcher(aExtAddress, Router::kInStateAny));
|
||||
}
|
||||
|
||||
otError RouterTable::GetRouterInfo(uint16_t aRouterId, Router::Info &aRouterInfo)
|
||||
|
||||
@@ -423,6 +423,12 @@ private:
|
||||
return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetNextEntry(aRouter));
|
||||
}
|
||||
|
||||
const Router *FindRouter(const Router::AddressMatcher &aMatcher) const;
|
||||
Router * FindRouter(const Router::AddressMatcher &aMatcher)
|
||||
{
|
||||
return const_cast<Router *>(const_cast<const RouterTable *>(this)->FindRouter(aMatcher));
|
||||
}
|
||||
|
||||
Router mRouters[Mle::kMaxRouters];
|
||||
Mle::RouterIdSet mAllocatedRouterIds;
|
||||
uint8_t mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
|
||||
|
||||
@@ -41,6 +41,28 @@
|
||||
|
||||
namespace ot {
|
||||
|
||||
bool Neighbor::AddressMatcher::Matches(const Neighbor &aNeighbor) const
|
||||
{
|
||||
bool matches = false;
|
||||
|
||||
VerifyOrExit(aNeighbor.MatchesFilter(mStateFilter), OT_NOOP);
|
||||
|
||||
if (mShortAddress != Mac::kShortAddrInvalid)
|
||||
{
|
||||
VerifyOrExit(mShortAddress == aNeighbor.GetRloc16(), OT_NOOP);
|
||||
}
|
||||
|
||||
if (mExtAddress != nullptr)
|
||||
{
|
||||
VerifyOrExit(*mExtAddress == aNeighbor.GetExtAddress(), OT_NOOP);
|
||||
}
|
||||
|
||||
matches = true;
|
||||
|
||||
exit:
|
||||
return matches;
|
||||
}
|
||||
|
||||
void Neighbor::Info::SetFrom(const Neighbor &aNeighbor)
|
||||
{
|
||||
Clear();
|
||||
@@ -112,6 +134,10 @@ bool Neighbor::MatchesFilter(StateFilter aFilter) const
|
||||
matches = IsStateValidOrAttaching();
|
||||
break;
|
||||
|
||||
case kInStateInvalid:
|
||||
matches = IsStateInvalid();
|
||||
break;
|
||||
|
||||
case kInStateAnyExceptInvalid:
|
||||
matches = !IsStateInvalid();
|
||||
break;
|
||||
@@ -119,6 +145,10 @@ bool Neighbor::MatchesFilter(StateFilter aFilter) const
|
||||
case kInStateAnyExceptValidOrRestoring:
|
||||
matches = !IsStateValidOrRestoring();
|
||||
break;
|
||||
|
||||
case kInStateAny:
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return matches;
|
||||
|
||||
@@ -83,12 +83,96 @@ public:
|
||||
*/
|
||||
enum StateFilter
|
||||
{
|
||||
kInStateValid, ///< Accept child only in `kStateValid`.
|
||||
kInStateValidOrRestoring, ///< Accept child with `IsStateValidOrRestoring()` being `true`.
|
||||
kInStateChildIdRequest, ///< Accept child only in `Child:kStateChildIdRequest`.
|
||||
kInStateValidOrAttaching, ///< Accept child with `IsStateValidOrAttaching()` being `true`.
|
||||
kInStateAnyExceptInvalid, ///< Accept child in any state except `kStateInvalid`.
|
||||
kInStateAnyExceptValidOrRestoring, ///< Accept child in any state except `IsStateValidOrRestoring()`.
|
||||
kInStateValid, ///< Accept neighbor only in `kStateValid`.
|
||||
kInStateValidOrRestoring, ///< Accept neighbor with `IsStateValidOrRestoring()` being `true`.
|
||||
kInStateChildIdRequest, ///< Accept neighbor only in `Child:kStateChildIdRequest`.
|
||||
kInStateValidOrAttaching, ///< Accept neighbor with `IsStateValidOrAttaching()` being `true`.
|
||||
kInStateInvalid, ///< Accept neighbor only in `kStateInvalid`.
|
||||
kInStateAnyExceptInvalid, ///< Accept neighbor in any state except `kStateInvalid`.
|
||||
kInStateAnyExceptValidOrRestoring, ///< Accept neighbor in any state except `IsStateValidOrRestoring()`.
|
||||
kInStateAny, ///< Accept neighbor in any state.
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents an Address Matcher used to find a neighbor (child/router) with a given MAC address also
|
||||
* matching a given state filter.
|
||||
*
|
||||
*/
|
||||
class AddressMatcher
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the `AddressMatcher` with a given MAC short address (RCOC16) and state filter.
|
||||
*
|
||||
* @param[in] aShortAddress A MAC short address (RLOC16).
|
||||
* @param[in] aStateFilter A state filter.
|
||||
*
|
||||
*/
|
||||
AddressMatcher(Mac::ShortAddress aShortAddress, StateFilter aStateFilter)
|
||||
: AddressMatcher(aStateFilter, aShortAddress, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `AddressMatcher` with a given MAC extended address and state filter.
|
||||
*
|
||||
* @param[in] aExtAddress A MAC extended address.
|
||||
* @param[in] aStateFilter A state filter.
|
||||
*
|
||||
*/
|
||||
AddressMatcher(const Mac::ExtAddress &aExtAddress, StateFilter aStateFilter)
|
||||
: AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, &aExtAddress)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `AddressMatcher` with a given MAC address and state filter.
|
||||
*
|
||||
* @param[in] aMacAddress A MAC address.
|
||||
* @param[in] aStateFilter A state filter.
|
||||
*
|
||||
*/
|
||||
AddressMatcher(const Mac::Address &aMacAddress, StateFilter aStateFilter)
|
||||
: AddressMatcher(aStateFilter,
|
||||
aMacAddress.IsShort() ? aMacAddress.GetShort()
|
||||
: static_cast<Mac::ShortAddress>(Mac::kShortAddrInvalid),
|
||||
aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `AddressMatcher` with a given state filter (it accepts any address).
|
||||
*
|
||||
* @param[in] aStateFilter A state filter.
|
||||
*
|
||||
*/
|
||||
explicit AddressMatcher(StateFilter aStateFilter)
|
||||
: AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates if a given neighbor matches the address and state filter of `AddressMatcher`.
|
||||
*
|
||||
* @param[in] aNeighbor A neighbor.
|
||||
*
|
||||
* @retval TRUE Neighbor @p aNeighbor matches the address and state filter.
|
||||
* @retval FALSE Neighbor @p aNeighbor does not match the address or state filter.
|
||||
*
|
||||
*/
|
||||
bool Matches(const Neighbor &aNeighbor) const;
|
||||
|
||||
private:
|
||||
AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress)
|
||||
: mStateFilter(aStateFilter)
|
||||
, mShortAddress(aShortAddress)
|
||||
, mExtAddress(aExtAddress)
|
||||
{
|
||||
}
|
||||
|
||||
StateFilter mStateFilter;
|
||||
Mac::ShortAddress mShortAddress;
|
||||
const Mac::ExtAddress *mExtAddress;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -210,6 +294,16 @@ public:
|
||||
*/
|
||||
bool MatchesFilter(StateFilter aFilter) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether neighbor matches a given `AddressMatcher`.
|
||||
*
|
||||
* @param[in] aMatcher An `AddressMatcher` to match against.
|
||||
*
|
||||
* @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); }
|
||||
|
||||
/**
|
||||
* This method gets the device mode flags.
|
||||
*
|
||||
|
||||
@@ -96,9 +96,17 @@ static bool StateMatchesFilter(Child::State aState, Child::StateFilter aFilter)
|
||||
rval = child.IsStateValidOrAttaching();
|
||||
break;
|
||||
|
||||
case Child::kInStateInvalid:
|
||||
rval = child.IsStateInvalid();
|
||||
break;
|
||||
|
||||
case Child::kInStateAnyExceptValidOrRestoring:
|
||||
rval = !child.IsStateValidOrRestoring();
|
||||
break;
|
||||
|
||||
case Child::kInStateAny:
|
||||
rval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
||||
Reference in New Issue
Block a user