mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 00:27:47 +00:00
[meshcop] implement a prioritized queue for Joiner Routers (#2152)
This commit is contained in:
committed by
Jonathan Hui
parent
cb03cd607a
commit
b3f60ff713
+98
-50
@@ -67,11 +67,6 @@ Joiner::Joiner(ThreadNetif &aNetif):
|
||||
mContext(NULL),
|
||||
mCcitt(0),
|
||||
mAnsi(0),
|
||||
mJoinerRouterIsSpecific(false),
|
||||
mJoinerRouterChannel(0),
|
||||
mJoinerRouterRssi(0),
|
||||
mJoinerRouterPanId(0),
|
||||
mJoinerUdpPort(0),
|
||||
mVendorName(NULL),
|
||||
mVendorModel(NULL),
|
||||
mVendorSwVersion(NULL),
|
||||
@@ -79,6 +74,7 @@ Joiner::Joiner(ThreadNetif &aNetif):
|
||||
mTimer(aNetif.GetInstance(), &Joiner::HandleTimer, this),
|
||||
mJoinerEntrust(OT_URI_PATH_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this)
|
||||
{
|
||||
memset(mJoinerRouters, 0, sizeof(mJoinerRouters));
|
||||
aNetif.GetCoap().AddResource(mJoinerEntrust);
|
||||
}
|
||||
|
||||
@@ -122,9 +118,8 @@ otError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl,
|
||||
error = netif.GetCoapSecure().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
|
||||
SuccessOrExit(error);
|
||||
|
||||
mJoinerRouterPanId = Mac::kPanIdBroadcast;
|
||||
mJoinerRouterRssi = 0;
|
||||
mJoinerRouterIsSpecific = false;
|
||||
memset(mJoinerRouters, 0, sizeof(mJoinerRouters));
|
||||
|
||||
SuccessOrExit(error = netif.GetMle().Discover(0, netif.GetMac().GetPanId(), true, false, HandleDiscoverResult,
|
||||
this));
|
||||
|
||||
@@ -169,13 +164,21 @@ void Joiner::Close(void)
|
||||
|
||||
void Joiner::Complete(otError aError)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
mState = OT_JOINER_STATE_IDLE;
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
GetNetif().SetStateChangedFlags(OT_CHANGED_JOINER_STATE);
|
||||
|
||||
GetNetif().GetCoapSecure().Stop();
|
||||
netif.GetCoapSecure().Disconnect();
|
||||
|
||||
if (mCallback)
|
||||
if (aError != OT_ERROR_NONE && aError != OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
error = TryNextJoin();
|
||||
}
|
||||
|
||||
if (error == OT_ERROR_NOT_FOUND && mCallback)
|
||||
{
|
||||
netif.GetCoapSecure().Stop();
|
||||
otJoinerCallback callback = mCallback;
|
||||
mCallback = NULL;
|
||||
callback(aError, mContext);
|
||||
@@ -189,13 +192,12 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
|
||||
|
||||
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
if (aResult != NULL)
|
||||
{
|
||||
JoinerRouter joinerRouter;
|
||||
|
||||
otLogFuncEntryMsg("aResult = %llX", HostSwap64(*reinterpret_cast<uint64_t *>(&aResult->mExtAddress)));
|
||||
|
||||
// Joining is disabled if the Steering Data is not included
|
||||
@@ -209,59 +211,105 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
steeringData.SetLength(aResult->mSteeringData.mLength);
|
||||
memcpy(steeringData.GetValue(), aResult->mSteeringData.m8, steeringData.GetLength());
|
||||
|
||||
if (steeringData.DoesAllowAny())
|
||||
{
|
||||
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
|
||||
if (!steeringData.GetBit(mCcitt % steeringData.GetNumBits()) ||
|
||||
!steeringData.GetBit(mAnsi % steeringData.GetNumBits()))
|
||||
{
|
||||
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)
|
||||
{
|
||||
otLogFuncEntryMsg("aResult = NULL");
|
||||
joinerRouter.mPriority = static_cast<uint16_t>(aResult->mRssi) + 0x80;
|
||||
|
||||
netif.GetMac().SetPanId(mJoinerRouterPanId);
|
||||
netif.GetMac().SetChannel(mJoinerRouterChannel);
|
||||
netif.GetIp6Filter().AddUnsecurePort(netif.GetCoapSecure().GetPort());
|
||||
if (!steeringData.DoesAllowAny())
|
||||
{
|
||||
joinerRouter.mPriority += kSpecificPriorityBonus;
|
||||
}
|
||||
|
||||
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
|
||||
messageInfo.GetPeerAddr().SetIid(mJoinerRouter);
|
||||
messageInfo.mPeerPort = mJoinerUdpPort;
|
||||
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
|
||||
|
||||
netif.GetCoapSecure().Connect(messageInfo, Joiner::HandleSecureCoapClientConnect, this);
|
||||
mState = OT_JOINER_STATE_CONNECT;
|
||||
joinerRouter.mJoinerUdpPort = aResult->mJoinerUdpPort;
|
||||
joinerRouter.mPanId = aResult->mPanId;
|
||||
joinerRouter.mChannel = aResult->mChannel;
|
||||
memcpy(joinerRouter.mExtAddr.m8, &aResult->mExtAddress, sizeof(joinerRouter.mExtAddr));
|
||||
AddJoinerRouter(joinerRouter);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogDebgMeshCoP(GetInstance(), "No joinable network found");
|
||||
Complete(OT_ERROR_NOT_FOUND);
|
||||
otError error = TryNextJoin();
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
Complete(error);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Joiner::AddJoinerRouter(JoinerRouter &aJoinerRouter)
|
||||
{
|
||||
JoinerRouter *joinerRouter = &mJoinerRouters[0];
|
||||
|
||||
// Find the lowest priority
|
||||
for (size_t i = 1; i < OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES; i++)
|
||||
{
|
||||
if (mJoinerRouters[i].mPriority < joinerRouter->mPriority)
|
||||
{
|
||||
joinerRouter = &mJoinerRouters[i];
|
||||
}
|
||||
|
||||
if (joinerRouter->mPriority == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aJoinerRouter.mPriority > joinerRouter->mPriority)
|
||||
{
|
||||
memcpy(joinerRouter, &aJoinerRouter, sizeof(aJoinerRouter));
|
||||
}
|
||||
}
|
||||
|
||||
otError Joiner::TryNextJoin()
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
JoinerRouter *joinerRouter = &mJoinerRouters[0];
|
||||
|
||||
for (size_t i = 1; i < OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES; i++)
|
||||
{
|
||||
if (mJoinerRouters[i].mPriority > joinerRouter->mPriority)
|
||||
{
|
||||
joinerRouter = &mJoinerRouters[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (joinerRouter->mPriority > 0)
|
||||
{
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
joinerRouter->mPriority = 0;
|
||||
|
||||
netif.GetMac().SetPanId(joinerRouter->mPanId);
|
||||
netif.GetMac().SetChannel(joinerRouter->mChannel);
|
||||
netif.GetIp6Filter().AddUnsecurePort(netif.GetCoapSecure().GetPort());
|
||||
|
||||
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
|
||||
messageInfo.GetPeerAddr().SetIid(joinerRouter->mExtAddr);
|
||||
messageInfo.mPeerPort = joinerRouter->mJoinerUdpPort;
|
||||
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
|
||||
|
||||
netif.GetCoapSecure().Connect(messageInfo, Joiner::HandleSecureCoapClientConnect, this);
|
||||
mState = OT_JOINER_STATE_CONNECT;
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogDebgMeshCoP(GetInstance(), "No joinable networks remaining to try");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Joiner::HandleSecureCoapClientConnect(bool aConnected, void *aContext)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleSecureCoapClientConnect(aConnected);
|
||||
|
||||
@@ -111,6 +111,16 @@ private:
|
||||
{
|
||||
kConfigExtAddressDelay = 100, ///< milliseconds
|
||||
kTimeout = 4000, ///< milliseconds
|
||||
kSpecificPriorityBonus = (1 << 9),
|
||||
};
|
||||
|
||||
struct JoinerRouter
|
||||
{
|
||||
Mac::ExtAddress mExtAddr;
|
||||
uint16_t mPriority;
|
||||
uint16_t mPanId;
|
||||
uint16_t mJoinerUdpPort;
|
||||
uint8_t mChannel;
|
||||
};
|
||||
|
||||
static void HandleDiscoverResult(otActiveScanResult *aResult, void *aContext);
|
||||
@@ -122,6 +132,9 @@ private:
|
||||
void Close(void);
|
||||
void Complete(otError aError);
|
||||
|
||||
void AddJoinerRouter(JoinerRouter &aJoinerRouter);
|
||||
otError TryNextJoin();
|
||||
|
||||
static void HandleSecureCoapClientConnect(bool aConnected, void *aContext);
|
||||
void HandleSecureCoapClientConnect(bool aConnected);
|
||||
|
||||
@@ -146,12 +159,7 @@ private:
|
||||
uint16_t mCcitt;
|
||||
uint16_t mAnsi;
|
||||
|
||||
bool mJoinerRouterIsSpecific;
|
||||
uint8_t mJoinerRouterChannel;
|
||||
int8_t mJoinerRouterRssi;
|
||||
uint16_t mJoinerRouterPanId;
|
||||
uint16_t mJoinerUdpPort;
|
||||
Mac::ExtAddress mJoinerRouter;
|
||||
JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES];
|
||||
|
||||
const char *mVendorName;
|
||||
const char *mVendorModel;
|
||||
|
||||
@@ -305,6 +305,16 @@
|
||||
#define OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES 2
|
||||
#endif // OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES
|
||||
*
|
||||
* The maximum number of Joiner Router entries that can be queued by the Joiner.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES
|
||||
#define OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES 2
|
||||
#endif // OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user