From c57908ce9e2b04a2f048e97015c93020867fa50b Mon Sep 17 00:00:00 2001 From: Ciaran Woodward Date: Wed, 30 Aug 2017 16:37:52 +0100 Subject: [PATCH] [meshcop] give priority to better matches during join, not channel (#2137) Previous behaviour of the joiner would result in the joiner joining the network with the highest channel number, rather than the most suitable. This commit utilizes the priority specified in thread spec 1.1.1 section 8.4.4.1.2 to choose the most suited network for joining. This removes the bug where it would be impossible to join the desired network due to another network on a higher channel allowing all joiners in the steering data. --- src/core/meshcop/joiner.cpp | 31 ++++++++++++++++++++++++------- src/core/meshcop/joiner.hpp | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 58efebd32..d3eb6ad26 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -67,7 +67,9 @@ Joiner::Joiner(ThreadNetif &aNetif): mContext(NULL), mCcitt(0), mAnsi(0), + mJoinerRouterIsSpecific(false), mJoinerRouterChannel(0), + mJoinerRouterRssi(0), mJoinerRouterPanId(0), mJoinerUdpPort(0), mVendorName(NULL), @@ -119,6 +121,8 @@ otError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl, SuccessOrExit(error); mJoinerRouterPanId = Mac::kPanIdBroadcast; + mJoinerRouterRssi = 0; + mJoinerRouterIsSpecific = false; SuccessOrExit(error = netif.GetMle().Discover(0, netif.GetMac().GetPanId(), true, false, HandleDiscoverResult, this)); @@ -197,19 +201,32 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult) steeringData.SetLength(aResult->mSteeringData.mLength); memcpy(steeringData.GetValue(), aResult->mSteeringData.m8, steeringData.GetLength()); - if (steeringData.DoesAllowAny() || - (steeringData.GetBit(mCcitt % steeringData.GetNumBits()) && - steeringData.GetBit(mAnsi % steeringData.GetNumBits()))) + if (steeringData.DoesAllowAny()) { - mJoinerUdpPort = aResult->mJoinerUdpPort; - mJoinerRouterPanId = aResult->mPanId; - mJoinerRouterChannel = aResult->mChannel; - memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter)); + VerifyOrExit(!mJoinerRouterIsSpecific); + VerifyOrExit(aResult->mRssi > mJoinerRouterRssi); + } + else if (steeringData.GetBit(mCcitt % steeringData.GetNumBits()) && + steeringData.GetBit(mAnsi % steeringData.GetNumBits())) + { + if (mJoinerRouterIsSpecific) + { + VerifyOrExit(aResult->mRssi > mJoinerRouterRssi); + } + + mJoinerRouterIsSpecific = true; } else { otLogDebgMeshCoP(GetInstance(), "Steering data does not include this device"); + ExitNow(); } + + mJoinerUdpPort = aResult->mJoinerUdpPort; + mJoinerRouterPanId = aResult->mPanId; + mJoinerRouterChannel = aResult->mChannel; + mJoinerRouterRssi = aResult->mRssi; + memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter)); } else if (mJoinerRouterPanId != Mac::kPanIdBroadcast) { diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index e67b67a6e..6a3478504 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -140,7 +140,9 @@ private: uint16_t mCcitt; uint16_t mAnsi; + bool mJoinerRouterIsSpecific; uint8_t mJoinerRouterChannel; + int8_t mJoinerRouterRssi; uint16_t mJoinerRouterPanId; uint16_t mJoinerUdpPort; Mac::ExtAddress mJoinerRouter;