From 674bff37fa2807b294eefaac71a8c945129048a5 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 23 Aug 2016 20:47:33 -0700 Subject: [PATCH] Implement a method for removing a neighbor. (#454) --- src/core/mac/mac.cpp | 12 +------- src/core/thread/mle_router.cpp | 56 +++++++++++++++++++++++++++++----- src/core/thread/mle_router.hpp | 21 +++++++++++++ 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index be6609b2c..4b500942a 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -648,7 +648,6 @@ void Mac::SentFrame(bool aAcked) { Frame &sendFrame(*static_cast(otPlatRadioGetTransmitBuffer())); Address destination; - Neighbor *neighbor; Sender *sender; if (sendFrame.GetAckRequest() && !aAcked) @@ -666,16 +665,7 @@ void Mac::SentFrame(bool aAcked) } sendFrame.GetDstAddr(destination); - - if ((neighbor = mMle.GetNeighbor(destination)) != NULL) - { - if (neighbor->mState == Neighbor::kStateValid && !mMle.IsActiveRouter(neighbor->mValid.mRloc16)) - { - mNetif.SetStateChangedFlags(OT_THREAD_CHILD_REMOVED); - } - - neighbor->mState = Neighbor::kStateInvalid; - } + mMle.RemoveNeighbor(destination); } mTransmitAttempts = 0; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 157b71cd9..4b8a0d2f8 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -623,7 +623,7 @@ ThreadError MleRouter::HandleLinkRequest(const Message &aMessage, const Ip6::Mes if ((neighbor = GetNeighbor(macAddr)) != NULL && neighbor->mValid.mRloc16 != rloc16) { // remove stale neighbors - neighbor->mState = Neighbor::kStateInvalid; + RemoveNeighbor(*neighbor); neighbor = NULL; } @@ -807,7 +807,7 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess if ((neighbor = GetNeighbor(macAddr)) != NULL && neighbor->mValid.mRloc16 != sourceAddress.GetRloc16()) { - neighbor->mState = Neighbor::kStateInvalid; + RemoveNeighbor(*neighbor); neighbor = NULL; } @@ -1218,7 +1218,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M if ((neighbor = GetNeighbor(macAddr)) != NULL && neighbor->mValid.mRloc16 != sourceAddress.GetRloc16()) { - neighbor->mState = Neighbor::kStateInvalid; + RemoveNeighbor(*neighbor); } // Leader Data @@ -1608,8 +1608,7 @@ void MleRouter::HandleStateUpdateTimer(void) if ((Timer::GetNow() - mChildren[i].mLastHeard) >= Timer::SecToMsec(mChildren[i].mTimeout)) { - mChildren[i].mState = Neighbor::kStateInvalid; - mNetif.SetStateChangedFlags(OT_THREAD_CHILD_REMOVED); + RemoveNeighbor(mChildren[i]); } } @@ -1828,7 +1827,7 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6:: if (mRouters[i].mState != Neighbor::kStateInvalid && memcmp(&mRouters[i].mMacAddr, &macAddr, sizeof(mRouters[i].mMacAddr)) == 0) { - mRouters[i].mState = Neighbor::kStateInvalid; + RemoveNeighbor(mRouters[i]); break; } } @@ -2282,6 +2281,49 @@ Child *MleRouter::GetChildren(uint8_t *numChildren) return mChildren; } +ThreadError MleRouter::RemoveNeighbor(const Mac::Address &aAddress) +{ + ThreadError error = kThreadError_None; + Neighbor *neighbor; + + VerifyOrExit((neighbor = GetNeighbor(aAddress)) != NULL, error = kThreadError_NotFound); + SuccessOrExit(error = RemoveNeighbor(*neighbor)); + +exit: + return error; +} + +ThreadError MleRouter::RemoveNeighbor(Neighbor &aNeighbor) +{ + switch (mDeviceState) + { + case kDeviceStateDisabled: + case kDeviceStateDetached: + break; + + case kDeviceStateChild: + if (&aNeighbor == &mParent) + { + BecomeDetached(); + } + + break; + + case kDeviceStateRouter: + case kDeviceStateLeader: + if (aNeighbor.mState == Neighbor::kStateValid && !IsActiveRouter(aNeighbor.mValid.mRloc16)) + { + mNetif.SetStateChangedFlags(OT_THREAD_CHILD_REMOVED); + } + + break; + } + + aNeighbor.mState = Neighbor::kStateInvalid; + + return kThreadError_None; +} + Neighbor *MleRouter::GetNeighbor(uint16_t aAddress) { Neighbor *rval = NULL; @@ -2885,7 +2927,7 @@ void MleRouter::HandleAddressSolicitResponse(Message &aMessage) case Neighbor::kStateValid: if (GetRouterId(mChildren[i].mValid.mRloc16) != mRouterId) { - mChildren[i].mState = Neighbor::kStateInvalid; + RemoveNeighbor(mChildren[i]); } break; diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index d70ffb1de..67fee82c2 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -245,6 +245,27 @@ public: */ ThreadError ReleaseRouterId(uint8_t aRouterId); + /** + * This method removes a link to a neighbor. + * + * @param[in] aAddress The link address of the neighbor. + * + * @retval kThreadError_None Successfully removed the neighbor. + * @retval kThreadError_NotFound Could not find the neighbor. + * + */ + ThreadError RemoveNeighbor(const Mac::Address &aAddress); + + /** + * This method removes a link to a neighbor. + * + * @param[in] aNeighbor A reference to the neighbor object. + * + * @retval kThreadError_None Successfully removed the neighbor. + * + */ + ThreadError RemoveNeighbor(Neighbor &aNeighbor); + /** * This method returns a pointer to a Child object. *