diff --git a/include/commissioner/commissioner.hpp b/include/commissioner/commissioner.hpp index 8ab598d74..3fbc3b981 100644 --- a/include/commissioner/commissioner.hpp +++ b/include/commissioner/commissioner.hpp @@ -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. * diff --git a/include/commissioner/defines.hpp b/include/commissioner/defines.hpp index 81bfdc1fe..c3fe5614a 100644 --- a/include/commissioner/defines.hpp +++ b/include/commissioner/defines.hpp @@ -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. * diff --git a/src/app/commissioner_app.cpp b/src/app/commissioner_app.cpp index 4a19ae821..248cd9861 100644 --- a/src/app/commissioner_app.cpp +++ b/src/app/commissioner_app.cpp @@ -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()) diff --git a/src/library/commissioner_impl.cpp b/src/library/commissioner_impl.cpp index 9180fcbac..04e531f76 100644 --- a/src/library/commissioner_impl.cpp +++ b/src/library/commissioner_impl.cpp @@ -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; @@ -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 @@ -281,7 +280,6 @@ void CommissionerImpl::Resign(ErrorHandler aHandler) } Disconnect(); - mMeshLocalPrefix.clear(); aHandler(ERROR_NONE); } @@ -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; } @@ -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 aHandler, uint16_t aDatasetFlags) { Error error; @@ -389,7 +367,7 @@ void CommissionerImpl::GetCommissionerDataset(Handler 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"); @@ -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"); @@ -495,15 +473,10 @@ void CommissionerImpl::GetRawActiveDataset(Handler 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); - } + // Always request Active Dataset from the Border Agent because + // the Mesh-Local prefix of current network is agnostic before + // we requesting the latest Active Operational Dataset. + mBrClient.SendRequest(request, onResponse); LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_ACTIVE_GET.req"); @@ -541,7 +514,6 @@ void CommissionerImpl::SetActiveDataset(ErrorHandler aHandler, const ActiveOpera "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)); @@ -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"); @@ -594,7 +566,6 @@ void CommissionerImpl::GetPendingDataset(Handler 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()) { @@ -608,7 +579,7 @@ void CommissionerImpl::GetPendingDataset(Handler aHan } #endif - mProxyClient.SendRequest(request, onResponse, GetLeaderLocator(), kDefaultMmPort); + mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort); LOG_DEBUG(LOG_REGION_MGMT, "sent MGMT_PENDING_GET.req"); @@ -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)); @@ -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"); @@ -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")); @@ -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"); @@ -724,7 +692,6 @@ void CommissionerImpl::GetBbrDataset(Handler 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)); @@ -734,7 +701,7 @@ void CommissionerImpl::GetBbrDataset(Handler 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"); @@ -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()); @@ -988,7 +971,6 @@ void CommissionerImpl::RegisterMulticastListener(Handler } 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})); @@ -1002,7 +984,7 @@ void CommissionerImpl::RegisterMulticastListener(Handler } #endif - mProxyClient.SendRequest(request, onResponse, GetPrimaryBbrLocator(), kDefaultMmPort); + mProxyClient.SendRequest(request, onResponse, kPrimaryBbrAloc16, kDefaultMmPort); LOG_DEBUG(LOG_REGION_MGMT, "sent MLR.req"); @@ -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(); } @@ -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(alocAddr, 0x0000); - utils::Encode(alocAddr, 0x00FF); - utils::Encode(alocAddr, 0xFE00); - utils::Encode(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 diff --git a/src/library/commissioner_impl.hpp b/src/library/commissioner_impl.hpp index 164d906b0..1e2a02eac 100644 --- a/src/library/commissioner_impl.hpp +++ b/src/library/commissioner_impl.hpp @@ -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 aHandler, uint16_t aDatasetFlags) override; Error GetCommissionerDataset(CommissionerDataset &, uint16_t) override { return ERROR_UNIMPLEMENTED(""); } @@ -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); @@ -264,7 +258,6 @@ class CommissionerImpl : public Commissioner Timer mKeepAliveTimer; coap::CoapSecure mBrClient; - ByteArray mMeshLocalPrefix; std::map mJoinerSessions; Timer mJoinerSessionTimer; diff --git a/src/library/commissioner_safe.cpp b/src/library/commissioner_safe.cpp index 9e819dfe6..df83a8874 100644 --- a/src/library/commissioner_safe.cpp +++ b/src/library/commissioner_safe.cpp @@ -208,14 +208,6 @@ Error CommissionerSafe::Resign() return pro.get_future().get(); } -Error CommissionerSafe::SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix) -{ - std::promise pro; - - PushAsyncRequest([&]() { pro.set_value(mImpl->SetMeshLocalPrefix(aMeshLocalPrefix)); }); - return pro.get_future().get(); -} - void CommissionerSafe::GetCommissionerDataset(Handler aHandler, uint16_t aDatasetFlags) { PushAsyncRequest([=]() { mImpl->GetCommissionerDataset(aHandler, aDatasetFlags); }); diff --git a/src/library/commissioner_safe.hpp b/src/library/commissioner_safe.hpp index 6c697cb9a..5523cd6d0 100644 --- a/src/library/commissioner_safe.hpp +++ b/src/library/commissioner_safe.hpp @@ -103,8 +103,6 @@ class CommissionerSafe : public Commissioner void Resign(ErrorHandler aHandler) override; Error Resign() override; - Error SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix) override; - void GetCommissionerDataset(Handler aHandler, uint16_t aDatasetFlags) override; Error GetCommissionerDataset(CommissionerDataset &aDataset, uint16_t aDatasetFlags) override; diff --git a/src/library/udp_proxy.cpp b/src/library/udp_proxy.cpp index f21e03a05..c115e5556 100644 --- a/src/library/udp_proxy.cpp +++ b/src/library/udp_proxy.cpp @@ -41,6 +41,15 @@ namespace ot { namespace commissioner { +static constexpr size_t kMeshLocalPrefixLength = 8; + +ProxyClient::ProxyClient(CommissionerImpl &aCommissioner, coap::CoapSecure &aBrClient) + : mCommissioner(aCommissioner) + , mEndpoint(aBrClient) + , mCoap(aCommissioner.GetEventBase(), mEndpoint) +{ +} + /** * Encapsulate the request and send it as a UDP_TX.ntf message. */ @@ -75,6 +84,30 @@ Error ProxyEndpoint::Send(const ByteArray &aRequest, MessageSubType aSubType) return error; } +void ProxyClient::SendRequest(const coap::Request & aRequest, + coap::ResponseHandler aHandler, + uint16_t aPeerAloc16, + uint16_t aPeerPort) +{ + if (mMeshLocalPrefix.empty()) + { + FetchMeshLocalPrefix([=](Error aError) { + if (aError == ErrorCode::kNone) + { + SendRequest(aRequest, aHandler, GetAnycastLocator(aPeerAloc16), aPeerPort); + } + else + { + aHandler(nullptr, aError); + } + }); + } + else + { + SendRequest(aRequest, aHandler, GetAnycastLocator(aPeerAloc16), aPeerPort); + } +} + void ProxyClient::SendRequest(const coap::Request & aRequest, coap::ResponseHandler aHandler, const Address & aPeerAddr, @@ -129,6 +162,61 @@ void ProxyClient::HandleUdpRx(const coap::Request &aUdpRx) return; } +void ProxyClient::FetchMeshLocalPrefix(Commissioner::ErrorHandler aHandler) +{ + auto onResponse = [=](const ActiveOperationalDataset *aActiveDataset, Error aError) { + Error error; + + SuccessOrExit(error = aError); + ASSERT(aActiveDataset != nullptr); + + VerifyOrExit(aActiveDataset->mPresentFlags & ActiveOperationalDataset::kMeshLocalPrefixBit, + error = ERROR_BAD_FORMAT("Mesh-Local prefix not included in response")); + SuccessOrExit(error = SetMeshLocalPrefix(aActiveDataset->mMeshLocalPrefix)); + + exit: + aHandler(aError); + }; + + mCommissioner.GetActiveDataset(onResponse, ActiveOperationalDataset::kMeshLocalPrefixBit); +} + +Error ProxyClient::SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix) +{ + constexpr uint8_t meshLocalPrefix[] = {0xfd}; + Error error; + + 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")); + + mMeshLocalPrefix = aMeshLocalPrefix; + +exit: + return error; +} + +Address ProxyClient::GetAnycastLocator(uint16_t aAloc16) const +{ + ASSERT(!mMeshLocalPrefix.empty()); + + Address ret; + Error error; + ByteArray alocAddr = mMeshLocalPrefix; + + utils::Encode(alocAddr, 0x0000); + utils::Encode(alocAddr, 0x00FF); + utils::Encode(alocAddr, 0xFE00); + utils::Encode(alocAddr, aAloc16); + + error = ret.Set(alocAddr); + ASSERT(error == ErrorCode::kNone); + + return ret; +} + } // namespace commissioner } // namespace ot diff --git a/src/library/udp_proxy.hpp b/src/library/udp_proxy.hpp index 0bb5eeaea..f13f4fd94 100644 --- a/src/library/udp_proxy.hpp +++ b/src/library/udp_proxy.hpp @@ -44,6 +44,8 @@ namespace ot { namespace commissioner { +class CommissionerImpl; + // The UDP proxy endpoint that sends UDP data by encapsulating // it in the UDP_TX.ntf message. class ProxyEndpoint : public Endpoint @@ -75,11 +77,12 @@ class ProxyEndpoint : public Endpoint class ProxyClient { public: - ProxyClient(struct event_base *aEventBase, coap::CoapSecure &aBrClient) - : mEndpoint(aBrClient) - , mCoap(aEventBase, mEndpoint) - { - } + ProxyClient(CommissionerImpl &aCommissioner, coap::CoapSecure &aBrClient); + + void SendRequest(const coap::Request & aRequest, + coap::ResponseHandler aHandler, + uint16_t aPeerAloc16, + uint16_t aPeerPort); void SendRequest(const coap::Request & aRequest, coap::ResponseHandler aHandler, @@ -96,9 +99,23 @@ class ProxyClient void CancelRequests() { mCoap.CancelRequests(); } + void FetchMeshLocalPrefix(Commissioner::ErrorHandler aHandler); + + const ByteArray &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; } + void ClearMeshLocalPrefix(void) { mMeshLocalPrefix.clear(); } + + Error SetMeshLocalPrefix(const ByteArray &aMeshLocalPrefix); + + Address GetAnycastLocator(uint16_t aAloc16) const; + private: - ProxyEndpoint mEndpoint; - coap::Coap mCoap; + CommissionerImpl &mCommissioner; + ProxyEndpoint mEndpoint; + coap::Coap mCoap; + + // The Mesh-Local prefix of current connected Thread network. + // Used to compute Mesh-Local address of UDP_TX.ntf peer. + ByteArray mMeshLocalPrefix; }; } // namespace commissioner