[joiner] update Joiner implementations

This commit contains the following changes to `Joiner` class
implementations:

- Notifier events are signaled on all `Joiner` state changes
  and are logged (through use of `Joiner::SetState()`).
- Discover scan during join uses filtering (removes the need
  to perform filtering by the `Joiner` class itself).
- `Joiner::Stop()` is changed to allow it to be called at any
  stage of join process and it correctly cleans all states.
- Priority assignment to discovered networks is updated/fixed
  (prioritizing networks with an exact match of Joiner ID in their
  Steering Data compared to ones that allow all joiners, and
  sub-prioritize based on signal strength).
- Logs are updated.
This commit is contained in:
Abtin Keshavarzian
2019-04-04 09:14:30 -07:00
committed by Jonathan Hui
parent 873a710a1a
commit 83c9270c29
2 changed files with 297 additions and 211 deletions
+269 -183
View File
@@ -38,10 +38,8 @@
#include <stdio.h>
#include <openthread/platform/radio.h>
#include <openthread/platform/random.h>
#include "common/code_utils.hpp"
#include "common/crc16.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "common/instance.hpp"
@@ -64,8 +62,7 @@ Joiner::Joiner(Instance &aInstance)
, mState(OT_JOINER_STATE_IDLE)
, mCallback(NULL)
, mContext(NULL)
, mCcitt(0)
, mAnsi(0)
, mJoinerRouterIndex(0)
, mVendorName(NULL)
, mVendorModel(NULL)
, mVendorSwVersion(NULL)
@@ -83,6 +80,18 @@ void Joiner::GetJoinerId(Mac::ExtAddress &aJoinerId) const
ComputeJoinerId(aJoinerId, aJoinerId);
}
void Joiner::SetState(otJoinerState aState)
{
VerifyOrExit(aState != mState);
otLogInfoMeshCoP("JoinerState: %s -> %s", JoinerStateToString(mState), JoinerStateToString(aState));
mState = aState;
Get<Notifier>().Signal(OT_CHANGED_JOINER_STATE);
exit:
return;
}
otError Joiner::Start(const char * aPSKd,
const char * aProvisioningUrl,
const char * aVendorName,
@@ -94,90 +103,122 @@ otError Joiner::Start(const char * aPSKd,
{
otError error;
Mac::ExtAddress joinerId;
Crc16 ccitt(Crc16::kCcitt);
Crc16 ansi(Crc16::kAnsi);
otLogInfoMeshCoP("Joiner starting");
VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_BUSY);
Get<Notifier>().Signal(OT_CHANGED_JOINER_STATE);
// use extended address based on factory-assigned IEEE EUI-64
// Use extended address based on factory-assigned IEEE EUI-64
GetJoinerId(joinerId);
Get<Mac::Mac>().SetExtAddress(joinerId);
Get<Mle::MleRouter>().UpdateLinkLocalAddress();
for (size_t i = 0; i < sizeof(joinerId); i++)
SuccessOrExit(error = Get<Coap::CoapSecure>().Start(kJoinerUdpPort));
SuccessOrExit(error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
static_cast<uint8_t>(strlen(aPSKd))));
SuccessOrExit(error = Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
for (JoinerRouter *router = &mJoinerRouters[0]; router < OT_ARRAY_END(mJoinerRouters); router++)
{
ccitt.Update(joinerId.m8[i]);
ansi.Update(joinerId.m8[i]);
router->mPriority = 0; // Priority zero means entry is not in-use.
}
mCcitt = ccitt.Get();
mAnsi = ansi.Get();
error = Get<Coap::CoapSecure>().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
SuccessOrExit(error);
error =
Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd), static_cast<uint8_t>(strlen(aPSKd)));
SuccessOrExit(error);
error = Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
SuccessOrExit(error);
memset(mJoinerRouters, 0, sizeof(mJoinerRouters));
SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(), true, false,
SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
/* aJoiner */ true, /* aEnableFiltering */ true,
HandleDiscoverResult, this));
mVendorName = aVendorName;
mVendorModel = aVendorModel;
mVendorSwVersion = aVendorSwVersion;
mVendorData = aVendorData;
mCallback = aCallback;
mContext = aContext;
mState = OT_JOINER_STATE_DISCOVER;
SetState(OT_JOINER_STATE_DISCOVER);
exit:
if (error != OT_ERROR_NONE)
{
otLogInfoMeshCoP("Error %s while starting joiner", otThreadErrorToString(error));
}
return error;
}
void Joiner::Stop(void)
{
Close();
otLogInfoMeshCoP("Joiner stopped");
// Callback is set to `NULL` to skip calling it from `Finish()`
mCallback = NULL;
Finish(OT_ERROR_ABORT);
}
otJoinerState Joiner::GetState(void) const
void Joiner::Finish(otError aError)
{
return mState;
}
void Joiner::Close(void)
{
Get<Coap::CoapSecure>().Disconnect();
Get<Ip6::Filter>().RemoveUnsecurePort(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
}
void Joiner::Complete(otError aError)
{
mState = OT_JOINER_STATE_IDLE;
otError error = OT_ERROR_NOT_FOUND;
Get<Notifier>().Signal(OT_CHANGED_JOINER_STATE);
Get<Coap::CoapSecure>().Disconnect();
if (aError != OT_ERROR_NONE && aError != OT_ERROR_NOT_FOUND)
switch (mState)
{
error = TryNextJoin();
}
case OT_JOINER_STATE_IDLE:
ExitNow();
if (error == OT_ERROR_NOT_FOUND && mCallback)
{
case OT_JOINER_STATE_CONNECT:
case OT_JOINER_STATE_CONNECTED:
case OT_JOINER_STATE_ENTRUST:
case OT_JOINER_STATE_JOINED:
Get<Coap::CoapSecure>().Disconnect();
Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort);
mTimer.Stop();
// Fall through
case OT_JOINER_STATE_DISCOVER:
Get<Coap::CoapSecure>().Stop();
otJoinerCallback callback = mCallback;
mCallback = NULL;
callback(aError, mContext);
break;
}
SetState(OT_JOINER_STATE_IDLE);
if (mCallback)
{
mCallback(aError, mContext);
}
exit:
return;
}
uint8_t Joiner::CalculatePriority(int8_t aRssi, bool aSteeringDataAllowsAny)
{
int16_t priority;
if (aRssi == OT_RADIO_RSSI_INVALID)
{
aRssi = -127;
}
// Limit the RSSI to range (-128, 0), i.e. -128 < aRssi < 0.
if (aRssi <= -128)
{
priority = -127;
}
else if (aRssi >= 0)
{
priority = -1;
}
else
{
priority = aRssi;
}
// Assign higher priority to networks with an exact match of Joiner
// ID in the Steering Data (128 < priority < 256) compared to ones
// that allow all Joiners (0 < priority < 128). Sub-prioritize
// based on signal strength. Priority 0 is reserved for unused
// entry.
priority += aSteeringDataAllowsAny ? 128 : 256;
return static_cast<uint8_t>(priority);
}
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
@@ -187,117 +228,137 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
{
VerifyOrExit(mState == OT_JOINER_STATE_DISCOVER);
if (aResult != NULL)
{
JoinerRouter joinerRouter;
otLogDebgMeshCoP("Received Discovery Response (%s)",
static_cast<Mac::ExtAddress &>(aResult->mExtAddress).ToString().AsCString());
// Joining is disabled if the Steering Data is not included
if (aResult->mSteeringData.mLength == 0)
{
otLogDebgMeshCoP("No steering data, joining disabled");
ExitNow();
}
SteeringDataTlv steeringData;
steeringData.SetLength(aResult->mSteeringData.mLength);
memcpy(steeringData.GetValue(), aResult->mSteeringData.m8, steeringData.GetLength());
if (!steeringData.GetBit(mCcitt % steeringData.GetNumBits()) ||
!steeringData.GetBit(mAnsi % steeringData.GetNumBits()))
{
otLogDebgMeshCoP("Steering data does not include this device");
ExitNow();
}
joinerRouter.mPriority = static_cast<uint16_t>(aResult->mRssi) + 0x80;
if (!steeringData.DoesAllowAny())
{
joinerRouter.mPriority += kSpecificPriorityBonus;
}
joinerRouter.mJoinerUdpPort = aResult->mJoinerUdpPort;
joinerRouter.mPanId = aResult->mPanId;
joinerRouter.mChannel = aResult->mChannel;
joinerRouter.mExtAddr = static_cast<Mac::ExtAddress &>(aResult->mExtAddress);
AddJoinerRouter(joinerRouter);
SaveDiscoveredJoinerRouter(*aResult);
}
else
{
otError error = TryNextJoin();
if (error != OT_ERROR_NONE)
{
Complete(error);
}
mJoinerRouterIndex = 0;
TryNextJoinerRouter(OT_ERROR_NONE);
}
exit:
return;
}
void Joiner::AddJoinerRouter(JoinerRouter &aJoinerRouter)
void Joiner::SaveDiscoveredJoinerRouter(const otActiveScanResult &aResult)
{
JoinerRouter *joinerRouter = &mJoinerRouters[0];
uint8_t priority;
bool doesAllowAny = true;
JoinerRouter *end = OT_ARRAY_END(mJoinerRouters);
JoinerRouter *entry;
// Find the lowest priority
for (size_t i = 1; i < OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES; i++)
// Check whether Steering Data allows any joiner (it is all 0xff).
for (uint8_t i = 0; i < aResult.mSteeringData.mLength; i++)
{
if (mJoinerRouters[i].mPriority < joinerRouter->mPriority)
if (aResult.mSteeringData.m8[i] != 0xff)
{
joinerRouter = &mJoinerRouters[i];
doesAllowAny = false;
break;
}
}
if (joinerRouter->mPriority == 0)
otLogInfoMeshCoP("Joiner discover network: %s, pan:0x%04x, port:%d, chan:%d, rssi:%d, allow-any:%s",
static_cast<const Mac::ExtAddress &>(aResult.mExtAddress).ToString().AsCString(), aResult.mPanId,
aResult.mJoinerUdpPort, aResult.mChannel, aResult.mRssi, doesAllowAny ? "yes" : "no");
priority = CalculatePriority(aResult.mRssi, doesAllowAny);
// We keep the list sorted based on priority. Find the place to
// add the new result.
for (entry = &mJoinerRouters[0]; entry < end; entry++)
{
if (priority > entry->mPriority)
{
break;
}
}
if (aJoinerRouter.mPriority > joinerRouter->mPriority)
{
memcpy(joinerRouter, &aJoinerRouter, sizeof(aJoinerRouter));
}
VerifyOrExit(entry < end);
// Shift elements in array to make room for the new one.
memmove(entry + 1, entry,
static_cast<size_t>(reinterpret_cast<uint8_t *>(end - 1) - reinterpret_cast<uint8_t *>(entry)));
entry->mExtAddr = static_cast<const Mac::ExtAddress &>(aResult.mExtAddress);
entry->mPanId = aResult.mPanId;
entry->mJoinerUdpPort = aResult.mJoinerUdpPort;
entry->mChannel = aResult.mChannel;
entry->mPriority = priority;
exit:
return;
}
otError Joiner::TryNextJoin()
void Joiner::TryNextJoinerRouter(otError aPrevError)
{
otError error = OT_ERROR_NOT_FOUND;
JoinerRouter *joinerRouter = &mJoinerRouters[0];
for (size_t i = 1; i < OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES; i++)
for (; mJoinerRouterIndex < OT_ARRAY_LENGTH(mJoinerRouters); mJoinerRouterIndex++)
{
if (mJoinerRouters[i].mPriority > joinerRouter->mPriority)
JoinerRouter &router = mJoinerRouters[mJoinerRouterIndex];
otError error;
if (router.mPriority == 0)
{
joinerRouter = &mJoinerRouters[i];
break;
}
error = Connect(router);
VerifyOrExit(error != OT_ERROR_NONE, mJoinerRouterIndex++);
// Save the error from `Connect` only if there is no previous
// error from earlier attempts. This ensures that if there has
// been a previous Joiner Router connect attempt where
// `Connect()` call itself was successful, the error status
// emitted from `Finish()` call corresponds to the error from
// that attempt.
if (aPrevError == OT_ERROR_NONE)
{
aPrevError = error;
}
}
if (joinerRouter->mPriority > 0)
if (aPrevError == OT_ERROR_NONE)
{
Ip6::SockAddr sockaddr;
joinerRouter->mPriority = 0;
Get<Mac::Mac>().SetPanId(joinerRouter->mPanId);
Get<Mac::Mac>().SetPanChannel(joinerRouter->mChannel);
Get<Ip6::Filter>().AddUnsecurePort(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
sockaddr.GetAddress().mFields.m16[0] = HostSwap16(0xfe80);
sockaddr.GetAddress().SetIid(joinerRouter->mExtAddr);
sockaddr.mPort = joinerRouter->mJoinerUdpPort;
sockaddr.mScopeId = OT_NETIF_INTERFACE_ID_THREAD;
Get<Coap::CoapSecure>().Connect(sockaddr, Joiner::HandleSecureCoapClientConnect, this);
mState = OT_JOINER_STATE_CONNECT;
error = OT_ERROR_NONE;
aPrevError = OT_ERROR_NOT_FOUND;
}
else
Finish(aPrevError);
exit:
return;
}
otError Joiner::Connect(JoinerRouter &aRouter)
{
otError error = OT_ERROR_NOT_FOUND;
Ip6::SockAddr sockaddr;
otLogInfoMeshCoP("Joiner connecting to %s, pan:0x%04x, chan:%d", aRouter.mExtAddr.ToString().AsCString(),
aRouter.mPanId, aRouter.mChannel);
Get<Mac::Mac>().SetPanId(aRouter.mPanId);
SuccessOrExit(error = Get<Mac::Mac>().SetPanChannel(aRouter.mChannel));
SuccessOrExit(error = Get<Ip6::Filter>().AddUnsecurePort(kJoinerUdpPort));
sockaddr.GetAddress().mFields.m16[0] = HostSwap16(0xfe80);
sockaddr.GetAddress().SetIid(aRouter.mExtAddr);
sockaddr.mPort = aRouter.mJoinerUdpPort;
sockaddr.mScopeId = OT_NETIF_INTERFACE_ID_THREAD;
SuccessOrExit(error = Get<Coap::CoapSecure>().Connect(sockaddr, Joiner::HandleSecureCoapClientConnect, this));
SetState(OT_JOINER_STATE_CONNECT);
exit:
if (error != OT_ERROR_NONE)
{
otLogDebgMeshCoP("No joinable networks remaining to try");
otLogInfoMeshCoP("Error %s while joiner trying to connect", otThreadErrorToString(error));
}
return error;
@@ -310,25 +371,21 @@ void Joiner::HandleSecureCoapClientConnect(bool aConnected, void *aContext)
void Joiner::HandleSecureCoapClientConnect(bool aConnected)
{
switch (mState)
VerifyOrExit(mState == OT_JOINER_STATE_CONNECT);
if (aConnected)
{
case OT_JOINER_STATE_CONNECT:
if (aConnected)
{
mState = OT_JOINER_STATE_CONNECTED;
SendJoinerFinalize();
mTimer.Start(kTimeout);
}
else
{
Complete(OT_ERROR_SECURITY);
}
break;
default:
break;
SetState(OT_JOINER_STATE_CONNECTED);
SendJoinerFinalize();
mTimer.Start(kReponseTimeout);
}
else
{
TryNextJoinerRouter(OT_ERROR_SECURITY);
}
exit:
return;
}
void Joiner::SendJoinerFinalize(void)
@@ -386,16 +443,12 @@ void Joiner::SendJoinerFinalize(void)
}
#if OPENTHREAD_ENABLE_CERT_LOG
uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE];
VerifyOrExit(message->GetLength() <= sizeof(buf));
message->Read(message->GetOffset(), message->GetLength() - message->GetOffset(), buf);
otDumpCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.req |", buf, message->GetLength() - message->GetOffset());
LogCertMessage("[THCI] direction=send | type=JOIN_FIN.req |", *message);
#endif
SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, Joiner::HandleJoinerFinalizeResponse, this));
otLogInfoMeshCoP("Sent joiner finalize");
otLogInfoMeshCoP("Joiner sent finalize");
exit:
@@ -428,20 +481,18 @@ void Joiner::HandleJoinerFinalizeResponse(Coap::Message & aMessage,
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
VerifyOrExit(state.IsValid());
mState = OT_JOINER_STATE_ENTRUST;
mTimer.Start(kTimeout);
SetState(OT_JOINER_STATE_ENTRUST);
mTimer.Start(kReponseTimeout);
otLogInfoMeshCoP("Joiner received finalize response %d", static_cast<uint8_t>(state.GetState()));
otLogInfoMeshCoP("received joiner finalize response %d", static_cast<uint8_t>(state.GetState()));
#if OPENTHREAD_ENABLE_CERT_LOG
uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE];
VerifyOrExit(aMessage.GetLength() <= sizeof(buf));
aMessage.Read(aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset(), buf);
otDumpCertMeshCoP("[THCI] direction=recv | type=JOIN_FIN.rsp |", buf, aMessage.GetLength() - aMessage.GetOffset());
LogCertMessage("[THCI] direction=recv | type=JOIN_FIN.rsp |", aMessage);
#endif
exit:
Close();
Get<Coap::CoapSecure>().Disconnect();
Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort);
}
void Joiner::HandleJoinerEntrust(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -464,7 +515,7 @@ void Joiner::HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo
aMessage.GetCode() == OT_COAP_CODE_POST,
error = OT_ERROR_DROP);
otLogInfoMeshCoP("Received joiner entrust");
otLogInfoMeshCoP("Joiner received entrust");
otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_ENT.ntf");
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey));
@@ -490,17 +541,10 @@ void Joiner::HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo
Get<Mle::MleRouter>().SetMeshLocalPrefix(meshLocalPrefix.GetMeshLocalPrefix());
Get<Mac::Mac>().SetExtendedPanId(extendedPanId.GetExtendedPanId());
{
otNetworkName name;
Get<Mac::Mac>().SetNetworkName(networkName.GetNetworkName(), networkName.GetLength());
memcpy(name.m8, networkName.GetNetworkName(), networkName.GetLength());
name.m8[networkName.GetLength()] = '\0';
Get<Mac::Mac>().SetNetworkName(name.m8);
}
otLogInfoMeshCoP("Joiner successful!");
otLogInfoMeshCoP("join success!");
// Send dummy response.
SendJoinerEntrustResponse(aMessage, aMessageInfo);
// Delay extended address configuration to allow DTLS wrap up.
@@ -510,7 +554,7 @@ exit:
if (error != OT_ERROR_NONE)
{
otLogWarnMeshCoP("Error while processing joiner entrust: %s", otThreadErrorToString(error));
otLogWarnMeshCoP("Error %s while processing joiner entrust", otThreadErrorToString(error));
}
}
@@ -527,11 +571,9 @@ void Joiner::SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6:
memset(&responseInfo.mSockAddr, 0, sizeof(responseInfo.mSockAddr));
SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, responseInfo));
mState = OT_JOINER_STATE_JOINED;
SetState(OT_JOINER_STATE_JOINED);
otLogInfoArp("Sent Joiner Entrust response");
otLogInfoMeshCoP("Sent joiner entrust response length = %d", message->GetLength());
otLogInfoMeshCoP("Joiner sent entrust response");
otLogCertMeshCoP("[THCI] direction=send | type=JOIN_ENT.rsp");
exit:
@@ -575,9 +617,53 @@ void Joiner::HandleTimer(void)
break;
}
Complete(error);
Finish(error);
}
const char *Joiner::JoinerStateToString(otJoinerState aState)
{
const char *str = "Unknown";
switch (aState)
{
case OT_JOINER_STATE_IDLE:
str = "Idle";
break;
case OT_JOINER_STATE_DISCOVER:
str = "Discover";
break;
case OT_JOINER_STATE_CONNECT:
str = "Connecting";
break;
case OT_JOINER_STATE_CONNECTED:
str = "Connected";
break;
case OT_JOINER_STATE_ENTRUST:
str = "Entrust";
break;
case OT_JOINER_STATE_JOINED:
str = "Joined";
break;
}
return str;
}
#if OPENTHREAD_ENABLE_CERT_LOG
void Joiner::LogCertMessage(const char *aText, const Coap::Message &aMessage) const
{
uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE];
VerifyOrExit(aMessage.GetLength() <= sizeof(buf));
aMessage.Read(aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset(), buf);
otDumpCertMeshCoP(aText, buf, aMessage.GetLength() - aMessage.GetOffset());
exit:
return;
}
#endif
} // namespace MeshCoP
} // namespace ot
+28 -28
View File
@@ -41,12 +41,12 @@
#include "coap/coap.hpp"
#include "coap/coap_message.hpp"
#include "coap/coap_secure.hpp"
#include "common/crc16.hpp"
#include "common/locator.hpp"
#include "common/logging.hpp"
#include "common/message.hpp"
#include "mac/mac_frame.hpp"
#include "meshcop/dtls.hpp"
#include "meshcop/meshcop_tlvs.hpp"
#include "net/udp6.hpp"
namespace ot {
@@ -96,15 +96,10 @@ public:
/**
* This function returns the Joiner State.
*
* @retval OT_JOINER_STATE_IDLE
* @retval OT_JOINER_STATE_DISCOVER
* @retval OT_JOINER_STATE_CONNECT
* @retval OT_JOINER_STATE_CONNECTED
* @retval OT_JOINER_STATE_ENTRUST
* @retval OT_JOINER_STATE_JOINED
* @returns The Joiner state (see `otJoinerState`).
*
*/
otJoinerState GetState(void) const;
otJoinerState GetState(void) const { return mState; }
/**
* This method retrieves the Joiner ID.
@@ -117,36 +112,26 @@ public:
private:
enum
{
kConfigExtAddressDelay = 100, ///< milliseconds
kTimeout = 4000, ///< milliseconds
kSpecificPriorityBonus = (1 << 9),
kJoinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT,
kConfigExtAddressDelay = 100, ///< [milliseconds]
kReponseTimeout = 4000, ///< Maximum wait time to receive response [milliseconds].
};
struct JoinerRouter
{
Mac::ExtAddress mExtAddr;
uint16_t mPriority;
uint16_t mPanId;
Mac::PanId mPanId;
uint16_t mJoinerUdpPort;
uint8_t mChannel;
uint8_t mPriority;
};
static void HandleDiscoverResult(otActiveScanResult *aResult, void *aContext);
void HandleDiscoverResult(otActiveScanResult *aResult);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
void Close(void);
void Complete(otError aError);
void AddJoinerRouter(JoinerRouter &aJoinerRouter);
otError TryNextJoin();
static void HandleSecureCoapClientConnect(bool aConnected, void *aContext);
void HandleSecureCoapClientConnect(bool aConnected);
void SendJoinerFinalize(void);
static void HandleJoinerFinalizeResponse(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
@@ -155,17 +140,32 @@ private:
static void HandleJoinerEntrust(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
static const char *JoinerStateToString(otJoinerState aState);
void SetState(otJoinerState aState);
void SaveDiscoveredJoinerRouter(const otActiveScanResult &aResult);
void TryNextJoinerRouter(otError aPrevError);
otError Connect(JoinerRouter &aRouter);
void Finish(otError aError);
uint8_t CalculatePriority(int8_t aRssi, bool aSteeringDataAllowsAny);
void SendJoinerFinalize(void);
void SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo);
#if OPENTHREAD_ENABLE_CERT_LOG
void LogCertMessage(const char *aText, const Coap::Message &aMessage) const;
#endif
otJoinerState mState;
otJoinerCallback mCallback;
void * mContext;
uint16_t mCcitt;
uint16_t mAnsi;
JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES];
uint16_t mJoinerRouterIndex;
const char *mVendorName;
const char *mVendorModel;