Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[udp-proxy] track Mesh-Local prefix in UDP Proxy client #188

Merged
merged 1 commit into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions include/commissioner/commissioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,19 +503,6 @@ class Commissioner
*/
virtual Error Resign() = 0;

/**
* @brief Set the Mesh-local Prefix of current connected Thread network.
*
* The user should get the Mesh-local Prefix with `GetActiveDataset` and set the prefix
* with this method, before initiating any other MGMT commands.
*
* @param[in] aMeshLocalPrefix The Mesh-local Prefix of current Thread network.
*
* @retval Error::kNone Successfully set the Mesh-local Prefix.
* @retval Error::kInvalidArgs The Mesh-local Prefix is not valid.
*/
virtual Error SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix) = 0;

/**
* @brief Asynchronously get the Commissioner Dataset.
*
Expand Down
5 changes: 0 additions & 5 deletions include/commissioner/defines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,6 @@ static constexpr uint16_t kDefaultAeUdpPort = 1001;
*/
static constexpr uint16_t kDefaultNmkpUdpPort = 1002;

/**
* The fixed primary backbone router anycast locator.
*/
static constexpr uint16_t kPrimaryBbrAloc16 = 0xFC38;

/**
* If using radio 915Mhz. Default radio freq of Thread is 2.4Ghz.
*
Expand Down
3 changes: 1 addition & 2 deletions src/app/commissioner_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ Error CommissionerApp::SyncNetworkData(void)
BbrDataset bbrDataset;

SuccessOrExit(error = mCommissioner->GetActiveDataset(activeDataset, 0xFFFF));
SuccessOrExit(error = mCommissioner->SetMeshLocalPrefix(activeDataset.mMeshLocalPrefix));
SuccessOrExit(error = mCommissioner->GetPendingDataset(pendingDataset, 0xFFFF));
SuccessOrExit(error = mCommissioner->SetCommissionerDataset(mCommDataset));
if (IsCcmMode())
Expand Down Expand Up @@ -535,7 +534,7 @@ Error CommissionerApp::GetMeshLocalPrefix(std::string &aPrefix)
SuccessOrExit(error = mCommissioner->GetActiveDataset(mActiveDataset, 0xFFFF));

VerifyOrExit(mActiveDataset.mPresentFlags & ActiveOperationalDataset::kMeshLocalPrefixBit,
error = ERROR_NOT_FOUND("cannot find valid Mesh-local Prefix in Active Operational Dataset"));
error = ERROR_NOT_FOUND("cannot find valid Mesh-Local Prefix in Active Operational Dataset"));
aPrefix = Ipv6PrefixToString(mActiveDataset.mMeshLocalPrefix);

exit:
Expand Down
122 changes: 40 additions & 82 deletions src/library/commissioner_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ namespace ot {

namespace commissioner {

static constexpr size_t kMeshLocalPrefixLength = 8;

static constexpr uint16_t kLeaderAloc16 = 0xFC00;
static constexpr uint16_t kLeaderAloc16 = 0xFC00;
static constexpr uint16_t kPrimaryBbrAloc16 = 0xFC38;

static constexpr uint16_t kDefaultMmPort = 61631;

Expand Down Expand Up @@ -128,7 +127,7 @@ CommissionerImpl::CommissionerImpl(CommissionerHandler &aHandler, struct event_b
, mJoinerSessionTimer(mEventBase, [this](Timer &aTimer) { HandleJoinerSessionTimer(aTimer); })
, mResourceUdpRx(uri::kUdpRx, [this](const coap::Request &aRequest) { mProxyClient.HandleUdpRx(aRequest); })
, mResourceRlyRx(uri::kRelayRx, [this](const coap::Request &aRequest) { HandleRlyRx(aRequest); })
, mProxyClient(mEventBase, mBrClient)
, mProxyClient(*this, mBrClient)
#if OT_COMM_CONFIG_CCM_ENABLE
, mTokenManager(mEventBase)
#endif
Expand Down Expand Up @@ -281,7 +280,6 @@ void CommissionerImpl::Resign(ErrorHandler aHandler)
}

Disconnect();
mMeshLocalPrefix.clear();

aHandler(ERROR_NONE);
}
Expand All @@ -295,6 +293,7 @@ void CommissionerImpl::Connect(ErrorHandler aHandler, const std::string &aAddr,
void CommissionerImpl::Disconnect()
{
mBrClient.Disconnect(ERROR_CANCELLED("the CoAPs client was disconnected"));
mProxyClient.ClearMeshLocalPrefix();
mState = State::kDisabled;
}

Expand Down Expand Up @@ -336,27 +335,6 @@ void CommissionerImpl::CancelRequests()
#endif
}

Error CommissionerImpl::SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix)
{
constexpr uint8_t meshLocalPrefix[] = {0xfd};
Error error;

VerifyOrExit(!aMeshLocalPrefix.empty(), error = ERROR_NONE);
VerifyOrExit(aMeshLocalPrefix.size() == kMeshLocalPrefixLength,
error = ERROR_INVALID_ARGS("Thread Mesh-local Prefix length must be {}", kMeshLocalPrefixLength));
VerifyOrExit(
std::equal(aMeshLocalPrefix.begin(), aMeshLocalPrefix.begin() + sizeof(meshLocalPrefix), meshLocalPrefix),
error = ERROR_INVALID_ARGS("Thread mesh-local Prefix must starts with fd00::/8"));
error = ERROR_NONE;

exit:
if (error == ErrorCode::kNone)
{
mMeshLocalPrefix = aMeshLocalPrefix;
}
return error;
}

void CommissionerImpl::GetCommissionerDataset(Handler<CommissionerDataset> aHandler, uint16_t aDatasetFlags)
{
Error error;
Expand Down Expand Up @@ -389,7 +367,7 @@ void CommissionerImpl::GetCommissionerDataset(Handler<CommissionerDataset> aHand
SuccessOrExit(AppendTlv(request, {tlv::Type::kGet, tlvTypes}));
}

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_COMMISSIONER_GET.req");

Expand Down Expand Up @@ -429,7 +407,7 @@ void CommissionerImpl::SetCommissionerDataset(ErrorHandler aHandler, const Commi
}
#endif

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_COMMISSIONER_SET.req");

Expand Down Expand Up @@ -495,15 +473,10 @@ void CommissionerImpl::GetRawActiveDataset(Handler<ByteArray> aHandler, uint16_t
}
#endif

if (mMeshLocalPrefix.empty())
{
// Request Active Dataset from the BA when we don't possess the mesh-local prefix.
mBrClient.SendRequest(request, onResponse);
}
else
{
mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
}
// Send MGMT_ACTIVE_GET.req to the Border Agent but not the Leader,
// because we don't possess the Mesh-Local Prefix before getting the
// Active Operational Dataset.
mBrClient.SendRequest(request, onResponse);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_ACTIVE_GET.req");

Expand Down Expand Up @@ -534,14 +507,13 @@ void CommissionerImpl::SetActiveDataset(ErrorHandler aHandler, const ActiveOpera
error = ERROR_INVALID_ARGS("PAN ID cannot be set with Active Operational Dataset, "
"try setting with Pending Operational Dataset instead"));
VerifyOrExit((aDataset.mPresentFlags & ActiveOperationalDataset::kMeshLocalPrefixBit) == 0,
error = ERROR_INVALID_ARGS("Mesh-local Prefix cannot be set with Active Operational Dataset, "
error = ERROR_INVALID_ARGS("Mesh-Local Prefix cannot be set with Active Operational Dataset, "
"try setting with Pending Operational Dataset instead"));
VerifyOrExit((aDataset.mPresentFlags & ActiveOperationalDataset::kNetworkMasterKeyBit) == 0,
error = ERROR_INVALID_ARGS("Network Master Key cannot be set with Active Operational Dataset, "
"try setting with Pending Operational Dataset instead"));

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
SuccessOrExit(error = request.SetUriPath(uri::kMgmtActiveSet));
SuccessOrExit(error = AppendTlv(request, {tlv::Type::kCommissionerSessionId, GetSessionId()}));
SuccessOrExit(error = EncodeActiveOperationalDataset(request, aDataset));
Expand All @@ -553,7 +525,7 @@ void CommissionerImpl::SetActiveDataset(ErrorHandler aHandler, const ActiveOpera
}
#endif

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_ACTIVE_SET.req");

Expand Down Expand Up @@ -594,7 +566,6 @@ void CommissionerImpl::GetPendingDataset(Handler<PendingOperationalDataset> aHan
};

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
SuccessOrExit(error = request.SetUriPath(uri::kMgmtPendingGet));
if (!datasetList.empty())
{
Expand All @@ -608,7 +579,7 @@ void CommissionerImpl::GetPendingDataset(Handler<PendingOperationalDataset> aHan
}
#endif

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_PENDING_GET.req");

Expand Down Expand Up @@ -637,7 +608,6 @@ void CommissionerImpl::SetPendingDataset(ErrorHandler aHandler, const PendingOpe
error = ERROR_INVALID_ARGS("Delay Timer is mandatory for a Pending Operational Dataset"));

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
SuccessOrExit(error = request.SetUriPath(uri::kMgmtPendingSet));
SuccessOrExit(error = AppendTlv(request, {tlv::Type::kCommissionerSessionId, GetSessionId()}));
SuccessOrExit(error = EncodePendingOperationalDataset(request, aDataset));
Expand All @@ -649,7 +619,7 @@ void CommissionerImpl::SetPendingDataset(ErrorHandler aHandler, const PendingOpe
}
#endif

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_PENDING_SET.req");

Expand All @@ -672,8 +642,6 @@ void CommissionerImpl::SetBbrDataset(ErrorHandler aHandler, const BbrDataset &aD
};

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));

VerifyOrExit(IsCcmMode(), error = ERROR_INVALID_STATE("sending MGMT_BBR_SET.req is only valid in CCM mode"));
VerifyOrExit((aDataset.mPresentFlags & BbrDataset::kRegistrarIpv6AddrBit) == 0,
error = ERROR_INVALID_ARGS("trying to set Registrar IPv6 Address which is read-only"));
Expand All @@ -687,7 +655,7 @@ void CommissionerImpl::SetBbrDataset(ErrorHandler aHandler, const BbrDataset &aD
SuccessOrExit(error = SignRequest(request));
}

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_BBR_SET.req");

Expand Down Expand Up @@ -724,7 +692,6 @@ void CommissionerImpl::GetBbrDataset(Handler<BbrDataset> aHandler, uint16_t aDat
};

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
VerifyOrExit(IsCcmMode(), error = ERROR_INVALID_STATE("sending MGMT_BBR_GET.req is only valid in CCM mode"));

SuccessOrExit(error = request.SetUriPath(uri::kMgmtBbrGet));
Expand All @@ -734,7 +701,7 @@ void CommissionerImpl::GetBbrDataset(Handler<BbrDataset> aHandler, uint16_t aDat
SuccessOrExit(error = AppendTlv(request, {tlv::Type::kGet, datasetList}));
}

mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_BBR_GET.req");

Expand All @@ -759,19 +726,35 @@ void CommissionerImpl::SetSecurePendingDataset(ErrorHandler
aHandler(HandleStateResponse(aResponse, aError));
};

auto onMeshLocalPrefixResponse = [=](Error aError) {
if (aError == ErrorCode::kNone)
{
SetSecurePendingDataset(aHandler, aMaxRetrievalTimer, aDataset);
}
else
{
aHandler(aError);
}
};

// Delay timer is mandatory.
VerifyOrExit(aDataset.mPresentFlags & PendingOperationalDataset::kDelayTimerBit,
error = ERROR_INVALID_ARGS("Delay Timer is mandatory for a Secure Pending Operational Dataset"));

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
VerifyOrExit(IsCcmMode(),
error = ERROR_INVALID_STATE("sending MGMT_SEC_PENDING_SET.req is only valid in CCM mode"));

if (mProxyClient.GetMeshLocalPrefix().empty())
{
mProxyClient.FetchMeshLocalPrefix(onMeshLocalPrefixResponse);
ExitNow();
}

SuccessOrExit(error = request.SetUriPath(uri::kMgmtSecPendingSet));
SuccessOrExit(error = AppendTlv(request, {tlv::Type::kCommissionerSessionId, GetSessionId()}));

pbbrAddr = GetPrimaryBbrLocator();
pbbrAddr = mProxyClient.GetAnycastLocator(kPrimaryBbrAloc16);
uri = "coaps://[" + pbbrAddr.ToString() + "]" + uri::kMgmtPendingGet;

utils::Encode(secureDissemination, aDataset.mPendingTimestamp.Encode());
Expand Down Expand Up @@ -988,7 +971,6 @@ void CommissionerImpl::RegisterMulticastListener(Handler<uint8_t>
}

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("the commissioner is not active"));
VerifyOrExit(!mMeshLocalPrefix.empty(), error = ERROR_INVALID_STATE("no valid Mesh-local Prefix is set"));
SuccessOrExit(error = request.SetUriPath(uri::kMlr));
SuccessOrExit(
error = AppendTlv(request, {tlv::Type::kThreadCommissionerSessionId, GetSessionId(), tlv::Scope::kThread}));
Expand All @@ -1002,7 +984,7 @@ void CommissionerImpl::RegisterMulticastListener(Handler<uint8_t>
}
#endif

mProxyClient.SendRequest(request, onResponse, GetPrimaryBbrLocator(), kDefaultMmPort);
mProxyClient.SendRequest(request, onResponse, kPrimaryBbrAloc16, kDefaultMmPort);

LOG_DEBUG(LOG_REGION_MGMT, "sent MLR.req");

Expand Down Expand Up @@ -1975,6 +1957,11 @@ void CommissionerImpl::HandleDatasetChanged(const coap::Request &aRequest)

mProxyClient.SendEmptyChanged(aRequest);

// Clear the cached Mesh-Local prefix so that the UDP Proxy client
// will request for the new Mesh-Local prefix before sending next
// UDP_TX.ntf message.
mProxyClient.ClearMeshLocalPrefix();

mCommissionerHandler.OnDatasetChanged();
}

Expand Down Expand Up @@ -2197,35 +2184,6 @@ void CommissionerImpl::HandleJoinerSessionTimer(Timer &aTimer)
}
}

Address CommissionerImpl::GetAnycastLocator(uint16_t aAloc16) const
{
ASSERT(!mMeshLocalPrefix.empty());

Address ret;
Error error;
ByteArray alocAddr = mMeshLocalPrefix;

utils::Encode<uint16_t>(alocAddr, 0x0000);
utils::Encode<uint16_t>(alocAddr, 0x00FF);
utils::Encode<uint16_t>(alocAddr, 0xFE00);
utils::Encode<uint16_t>(alocAddr, aAloc16);

error = ret.Set(alocAddr);
ASSERT(error == ErrorCode::kNone);

return ret;
}

Address CommissionerImpl::GetLeaderLocator(void) const
{
return GetAnycastLocator(kLeaderAloc16);
}

Address CommissionerImpl::GetPrimaryBbrLocator(void) const
{
return GetAnycastLocator(kPrimaryBbrAloc16);
}

} // namespace commissioner

} // namespace ot
7 changes: 0 additions & 7 deletions src/library/commissioner_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ class CommissionerImpl : public Commissioner
void Resign(ErrorHandler aHandler) override;
Error Resign() override { return ERROR_UNIMPLEMENTED(""); }

Error SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix) override;

void GetCommissionerDataset(Handler<CommissionerDataset> aHandler, uint16_t aDatasetFlags) override;
Error GetCommissionerDataset(CommissionerDataset &, uint16_t) override { return ERROR_UNIMPLEMENTED(""); }

Expand Down Expand Up @@ -222,10 +220,6 @@ class CommissionerImpl : public Commissioner

void SendPetition(PetitionHandler aHandler);

Address GetAnycastLocator(uint16_t aAloc16) const;
Address GetLeaderLocator(void) const;
Address GetPrimaryBbrLocator(void) const;

// Set @p aKeepAlive to false to resign the commissioner role.
void SendKeepAlive(Timer &aTimer, bool aKeepAlive = true);

Expand Down Expand Up @@ -264,7 +258,6 @@ class CommissionerImpl : public Commissioner
Timer mKeepAliveTimer;

coap::CoapSecure mBrClient;
ByteArray mMeshLocalPrefix;

std::map<ByteArray, JoinerSession> mJoinerSessions;
Timer mJoinerSessionTimer;
Expand Down
8 changes: 0 additions & 8 deletions src/library/commissioner_safe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,6 @@ Error CommissionerSafe::Resign()
return pro.get_future().get();
}

Error CommissionerSafe::SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix)
{
std::promise<Error> pro;

PushAsyncRequest([&]() { pro.set_value(mImpl->SetMeshLocalPrefix(aMeshLocalPrefix)); });
return pro.get_future().get();
}

void CommissionerSafe::GetCommissionerDataset(Handler<CommissionerDataset> aHandler, uint16_t aDatasetFlags)
{
PushAsyncRequest([=]() { mImpl->GetCommissionerDataset(aHandler, aDatasetFlags); });
Expand Down
Loading