mirror of
https://github.com/espressif/openthread.git
synced 2026-09-09 18:50:07 +00:00
[border-agent] directly respond to MGMT_COMMISSIONER_GET from non-active commissioner (#10632)
This commit is contained in:
@@ -468,7 +468,7 @@ void BorderAgent::HandleTmf<kUriCommissionerPetition>(Coap::Message &aMessage, c
|
||||
template <>
|
||||
void BorderAgent::HandleTmf<kUriCommissionerGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
IgnoreError(ForwardToLeader(aMessage, aMessageInfo, kUriCommissionerGet));
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, kUriCommissionerGet);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -479,7 +479,7 @@ void BorderAgent::HandleTmf<kUriCommissionerSet>(Coap::Message &aMessage, const
|
||||
|
||||
template <> void BorderAgent::HandleTmf<kUriActiveGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, Dataset::kActive);
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, kUriActiveGet);
|
||||
mCounters.mMgmtActiveGets++;
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ template <> void BorderAgent::HandleTmf<kUriActiveSet>(Coap::Message &aMessage,
|
||||
|
||||
template <> void BorderAgent::HandleTmf<kUriPendingGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, Dataset::kPending);
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, kUriPendingGet);
|
||||
mCounters.mMgmtPendingGets++;
|
||||
}
|
||||
|
||||
@@ -610,18 +610,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
Dataset::Type aType)
|
||||
void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *response = nullptr;
|
||||
|
||||
if (mState == kStateAccepted)
|
||||
{
|
||||
Uri uri = (aType == Dataset::kActive) ? kUriActiveGet : kUriPendingGet;
|
||||
|
||||
IgnoreError(ForwardToLeader(aMessage, aMessageInfo, uri));
|
||||
IgnoreError(ForwardToLeader(aMessage, aMessageInfo, aUri));
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -629,23 +625,32 @@ void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage,
|
||||
// the Security Policy flags (O-bit) should be ignore to allow
|
||||
// the commissioner candidate to get the full Operational Dataset.
|
||||
|
||||
if (aType == Dataset::kActive)
|
||||
switch (aUri)
|
||||
{
|
||||
case kUriActiveGet:
|
||||
response = Get<ActiveDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case kUriPendingGet:
|
||||
response = Get<PendingDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
|
||||
break;
|
||||
|
||||
case kUriCommissionerGet:
|
||||
response = Get<NetworkData::Leader>().ProcessCommissionerGetRequest(aMessage);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VerifyOrExit(response != nullptr, error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = Get<Tmf::SecureAgent>().SendMessage(*response, aMessageInfo));
|
||||
|
||||
LogInfo("Sent %sGet response to non-active commissioner", Dataset::TypeToString(aType));
|
||||
LogInfo("Sent %s response to non-active commissioner", PathForUri(aUri));
|
||||
|
||||
exit:
|
||||
LogWarnOnError(error, "send Active/PendingGet response");
|
||||
LogWarnOnError(error, "send Active/Pending/CommissionerGet response");
|
||||
FreeMessageOnError(response, error);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ private:
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
void HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Dataset::Type aType);
|
||||
void HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri);
|
||||
void HandleTimeout(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
|
||||
@@ -581,6 +581,52 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Coap::Message *Leader::ProcessCommissionerGetRequest(const Coap::Message &aMessage) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *response = nullptr;
|
||||
OffsetRange offsetRange;
|
||||
|
||||
response = Get<Tmf::Agent>().NewPriorityResponseMessage(aMessage);
|
||||
VerifyOrExit(response != nullptr, error = kErrorNoBufs);
|
||||
|
||||
if (Tlv::FindTlvValueOffsetRange(aMessage, MeshCoP::Tlv::kGet, offsetRange) == kErrorNone)
|
||||
{
|
||||
// Append the requested sub-TLV types given in Get TLV.
|
||||
|
||||
while (!offsetRange.IsEmpty())
|
||||
{
|
||||
uint8_t type;
|
||||
const MeshCoP::Tlv *subTlv;
|
||||
|
||||
IgnoreError(aMessage.Read(offsetRange, type));
|
||||
offsetRange.AdvanceOffset(sizeof(type));
|
||||
|
||||
subTlv = FindCommissioningDataSubTlv(type);
|
||||
|
||||
if (subTlv != nullptr)
|
||||
{
|
||||
SuccessOrExit(error = subTlv->AppendTo(*response));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append all sub-TLVs in the Commissioning Data.
|
||||
|
||||
const CommissioningDataTlv *dataTlv = FindCommissioningData();
|
||||
|
||||
if (dataTlv != nullptr)
|
||||
{
|
||||
SuccessOrExit(error = response->AppendBytes(dataTlv->GetValue(), dataTlv->GetLength()));
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
FreeAndNullMessageOnError(response, error);
|
||||
return response;
|
||||
}
|
||||
|
||||
Error Leader::FindBorderAgentRloc(uint16_t &aRloc16) const
|
||||
{
|
||||
return ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::kBorderAgentLocator, aRloc16);
|
||||
|
||||
@@ -188,6 +188,16 @@ public:
|
||||
*/
|
||||
void GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset) const;
|
||||
|
||||
/**
|
||||
* Processes a MGMT_COMMISSIONER_GET request message and prepares the response.
|
||||
*
|
||||
* @param[in] aRequest The MGMT_COMMISSIONER_GET request message.
|
||||
*
|
||||
* @returns The prepared response, or `nullptr` if fails to parse the request or cannot allocate message.
|
||||
*
|
||||
*/
|
||||
Coap::Message *ProcessCommissionerGetRequest(const Coap::Message &aMessage) const;
|
||||
|
||||
/**
|
||||
* Searches for given sub-TLV in Commissioning Data TLV.
|
||||
*
|
||||
|
||||
@@ -317,53 +317,21 @@ exit:
|
||||
|
||||
template <> void Leader::HandleTmf<kUriCommissionerGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *response = nullptr;
|
||||
OffsetRange offsetRange;
|
||||
|
||||
VerifyOrExit(Get<Mle::Mle>().IsLeader() && !mWaitingForNetDataSync);
|
||||
VerifyOrExit(Get<Mle::Mle>().IsLeader() && !mWaitingForNetDataSync, error = kErrorInvalidState);
|
||||
|
||||
response = Get<Tmf::Agent>().NewPriorityResponseMessage(aMessage);
|
||||
VerifyOrExit(response != nullptr);
|
||||
response = ProcessCommissionerGetRequest(aMessage);
|
||||
VerifyOrExit(response != nullptr, error = kErrorParse);
|
||||
SuccessOrExit(error = Get<Tmf::Agent>().SendMessage(*response, aMessageInfo));
|
||||
|
||||
if (Tlv::FindTlvValueOffsetRange(aMessage, MeshCoP::Tlv::kGet, offsetRange) == kErrorNone)
|
||||
{
|
||||
// Append the requested sub-TLV types given in Get TLV.
|
||||
|
||||
while (!offsetRange.IsEmpty())
|
||||
{
|
||||
uint8_t type;
|
||||
const MeshCoP::Tlv *subTlv;
|
||||
|
||||
IgnoreError(aMessage.Read(offsetRange, type));
|
||||
offsetRange.AdvanceOffset(sizeof(type));
|
||||
|
||||
subTlv = FindCommissioningDataSubTlv(type);
|
||||
|
||||
if (subTlv != nullptr)
|
||||
{
|
||||
SuccessOrExit(subTlv->AppendTo(*response));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append all sub-TLVs in the Commissioning Data.
|
||||
|
||||
CommissioningDataTlv *dataTlv = FindCommissioningData();
|
||||
|
||||
if (dataTlv != nullptr)
|
||||
{
|
||||
SuccessOrExit(response->AppendBytes(dataTlv->GetValue(), dataTlv->GetLength()));
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(Get<Tmf::Agent>().SendMessage(*response, aMessageInfo));
|
||||
response = nullptr; // `SendMessage` takes ownership on success
|
||||
|
||||
LogInfo("Sent %s response", UriToString<kUriCommissionerGet>());
|
||||
LogInfo("Sent %s response to %s", UriToString<kUriCommissionerGet>(),
|
||||
aMessageInfo.GetPeerAddr().ToString().AsCString());
|
||||
|
||||
exit:
|
||||
FreeMessage(response);
|
||||
LogWarnOnError(error, "send CommissionerGet response");
|
||||
FreeMessageOnError(response, error);
|
||||
}
|
||||
|
||||
void Leader::SendCommissioningSetResponse(const Coap::Message &aRequest,
|
||||
|
||||
Reference in New Issue
Block a user