mirror of
https://github.com/espressif/openthread.git
synced 2026-08-24 11:19:51 +00:00
[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:
committed by
Jonathan Hui
parent
873a710a1a
commit
83c9270c29
+269
-183
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user