[neighbor-table] add 'NeighborTable' class (#5354)

This commit adds a `NeighborTable` class which provides helper methods
dealing with neighbor, e.g., finding a `Neighbor` (i.e., a `Child`
from `ChildTable`, a `Router` from `RouterTable`, or parent or parent
candidate entries), or iterating through all neighbors.  These methods
use the newly added `Neighbor::AddressMacther` to simplify the
implementation. The `NeighborTable` methods replace the similar ones
in `Mle` and `MleRouter`.
This commit is contained in:
Abtin Keshavarzian
2020-08-10 09:07:52 -07:00
committed by Jonathan Hui
parent 6c75a53bdc
commit 36b9ecbf11
19 changed files with 479 additions and 416 deletions
+1
View File
@@ -256,6 +256,7 @@ LOCAL_SRC_FILES := \
src/core/thread/mle_router.cpp \
src/core/thread/mle_types.cpp \
src/core/thread/mlr_manager.cpp \
src/core/thread/neighbor_table.cpp \
src/core/thread/network_data.cpp \
src/core/thread/network_data_leader.cpp \
src/core/thread/network_data_leader_ftd.cpp \
+1
View File
@@ -151,6 +151,7 @@ static_library("lib-ot-core") {
"src/core/thread/mle_router.cpp",
"src/core/thread/mle_types.cpp",
"src/core/thread/mlr_manager.cpp",
"src/core/thread/neighbor_table.cpp",
"src/core/thread/network_data.cpp",
"src/core/thread/network_data_leader.cpp",
"src/core/thread/network_data_leader_ftd.cpp",
+1
View File
@@ -187,6 +187,7 @@ set(COMMON_SOURCES
thread/mle_router.cpp
thread/mle_types.cpp
thread/mlr_manager.cpp
thread/neighbor_table.cpp
thread/network_data.cpp
thread/network_data_leader.cpp
thread/network_data_leader_ftd.cpp
+2
View File
@@ -229,6 +229,7 @@ SOURCES_COMMON = \
thread/mle_router.cpp \
thread/mle_types.cpp \
thread/mlr_manager.cpp \
thread/neighbor_table.cpp \
thread/network_data.cpp \
thread/network_data_leader.cpp \
thread/network_data_leader_ftd.cpp \
@@ -445,6 +446,7 @@ HEADERS_COMMON = \
thread/mle_types.hpp \
thread/mlr_manager.hpp \
thread/mlr_types.hpp \
thread/neighbor_table.hpp \
thread/network_data.hpp \
thread/network_data_leader.hpp \
thread/network_data_leader_ftd.hpp \
+1 -1
View File
@@ -304,7 +304,7 @@ otError otThreadGetNextNeighborInfo(otInstance *aInstance, otNeighborInfoIterato
OT_ASSERT((aInfo != nullptr) && (aIterator != nullptr));
return instance.Get<Mle::MleRouter>().GetNextNeighborInfo(*aIterator, *static_cast<Neighbor::Info *>(aInfo));
return instance.Get<NeighborTable>().GetNextNeighborInfo(*aIterator, *static_cast<Neighbor::Info *>(aInfo));
}
otDeviceRole otThreadGetDeviceRole(otInstance *aInstance)
+5
View File
@@ -443,6 +443,11 @@ template <> inline Mle::DiscoverScanner &Instance::Get(void)
return mThreadNetif.mDiscoverScanner;
}
template <> inline NeighborTable &Instance::Get(void)
{
return mThreadNetif.mMleRouter.mNeighborTable;
}
#if OPENTHREAD_FTD
template <> inline ChildTable &Instance::Get(void)
{
+3 -3
View File
@@ -1152,7 +1152,7 @@ void Mac::RecordFrameTransmitStatus(const TxFrame &aFrame,
VerifyOrExit(!aFrame.IsEmpty(), OT_NOOP);
IgnoreError(aFrame.GetDstAddr(dstAddr));
neighbor = Get<Mle::MleRouter>().GetNeighbor(dstAddr);
neighbor = Get<NeighborTable>().FindNeighbor(dstAddr);
// Record frame transmission success/failure state (for a neighbor).
@@ -1565,7 +1565,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
IgnoreError(aFrame->GetSrcAddr(srcaddr));
IgnoreError(aFrame->GetDstAddr(dstaddr));
neighbor = Get<Mle::MleRouter>().GetNeighbor(srcaddr);
neighbor = Get<NeighborTable>().FindNeighbor(srcaddr);
// Destination Address Filtering
switch (dstaddr.GetType())
@@ -1583,7 +1583,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
// Allow multicasts from neighbor routers if FTD
if (neighbor == nullptr && dstaddr.IsBroadcast() && Get<Mle::MleRouter>().IsFullThreadDevice())
{
neighbor = Get<Mle::MleRouter>().GetRxOnlyNeighborRouter(srcaddr);
neighbor = Get<NeighborTable>().FindRxOnlyNeighborRouter(srcaddr);
}
#endif
+1
View File
@@ -49,6 +49,7 @@ namespace ot {
*/
class ChildTable : public InstanceLocator
{
friend class NeighborTable;
class IteratorBuilder;
public:
+1 -1
View File
@@ -740,7 +740,7 @@ Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, otError
VerifyOrExit(mEnabled, OT_NOOP);
neighbor = Get<Mle::MleRouter>().GetNeighbor(aMacDest);
neighbor = Get<NeighborTable>().FindNeighbor(aMacDest);
VerifyOrExit(neighbor != nullptr, OT_NOOP);
VerifyOrExit(aFrame.GetAckRequest(), OT_NOOP);
+10 -11
View File
@@ -101,8 +101,8 @@ otError MeshForwarder::SendMessage(Message &aMessage)
}
}
}
else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != nullptr && !neighbor->IsRxOnWhenIdle() &&
!aMessage.GetDirectTransmission())
else if ((neighbor = Get<NeighborTable>().FindNeighbor(ip6Header.GetDestination())) != nullptr &&
!neighbor->IsRxOnWhenIdle() && !aMessage.GetDirectTransmission())
{
// destined for a sleepy child
Child &child = *static_cast<Child *>(neighbor);
@@ -246,8 +246,7 @@ exit:
void MeshForwarder::RemoveMessages(Child &aChild, Message::SubType aSubType)
{
Mle::MleRouter &mle = Get<Mle::MleRouter>();
Message * nextMessage;
Message *nextMessage;
for (Message *message = mSendQueue.GetHead(); message; message = nextMessage)
{
@@ -268,7 +267,7 @@ void MeshForwarder::RemoveMessages(Child &aChild, Message::SubType aSubType)
IgnoreReturnValue(message->Read(0, sizeof(ip6header), &ip6header));
if (&aChild == static_cast<Child *>(mle.GetNeighbor(ip6header.GetDestination())))
if (&aChild == static_cast<Child *>(Get<NeighborTable>().FindNeighbor(ip6header.GetDestination())))
{
message->ClearDirectTransmission();
}
@@ -282,7 +281,7 @@ void MeshForwarder::RemoveMessages(Child &aChild, Message::SubType aSubType)
IgnoreError(meshHeader.ParseFrom(*message));
if (&aChild == static_cast<Child *>(mle.GetNeighbor(meshHeader.GetDestination())))
if (&aChild == static_cast<Child *>(Get<NeighborTable>().FindNeighbor(meshHeader.GetDestination())))
{
message->ClearDirectTransmission();
}
@@ -375,11 +374,11 @@ otError MeshForwarder::UpdateMeshRoute(Message &aMessage)
if (nextHop != Mac::kShortAddrInvalid)
{
neighbor = Get<Mle::MleRouter>().GetNeighbor(nextHop);
neighbor = Get<NeighborTable>().FindNeighbor(nextHop);
}
else
{
neighbor = Get<Mle::MleRouter>().GetNeighbor(meshHeader.GetDestination());
neighbor = Get<NeighborTable>().FindNeighbor(meshHeader.GetDestination());
}
if (neighbor == nullptr)
@@ -465,7 +464,7 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessa
ExitNow(error = OT_ERROR_DROP);
}
}
else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != nullptr)
else if ((neighbor = Get<NeighborTable>().FindNeighbor(ip6Header.GetDestination())) != nullptr)
{
mMeshDest = neighbor->GetRloc16();
}
@@ -715,7 +714,7 @@ void MeshForwarder::UpdateRoutes(const uint8_t * aFrame,
}
}
neighbor = Get<Mle::MleRouter>().GetNeighbor(ip6Header.GetSource());
neighbor = Get<NeighborTable>().FindNeighbor(ip6Header.GetSource());
VerifyOrExit(neighbor != nullptr && !neighbor->IsFullThreadDevice(), OT_NOOP);
if (!Mle::Mle::RouterIdMatch(aMeshSource.GetShort(), Get<Mac::Mac>().GetShortAddress()))
@@ -907,7 +906,7 @@ otError MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, ui
}
// Cost if the server is direct neighbor.
neighbor = Get<Mle::MleRouter>().GetNeighbor(server16);
neighbor = Get<NeighborTable>().FindNeighbor(server16);
if (neighbor != nullptr && neighbor->IsStateValid())
{
+4 -78
View File
@@ -65,6 +65,7 @@ Mle::Mle(Instance &aInstance)
, Notifier::Receiver(aInstance, Mle::HandleNotifierEvents)
, mRetrieveNewNetworkData(false)
, mRole(kRoleDisabled)
, mNeighborTable(aInstance)
, mDeviceMode(DeviceMode::kModeRxOnWhenIdle | DeviceMode::kModeSecureDataRequest)
, mAttachState(kAttachStateIdle)
, mReattachState(kReattachStop)
@@ -2001,7 +2002,7 @@ otError Mle::SendChildIdRequest(void)
//
// 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 GetNeighbor() returns mParentCandidate when processing the Child ID Response.
// that FindNeighbor() returns mParentCandidate when processing the Child ID Response.
mParent.SetState(Neighbor::kStateInvalid);
}
}
@@ -2628,30 +2629,8 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
aMessage.Read(aMessage.GetOffset(), sizeof(command), &command);
aMessage.MoveOffset(sizeof(command));
switch (mRole)
{
case kRoleDetached:
case kRoleChild:
neighbor = GetNeighbor(extAddr);
break;
case kRoleRouter:
case kRoleLeader:
if (command == Header::kCommandChildIdResponse)
{
neighbor = GetNeighbor(extAddr);
}
else
{
neighbor = Get<MleRouter>().GetNeighbor(extAddr);
}
break;
default:
neighbor = nullptr;
break;
}
neighbor = (command == Header::kCommandChildIdResponse) ? mNeighborTable.FindParent(extAddr)
: mNeighborTable.FindNeighbor(extAddr);
if (neighbor != nullptr && neighbor->IsStateValid())
{
@@ -3773,59 +3752,6 @@ void Mle::ProcessAnnounce(void)
IgnoreError(Start(/* aAnnounceAttach */ true));
}
Neighbor *Mle::GetNeighbor(uint16_t aAddress)
{
Neighbor *rval = nullptr;
if (mParent.IsStateValidOrRestoring() && (mParent.GetRloc16() == aAddress))
{
rval = &mParent;
}
else if (mParentCandidate.IsStateValid() && (mParentCandidate.GetRloc16() == aAddress))
{
rval = &mParentCandidate;
}
return rval;
}
Neighbor *Mle::GetNeighbor(const Mac::ExtAddress &aAddress)
{
Neighbor *rval = nullptr;
if (mParent.IsStateValidOrRestoring() && (mParent.GetExtAddress() == aAddress))
{
rval = &mParent;
}
else if (mParentCandidate.IsStateValid() && (mParentCandidate.GetExtAddress() == aAddress))
{
rval = &mParentCandidate;
}
return rval;
}
Neighbor *Mle::GetNeighbor(const Mac::Address &aAddress)
{
Neighbor *neighbor = nullptr;
switch (aAddress.GetType())
{
case Mac::Address::kTypeShort:
neighbor = GetNeighbor(aAddress.GetShort());
break;
case Mac::Address::kTypeExtended:
neighbor = GetNeighbor(aAddress.GetExtended());
break;
default:
break;
}
return neighbor;
}
uint16_t Mle::GetNextHop(uint16_t aDestination) const
{
OT_UNUSED_VARIABLE(aDestination);
+2 -44
View File
@@ -45,6 +45,7 @@
#include "net/udp6.hpp"
#include "thread/mle_tlvs.hpp"
#include "thread/mle_types.hpp"
#include "thread/neighbor_table.hpp"
#include "thread/topology.hpp"
namespace ot {
@@ -1381,50 +1382,6 @@ protected:
*/
otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header);
/**
* This method returns a pointer to the neighbor object.
*
* @param[in] aAddress A reference to the MAC address.
*
* @returns A pointer to the neighbor object.
*
*/
Neighbor *GetNeighbor(const Mac::Address &aAddress);
/**
* This method returns a pointer to the neighbor object.
*
* @param[in] aAddress A reference to the MAC short address.
*
* @returns A pointer to the neighbor object.
*
*/
Neighbor *GetNeighbor(Mac::ShortAddress aAddress);
/**
* This method returns a pointer to the neighbor object.
*
* @param[in] aAddress A reference to the MAC extended address.
*
* @returns A pointer to the neighbor object.
*
*/
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress);
/**
* This method returns a pointer to the neighbor object.
*
* @param[in] aAddress A reference to the IPv6 address.
*
* @returns A pointer to the neighbor object.
*
*/
Neighbor *GetNeighbor(const Ip6::Address &aAddress)
{
OT_UNUSED_VARIABLE(aAddress);
return nullptr;
}
/**
* This method returns the next hop towards an RLOC16 destination.
*
@@ -1605,6 +1562,7 @@ protected:
DeviceRole mRole; ///< Current Thread role.
Router mParent; ///< Parent information.
Router mParentCandidate; ///< Parent candidate information.
NeighborTable mNeighborTable; ///< The neighbor table.
DeviceMode mDeviceMode; ///< Device mode setting.
AttachState mAttachState; ///< The parent request state.
ReattachState mReattachState; ///< Reattach state
+3 -207
View File
@@ -3286,7 +3286,7 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
switch (aTlvs[i])
{
case Tlv::kNetworkData:
neighbor = GetNeighbor(aDestination);
neighbor = mNeighborTable.FindNeighbor(aDestination);
stableOnly = neighbor != nullptr ? !neighbor->IsFullNetworkData() : false;
SuccessOrExit(error = AppendNetworkData(*message, stableOnly));
break;
@@ -3339,7 +3339,7 @@ bool MleRouter::IsMinimalChild(uint16_t aRloc16)
{
Neighbor *neighbor;
neighbor = GetNeighbor(aRloc16);
neighbor = mNeighborTable.FindNeighbor(aRloc16);
rval = (neighbor != nullptr) && (!neighbor->IsFullThreadDevice());
}
@@ -3419,156 +3419,6 @@ exit:
return;
}
Neighbor *MleRouter::GetNeighbor(uint16_t aAddress)
{
Neighbor *rval = nullptr;
if (aAddress == Mac::kShortAddrBroadcast || aAddress == Mac::kShortAddrInvalid)
{
ExitNow();
}
switch (mRole)
{
case kRoleDisabled:
break;
case kRoleDetached:
case kRoleChild:
rval = Mle::GetNeighbor(aAddress);
break;
case kRoleRouter:
case kRoleLeader:
rval = mChildTable.FindChild(aAddress, Child::kInStateValidOrRestoring);
VerifyOrExit(rval == nullptr, OT_NOOP);
rval = mRouterTable.GetNeighbor(aAddress);
break;
}
exit:
return rval;
}
Neighbor *MleRouter::GetNeighbor(const Mac::ExtAddress &aAddress)
{
Neighbor *rval = nullptr;
switch (mRole)
{
case kRoleDisabled:
break;
case kRoleDetached:
case kRoleChild:
rval = Mle::GetNeighbor(aAddress);
break;
case kRoleRouter:
case kRoleLeader:
rval = mChildTable.FindChild(aAddress, Child::kInStateValidOrRestoring);
VerifyOrExit(rval == nullptr, OT_NOOP);
rval = mRouterTable.GetNeighbor(aAddress);
if (rval != nullptr)
{
ExitNow();
}
if (IsAttaching())
{
rval = Mle::GetNeighbor(aAddress);
}
break;
}
exit:
return rval;
}
Neighbor *MleRouter::GetNeighbor(const Mac::Address &aAddress)
{
Neighbor *rval = nullptr;
switch (aAddress.GetType())
{
case Mac::Address::kTypeShort:
rval = GetNeighbor(aAddress.GetShort());
break;
case Mac::Address::kTypeExtended:
rval = GetNeighbor(aAddress.GetExtended());
break;
default:
break;
}
return rval;
}
Neighbor *MleRouter::GetNeighbor(const Ip6::Address &aAddress)
{
Neighbor *rval = nullptr;
if (aAddress.IsLinkLocal())
{
Mac::Address macAddr;
aAddress.GetIid().ConvertToMacAddress(macAddr);
ExitNow(rval = GetNeighbor(macAddr));
}
if (IsRoutingLocator(aAddress))
{
uint16_t rloc16 = aAddress.GetIid().GetLocator();
rval = mChildTable.FindChild(rloc16, Child::kInStateValidOrRestoring);
VerifyOrExit(rval == nullptr, OT_NOOP);
rval = mRouterTable.GetNeighbor(rloc16);
ExitNow();
}
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
{
if (child.HasIp6Address(aAddress))
{
ExitNow(rval = &child);
}
}
exit:
return rval;
}
Neighbor *MleRouter::GetRxOnlyNeighborRouter(const Mac::Address &aAddress)
{
Neighbor *rval = nullptr;
VerifyOrExit(IsChild(), rval = nullptr);
switch (aAddress.GetType())
{
case Mac::Address::kTypeShort:
rval = mRouterTable.GetNeighbor(aAddress.GetShort());
break;
case Mac::Address::kTypeExtended:
rval = mRouterTable.GetNeighbor(aAddress.GetExtended());
break;
default:
break;
}
exit:
return rval;
}
uint16_t MleRouter::GetNextHop(uint16_t aDestination)
{
uint8_t destinationId = RouterIdFromRloc16(aDestination);
@@ -3663,60 +3513,6 @@ void MleRouter::SetRouterId(uint8_t aRouterId)
mPreviousRouterId = mRouterId;
}
otError MleRouter::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo)
{
otError error = OT_ERROR_NONE;
int16_t index;
// Non-negative iterator value gives the Child index into child table
if (aIterator >= 0)
{
for (index = aIterator;; index++)
{
Child *child = mChildTable.GetChildAtIndex(static_cast<uint16_t>(index));
if (child == nullptr)
{
break;
}
if (child->IsStateValid())
{
aNeighInfo.SetFrom(*child);
aNeighInfo.mIsChild = true;
index++;
aIterator = index;
ExitNow();
}
}
aIterator = 0;
}
// Negative iterator value gives the current index into mRouters array
for (index = -aIterator; index <= kMaxRouterId; index++)
{
Router *router = mRouterTable.GetRouter(static_cast<uint8_t>(index));
if (router != nullptr && router->IsStateValid())
{
aNeighInfo.SetFrom(*router);
aNeighInfo.mIsChild = false;
index++;
aIterator = -index;
ExitNow();
}
}
aIterator = -index;
error = OT_ERROR_NOT_FOUND;
exit:
return error;
}
void MleRouter::ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16)
{
Router *router;
@@ -3756,7 +3552,7 @@ otError MleRouter::CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header
// IPv6 destination is this device
ExitNow();
}
else if (GetNeighbor(aIp6Header.GetDestination()) != nullptr)
else if (mNeighborTable.FindNeighbor(aIp6Header.GetDestination()) != nullptr)
{
// IPv6 destination is an RFD child
ExitNow();
-70
View File
@@ -344,57 +344,6 @@ public:
*/
void RemoveRouterLink(Router &aRouter);
/**
* This method returns a pointer to a Neighbor object.
*
* @param[in] aAddress The address of the Neighbor.
*
* @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
*
*/
Neighbor *GetNeighbor(uint16_t aAddress);
/**
* This method returns a pointer to a Neighbor object.
*
* @param[in] aAddress The address of the Neighbor.
*
* @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
*
*/
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress);
/**
* This method returns a pointer to a Neighbor object.
*
* @param[in] aAddress The address of the Neighbor.
*
* @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
*
*/
Neighbor *GetNeighbor(const Mac::Address &aAddress);
/**
* This method returns a pointer to a Neighbor object.
*
* @param[in] aAddress The address of the Neighbor.
*
* @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
*
*/
Neighbor *GetNeighbor(const Ip6::Address &aAddress);
/**
* This method returns a pointer to a Neighbor object if a one-way link is maintained
* as in the instance of an FTD child with neighbor routers.
*
* @param[in] aAddress The address of the Neighbor.
*
* @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
*
*/
Neighbor *GetRxOnlyNeighborRouter(const Mac::Address &aAddress);
/**
* This method indicates whether or not the RLOC16 is an MTD child of this device.
*
@@ -406,20 +355,6 @@ public:
*/
bool IsMinimalChild(uint16_t aRloc16);
/**
* This method gets the next neighbor information. It is used to iterate through the entries of
* the neighbor table.
*
* @param[inout] aIterator A reference to the iterator context. To get the first neighbor entry
it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT.
* @param[out] aNeighInfo The neighbor information.
*
* @retval OT_ERROR_NONE Successfully found the next neighbor entry in table.
* @retval OT_ERROR_NOT_FOUND No subsequent neighbor entry exists in the table.
*
*/
otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo);
/**
* This method indicates whether or not the given Thread partition attributes are preferred.
*
@@ -797,11 +732,6 @@ public:
otError RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
void RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); }
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }
Neighbor *GetNeighbor(const Mac::Address &aAddress) { return Mle::GetNeighbor(aAddress); }
otError GetNextNeighborInfo(otNeighborInfoIterator &, otNeighborInfo &) { return OT_ERROR_NOT_IMPLEMENTED; }
static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
+256
View File
@@ -0,0 +1,256 @@
/*
* Copyright (c) 2016-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 Thread neighbor table.
*/
#include "neighbor_table.hpp"
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include "common/locator-getters.hpp"
namespace ot {
NeighborTable::NeighborTable(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
Neighbor *NeighborTable::FindParent(const Neighbor::AddressMatcher &aMatcher)
{
Neighbor *neighbor = nullptr;
Mle::Mle &mle = Get<Mle::Mle>();
if (mle.GetParent().Matches(aMatcher))
{
neighbor = &mle.GetParent();
}
else if (mle.GetParentCandidate().Matches(aMatcher))
{
neighbor = &mle.GetParentCandidate();
}
return neighbor;
}
Neighbor *NeighborTable::FindParent(Mac::ShortAddress aShortAddress)
{
return FindParent(Neighbor::AddressMatcher(aShortAddress, Neighbor::kInStateValidOrRestoring));
}
Neighbor *NeighborTable::FindParent(const Mac::ExtAddress &aExtAddress)
{
return FindParent(Neighbor::AddressMatcher(aExtAddress, Neighbor::kInStateValidOrRestoring));
}
Neighbor *NeighborTable::FindParent(const Mac::Address &aMacAddress)
{
return FindParent(Neighbor::AddressMatcher(aMacAddress, Neighbor::kInStateValidOrRestoring));
}
Neighbor *NeighborTable::FindNeighbor(const Neighbor::AddressMatcher &aMatcher)
{
Neighbor *neighbor = nullptr;
#if OPENTHREAD_FTD
if (Get<Mle::Mle>().IsRouterOrLeader())
{
neighbor = FindChildOrRouter(aMatcher);
}
if (neighbor == nullptr)
#endif
{
neighbor = FindParent(aMatcher);
}
return neighbor;
}
Neighbor *NeighborTable::FindNeighbor(Mac::ShortAddress aShortAddress)
{
Neighbor *neighbor = nullptr;
VerifyOrExit((aShortAddress != Mac::kShortAddrBroadcast) && (aShortAddress != Mac::kShortAddrInvalid), OT_NOOP);
neighbor = FindNeighbor(Neighbor::AddressMatcher(aShortAddress, Neighbor::kInStateValidOrRestoring));
exit:
return neighbor;
}
Neighbor *NeighborTable::FindNeighbor(const Mac::ExtAddress &aExtAddress)
{
return FindNeighbor(Neighbor::AddressMatcher(aExtAddress, Neighbor::kInStateValidOrRestoring));
}
Neighbor *NeighborTable::FindNeighbor(const Mac::Address &aMacAddress)
{
return FindNeighbor(Neighbor::AddressMatcher(aMacAddress, Neighbor::kInStateValidOrRestoring));
}
#if OPENTHREAD_FTD
Neighbor *NeighborTable::FindChildOrRouter(const Neighbor::AddressMatcher &aMatcher)
{
Neighbor *neighbor;
neighbor = Get<ChildTable>().FindChild(aMatcher);
if (neighbor == nullptr)
{
neighbor = Get<RouterTable>().FindRouter(aMatcher);
}
return neighbor;
}
Neighbor *NeighborTable::FindNeighbor(const Ip6::Address &aIp6Address)
{
Neighbor * neighbor = nullptr;
Mac::Address macAddresss;
if (aIp6Address.IsLinkLocal())
{
aIp6Address.GetIid().ConvertToMacAddress(macAddresss);
}
if (Get<Mle::Mle>().IsRoutingLocator(aIp6Address))
{
macAddresss.SetShort(aIp6Address.GetIid().GetLocator());
}
if (!macAddresss.IsNone())
{
neighbor = FindChildOrRouter(Neighbor::AddressMatcher(macAddresss, Neighbor::kInStateValidOrRestoring));
ExitNow();
}
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
{
if (child.HasIp6Address(aIp6Address))
{
ExitNow(neighbor = &child);
}
}
exit:
return neighbor;
}
Neighbor *NeighborTable::FindRxOnlyNeighborRouter(const Mac::Address &aMacAddress)
{
Neighbor *neighbor = nullptr;
VerifyOrExit(Get<Mle::Mle>().IsChild(), OT_NOOP);
neighbor = Get<RouterTable>().GetNeighbor(aMacAddress);
exit:
return neighbor;
}
otError NeighborTable::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo)
{
otError error = OT_ERROR_NONE;
int16_t index;
// Non-negative iterator value gives the Child index into child table
if (aIterator >= 0)
{
for (index = aIterator;; index++)
{
Child *child = Get<ChildTable>().GetChildAtIndex(static_cast<uint16_t>(index));
if (child == nullptr)
{
break;
}
if (child->IsStateValid())
{
aNeighInfo.SetFrom(*child);
aNeighInfo.mIsChild = true;
index++;
aIterator = index;
ExitNow();
}
}
aIterator = 0;
}
// Negative iterator value gives the current index into mRouters array
for (index = -aIterator; index <= Mle::kMaxRouterId; index++)
{
Router *router = Get<RouterTable>().GetRouter(static_cast<uint8_t>(index));
if (router != nullptr && router->IsStateValid())
{
aNeighInfo.SetFrom(*router);
aNeighInfo.mIsChild = false;
index++;
aIterator = -index;
ExitNow();
}
}
aIterator = -index;
error = OT_ERROR_NOT_FOUND;
exit:
return error;
}
#endif // OPENTHREAD_FTD
#if OPENTHREAD_MTD
otError NeighborTable::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo)
{
otError error = OT_ERROR_NOT_FOUND;
VerifyOrExit(aIterator == OT_NEIGHBOR_INFO_ITERATOR_INIT, OT_NOOP);
aIterator++;
VerifyOrExit(Get<Mle::Mle>().GetParent().IsStateValid(), OT_NOOP);
aNeighInfo.SetFrom(Get<Mle::Mle>().GetParent());
aNeighInfo.mIsChild = false;
error = OT_ERROR_NONE;
exit:
return error;
}
#endif
} // namespace ot
+171
View File
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2016-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 Thread neighbor table.
*/
#ifndef NEIGHBOR_TABLE_HPP_
#define NEIGHBOR_TABLE_HPP_
#include "openthread-core-config.h"
#include "common/locator.hpp"
#include "thread/topology.hpp"
namespace ot {
/**
* This class represents the Thread neighbor table.
*
*/
class NeighborTable : public InstanceLocator
{
public:
/**
* This constructor initializes the `NeighborTable` instance.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit NeighborTable(Instance &aInstance);
/**
* This method searches among parent and parent candidate to find a `Neighbor` corresponding to a given short
* address.
*
* @param[in] aShortAddress A short address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aShortAddress, nullptr otherwise.
*
*/
Neighbor *FindParent(Mac::ShortAddress aShortAddress);
/**
* This method searches in parent and parent candidate to find a `Neighbor` corresponding to a given MAC Extended
* Address.
*
* @param[in] aExtAddress A MAC Extended Address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aExtAddress, nullptr otherwise.
*
*/
Neighbor *FindParent(const Mac::ExtAddress &aExtAddress);
/**
* This method searches among parent and parent candidate to find a `Neighbor` object corresponding to a given MAC
* address.
*
* @param[in] aMacAddress A MAC address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aMacAddress, nullptr otherwise.
*
*/
Neighbor *FindParent(const Mac::Address &aMacAddress);
/**
* This method searches in the neighbor table to find a `Neighbor` corresponding to a given short address.
*
* @param[in] aShortAddress A short address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aShortAddress, nullptr otherwise.
*
*/
Neighbor *FindNeighbor(Mac::ShortAddress aShortAddress);
/**
* This method searches in the neighbor table to find a `Neighbor` corresponding to a given MAC Extended Address.
*
* @param[in] aExtAddress A MAC Extended Address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aExtAddress, nullptr otherwise.
*
*/
Neighbor *FindNeighbor(const Mac::ExtAddress &aExtAddress);
/**
* This method searches in the neighbor table to find a `Neighbor` object corresponding to a given MAC address.
*
* @param[in] aMacAddress A MAC address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aMacAddress, nullptr otherwise.
*
*/
Neighbor *FindNeighbor(const Mac::Address &aMacAddress);
#if OPENTHREAD_FTD
/**
* This method searches in the neighbor table to find a `Neighbor` object corresponding to a given IPv6 address.
*
* @param[in] aIp6Address An IPv6 address.
*
* @returns A pointer to the `Neighbor` corresponding to @p aIp6Address, nullptr otherwise.
*
*/
Neighbor *FindNeighbor(const Ip6::Address &aIp6Address);
/**
* This method searches in the neighbor table to find a `Neighbor` for which a one-way link is maintained (as in the
* case of an FTD child with neighbor routers).
*
* @param[in] aMacAddress A MAC address.
*
* @returns A pointer to the Neighbor corresponding to @p aMacAddress, nullptr otherwise.
*
*/
Neighbor *FindRxOnlyNeighborRouter(const Mac::Address &aMacAddress);
#endif // OPENTHREAD_FTD
/**
* This method gets the next neighbor information. It is used to iterate through the entries of
* the neighbor table.
*
* @param[inout] aIterator A reference to the iterator context. To get the first neighbor entry
it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT.
* @param[out] aNeighInfo The neighbor information.
*
* @retval OT_ERROR_NONE Successfully found the next neighbor entry in table.
* @retval OT_ERROR_NOT_FOUND No subsequent neighbor entry exists in the table.
*
*/
otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo);
private:
Neighbor *FindParent(const Neighbor::AddressMatcher &aMatcher);
Neighbor *FindNeighbor(const Neighbor::AddressMatcher &aMatcher);
#if OPENTHREAD_FTD
Neighbor *FindChildOrRouter(const Neighbor::AddressMatcher &aMatcher);
#endif
};
} // namespace ot
#endif // NEIGHBOR_TABLE_HPP_
+5
View File
@@ -373,6 +373,11 @@ Router *RouterTable::GetNeighbor(const Mac::ExtAddress &aExtAddress)
return FindRouter(Router::AddressMatcher(aExtAddress, Router::kInStateValid));
}
Router *RouterTable::GetNeighbor(const Mac::Address &aMacAddress)
{
return FindRouter(Router::AddressMatcher(aMacAddress, Router::kInStateValid));
}
const Router *RouterTable::GetRouter(uint8_t aRouterId) const
{
const Router *router = nullptr;
+11
View File
@@ -44,6 +44,7 @@ namespace ot {
class RouterTable : public InstanceLocator
{
friend class NeighborTable;
class IteratorBuilder;
public:
@@ -271,6 +272,16 @@ public:
*/
Router *GetNeighbor(const Mac::ExtAddress &aExtAddress);
/**
* This method returns the neighbor for a given MAC address.
*
* @param[in] aMacAddress A MAC address
*
* @returns A pointer to the router or nullptr if the router could not be found.
*
*/
Router *GetNeighbor(const Mac::Address &aMacAddress);
/**
* This method returns the router for a given router id.
*
+1 -1
View File
@@ -207,7 +207,7 @@ void SupervisionListener::UpdateOnReceive(const Mac::Address &aSourceAddress, bo
// If listener is enabled and device is a child and it received a secure frame from its parent, restart the timer.
VerifyOrExit(mTimer.IsRunning() && aIsSecure && Get<Mle::MleRouter>().IsChild() &&
(Get<Mle::MleRouter>().GetNeighbor(aSourceAddress) == &Get<Mle::MleRouter>().GetParent()),
(Get<NeighborTable>().FindNeighbor(aSourceAddress) == &Get<Mle::MleRouter>().GetParent()),
OT_NOOP);
RestartTimer();