From 95d2e8cdecc096efbf3287e6607c7b441086c115 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Fri, 30 Sep 2016 16:09:01 -0700 Subject: [PATCH] Implement `MleRouter::GetNextNeighborInfo()` method (#724) --- include/openthread.h | 5 +-- src/core/openthread.cpp | 8 +++-- src/core/thread/mle_router.cpp | 64 ++++++++++++++++++++++++++++++++++ src/core/thread/mle_router.hpp | 14 ++++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/include/openthread.h b/include/openthread.h index 8261d51ed..23e41cfec 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -1703,8 +1703,9 @@ ThreadError otGetChildInfoByIndex(otInstance *aInstance, uint8_t aChildIndex, ot it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT. * @param[out] aInfo A pointer to where the neighbor information will be placed. * - * @retval kThreadError_None Successfully found the next neighbor entry in table. - * @retval kThreadError_NotFound No subsequent neighbor entry exists in the table. + * @retval kThreadError_None Successfully found the next neighbor entry in table. + * @retval kThreadError_NotFound No subsequent neighbor entry exists in the table. + * @retval kThreadError_InvalidArgs @p aIterator or @p aInfo was NULL. * */ ThreadError otGetNextNeighborInfo(otInstance *aInstance, otNeighborInfoIterator *aIterator, otNeighborInfo *aInfo); diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index c940b824c..daadb1b2d 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -732,11 +732,13 @@ exit: ThreadError otGetNextNeighborInfo(otInstance *, otNeighborInfoIterator *aIterator, otNeighborInfo *aInfo) { - ThreadError error = kThreadError_NotImplemented; + ThreadError error = kThreadError_None; - (void)aIterator; - (void)aInfo; + VerifyOrExit((aInfo != NULL) && (aIterator != NULL), error = kThreadError_InvalidArgs); + error = sThreadNetif->GetMle().GetNextNeighborInfo(*aIterator, *aInfo); + +exit: return error; } diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 87f75dac6..b0c99c303 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2975,6 +2975,70 @@ exit: return error; } +ThreadError MleRouter::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo) +{ + ThreadError error = kThreadError_None; + Neighbor *neighbor = NULL; + int16_t index; + + memset(&aNeighInfo, 0, sizeof(aNeighInfo)); + + // Non-negative iterator value gives the current index into mChildren array + + if (aIterator >= 0) + { + for (index = aIterator; index < mMaxChildrenAllowed; index++) + { + if (mChildren[index].mState == Neighbor::kStateValid) + { + neighbor = &mChildren[index]; + 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++) + { + if (mRouters[index].mState == Neighbor::kStateValid) + { + neighbor = &mRouters[index]; + aNeighInfo.mIsChild = false; + index++; + aIterator = -index; + ExitNow(); + } + } + + aIterator = -index; + error = kThreadError_NotFound; + +exit: + + if (neighbor != NULL) + { + memcpy(&aNeighInfo.mExtAddress, &neighbor->mMacAddr, sizeof(aNeighInfo.mExtAddress)); + aNeighInfo.mAge = Timer::MsecToSec(Timer::GetNow() - neighbor->mLastHeard); + aNeighInfo.mRloc16 = neighbor->mValid.mRloc16; + aNeighInfo.mLinkFrameCounter = neighbor->mValid.mLinkFrameCounter; + aNeighInfo.mMleFrameCounter = neighbor->mValid.mMleFrameCounter; + aNeighInfo.mLinkQualityIn = neighbor->mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor()); + aNeighInfo.mAverageRssi = neighbor->mLinkInfo.GetAverageRss(); + aNeighInfo.mRxOnWhenIdle = (neighbor->mMode & ModeTlv::kModeRxOnWhenIdle) != 0; + aNeighInfo.mSecureDataRequest = (neighbor->mMode & ModeTlv::kModeSecureDataRequest) != 0; + aNeighInfo.mFullFunction = (neighbor->mMode & ModeTlv::kModeFFD) != 0; + aNeighInfo.mFullNetworkData = (neighbor->mMode & ModeTlv::kModeFullNetworkData) != 0; + } + + return error; +} + ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) { Ip6::Address destination; diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 42b1dcc94..81abb7e46 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -523,6 +523,20 @@ public: */ ThreadError GetChildInfoByIndex(uint8_t aChildIndex, otChildInfo &aChildInfo); + /** + * 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 kThreadError_None Successfully found the next neighbor entry in table. + * @retval kThreadError_NotFound No subsequent neighbor entry exists in the table. + * + */ + ThreadError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo); + /** * This method returns a pointer to a Router array. *