diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index cea472d7d..c9b58c140 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -38,10 +38,8 @@ #include #include -#include #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().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().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().SetExtAddress(joinerId); Get().UpdateLinkLocalAddress(); - for (size_t i = 0; i < sizeof(joinerId); i++) + SuccessOrExit(error = Get().Start(kJoinerUdpPort)); + SuccessOrExit(error = Get().SetPsk(reinterpret_cast(aPSKd), + static_cast(strlen(aPSKd)))); + SuccessOrExit(error = Get().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().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT); - SuccessOrExit(error); - - error = - Get().SetPsk(reinterpret_cast(aPSKd), static_cast(strlen(aPSKd))); - SuccessOrExit(error); - - error = Get().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl); - SuccessOrExit(error); - - memset(mJoinerRouters, 0, sizeof(mJoinerRouters)); - - SuccessOrExit(error = Get().Discover(Mac::ChannelMask(0), Get().GetPanId(), true, false, + SuccessOrExit(error = Get().Discover(Mac::ChannelMask(0), Get().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().Disconnect(); - Get().RemoveUnsecurePort(OPENTHREAD_CONFIG_JOINER_UDP_PORT); -} - -void Joiner::Complete(otError aError) -{ - mState = OT_JOINER_STATE_IDLE; - otError error = OT_ERROR_NOT_FOUND; - Get().Signal(OT_CHANGED_JOINER_STATE); - - Get().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().Disconnect(); + Get().RemoveUnsecurePort(kJoinerUdpPort); + mTimer.Stop(); + + // Fall through + + case OT_JOINER_STATE_DISCOVER: Get().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(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(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(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(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(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(reinterpret_cast(end - 1) - reinterpret_cast(entry))); + + entry->mExtAddr = static_cast(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().SetPanId(joinerRouter->mPanId); - Get().SetPanChannel(joinerRouter->mChannel); - Get().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().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().SetPanId(aRouter.mPanId); + SuccessOrExit(error = Get().SetPanChannel(aRouter.mChannel)); + SuccessOrExit(error = Get().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().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().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(state.GetState())); - otLogInfoMeshCoP("received joiner finalize response %d", static_cast(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().Disconnect(); + Get().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().SetMeshLocalPrefix(meshLocalPrefix.GetMeshLocalPrefix()); Get().SetExtendedPanId(extendedPanId.GetExtendedPanId()); - { - otNetworkName name; + Get().SetNetworkName(networkName.GetNetworkName(), networkName.GetLength()); - memcpy(name.m8, networkName.GetNetworkName(), networkName.GetLength()); - name.m8[networkName.GetLength()] = '\0'; - Get().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().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 diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index 64fd6892c..0c729db98 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -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;