[border-agent] directly respond to MGMT_COMMISSIONER_GET from non-active commissioner (#10632)

This commit is contained in:
Rongli Sun
2024-08-26 20:31:46 -07:00
committed by GitHub
parent 3c6b8a3dd2
commit abb6934cdd
5 changed files with 86 additions and 57 deletions
+20 -15
View File
@@ -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);
}
+1 -1
View File
@@ -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
+46
View File
@@ -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);
+10
View File
@@ -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.
*
+9 -41
View File
@@ -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,