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

[api] enable DIAG_GET query function into commissioner #304

Merged
merged 9 commits into from
Nov 26, 2024
44 changes: 44 additions & 0 deletions include/commissioner/commissioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <commissioner/defines.hpp>
#include <commissioner/error.hpp>
#include <commissioner/network_data.hpp>
#include <commissioner/network_diag_data.hpp>

namespace ot {

Expand Down Expand Up @@ -259,6 +260,19 @@ class CommissionerHandler
(void)aEnergyList;
}

/**
* This function notifies the receiving the queried Diagnostic TLVs by DIAG_GET.ans command.
*
* @param[in] aPeerAddr The destination address of the DIAG_GET.ans command.
* @param[in] aDiagAnsMsg Parsed network diag data.
*
*/
virtual void OnDiagGetAnswerMessage(const std::string &aPeerAddr, const ot::commissioner::NetDiagData &aDiagAnsMsg)
{
(void)aPeerAddr;
(void)aDiagAnsMsg;
}

/**
* This function notifies that the operational dataset has been changed.
*
Expand Down Expand Up @@ -1147,6 +1161,36 @@ class Commissioner
* git repository.
*/
static std::string GetVersion(void);

/**
* @brief Asynchronously query diagnostic decoded data from a Thread device.
*
* This method sends a DIAG_GET.qry message to the specified Thread device,
* requesting the set of diagnostic data indicated by `aDiagDataFlags`.
* The response, or any errors encountered, will be delivered to the provided `aHandler`.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param[in, out] aHandler A handler to process the response or any errors.
* This handler is guaranteed to be called.
* @param[in] aAddr Unicast mesh local address of the target Thread device.
* @param[in] aDiagDataFlags Diagnostic data flags indicate which TLVs are wanted.
*
*/
virtual void CommandDiagGetQuery(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) = 0;

/**
* @brief Synchronously query diagnostic decoded data from a Thread device.
*
* This method sends a DIAG_GET.qry message to the specified Thread device,
* requesting the set of diagnostic data indicated by `aDiagDataFlags`.
* The method blocks until a response is received, an error occurs.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param[in] aAddr Unicast mesh local address of the target Thread device.
* @param[in] aDiagDataFlags Diagnostic data flags indicate which TLVs are wanted.
*
* @return Error::kNone, succeed; Otherwise, failed.
*
*/
virtual Error CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagDataFlags) = 0;
};

} // namespace commissioner
Expand Down
81 changes: 80 additions & 1 deletion src/app/cli/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
#define WARN_NETWORK_SELECTION_DROPPED "Network selection was dropped by the command"
#define WARN_NETWORK_SELECTION_CHANGED "Network selection was changed by the command"

#define DIAG_GET_QRY_TYPE 1

#define COLOR_ALIAS_FAILED Console::Color::kYellow

namespace ot {
Expand Down Expand Up @@ -200,7 +202,7 @@ const std::map<std::string, Interpreter::Evaluator> &Interpreter::mEvaluatorMap
{"announce", &Interpreter::ProcessAnnounce}, {"panid", &Interpreter::ProcessPanId},
{"energy", &Interpreter::ProcessEnergy}, {"exit", &Interpreter::ProcessExit},
{"quit", &Interpreter::ProcessExit}, {"help", &Interpreter::ProcessHelp},
{"state", &Interpreter::ProcessState},
{"state", &Interpreter::ProcessState}, {"diag", &Interpreter::ProcessDiag},
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
};

const std::map<std::string, std::string> &Interpreter::mUsageMap = *new std::map<std::string, std::string>{
Expand Down Expand Up @@ -279,6 +281,7 @@ const std::map<std::string, std::string> &Interpreter::mUsageMap = *new std::map
"panid conflict <panid>"},
{"energy", "energy scan <channel-mask> <count> <period> <scan-duration> <dst-addr>\n"
"energy report [<dst-addr>]"},
{"diag", "diag query [extaddr | rloc16] <dest mesh local address>"},
{"exit", "exit"},
{"quit", "quit\n"
"(an alias to 'exit' command)"},
Expand Down Expand Up @@ -2553,6 +2556,82 @@ Interpreter::Value Interpreter::ProcessEnergy(const Expression &aExpr)
return value;
}

Interpreter::Value Interpreter::ProcessDiag(const Expression &aExpr)
{
Value value;
CommissionerAppPtr commissioner = nullptr;

SuccessOrExit(value = mJobManager->GetSelectedCommissioner(commissioner));
value = ProcessDiagJob(commissioner, aExpr);
exit:
return value;
}

Interpreter::Value Interpreter::ProcessDiagJob(CommissionerAppPtr &aCommissioner, const Expression &aExpr)
{
Value value;
uint64_t flags = 0;
uint8_t operationType = 0;
std::string dstAddr;
NetDiagData diagData;

VerifyOrExit(aExpr.size() >= 3, value = ERROR_INVALID_ARGS("{} \n {}", SYNTAX_FEW_ARGS,
"diag [query] [extaddr | rloc16 ] <dest mesh local address>"));
if (aExpr.size() > 3 && !aExpr[3].empty())
{
dstAddr = aExpr[3];
}
else
{
dstAddr.clear();
}

if (CaseInsensitiveEqual(aExpr[1], "query"))
{
operationType = DIAG_GET_QRY_TYPE;
}
else
{
ExitNow(value = ERROR_INVALID_COMMAND(SYNTAX_INVALID_SUBCOMMAND, aExpr[1]));
}

if (CaseInsensitiveEqual(aExpr[2], "extaddr"))
{
flags = NetDiagData::kExtMacAddrBit;
if (operationType == DIAG_GET_QRY_TYPE)
{
SuccessOrExit(value = aCommissioner->CommandDiagGetQuery(dstAddr, flags));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
diagData.mPresentFlags = flags;
DiagAnsDataMap diagAnsDataMaps = aCommissioner->GetNetDiagTlvs();
for (auto &diagAnsDataMap : diagAnsDataMaps)
{
value = "Peer Address: " + (diagAnsDataMap.first).ToString() +
"\nContent: " + NetDiagDataToJson(diagAnsDataMap.second);
}
}
}
if (CaseInsensitiveEqual(aExpr[2], "rloc16"))
{
flags = NetDiagData::kMacAddrBit;
if (operationType == DIAG_GET_QRY_TYPE)
{
SuccessOrExit(value = aCommissioner->CommandDiagGetQuery(dstAddr, flags));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
diagData.mPresentFlags = flags;
DiagAnsDataMap diagAnsDataMaps = aCommissioner->GetNetDiagTlvs();
for (auto &diagAnsDataMap : diagAnsDataMaps)
{
value = "Peer Address: " + (diagAnsDataMap.first).ToString() +
"\nContent: " + NetDiagDataToJson(diagAnsDataMap.second);
}
}
}

exit:
return value;
}

Interpreter::Value Interpreter::ProcessExit(const Expression &)
{
mJobManager->StopCommissionerPool();
Expand Down
7 changes: 7 additions & 0 deletions src/app/cli/interpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ class Interpreter
*/
Error UpdateNetworkSelectionInfo(bool onStart = false);

/**
* Execute the diagnostic command (query) to handle the network diag data.
*/
Value executeDiagCommands(uint64_t aFlags, uint8_t aOperationType, std::string aDstAddr);

Value ProcessConfig(const Expression &aExpr);
Value ProcessStart(const Expression &aExpr);
Value ProcessState(const Expression &aExpr);
Expand All @@ -223,6 +228,7 @@ class Interpreter
Value ProcessAnnounce(const Expression &aExpr);
Value ProcessPanId(const Expression &aExpr);
Value ProcessEnergy(const Expression &aExpr);
Value ProcessDiag(const Expression &aExpr);
Value ProcessExit(const Expression &aExpr);
Value ProcessHelp(const Expression &aExpr);

Expand All @@ -233,6 +239,7 @@ class Interpreter
Value ProcessCommDatasetJob(CommissionerAppPtr &aCommissioner, const Expression &aExpr);
Value ProcessOpDatasetJob(CommissionerAppPtr &aCommissioner, const Expression &aExpr);
Value ProcessBbrDatasetJob(CommissionerAppPtr &aCommissioner, const Expression &aExpr);
Value ProcessDiagJob(CommissionerAppPtr &aCommissioner, const Expression &aExpr);

static void BorderAgentHandler(const BorderAgent *aBorderAgent, const Error &aError);

Expand Down
24 changes: 24 additions & 0 deletions src/app/commissioner_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "commissioner/defines.hpp"
#include "commissioner/error.hpp"
#include "commissioner/network_data.hpp"
#include "commissioner/network_diag_data.hpp"
#include "common/address.hpp"
#include "common/error_macros.hpp"
#include "common/utils.hpp"
Expand Down Expand Up @@ -1389,6 +1390,29 @@ const JoinerInfo *CommissionerApp::GetJoinerInfo(JoinerType aType, const ByteArr
return nullptr;
}

// Network Diagnostic
Error CommissionerApp::CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagDataFlags)
{
Error error;

error = mCommissioner->CommandDiagGetQuery(aAddr, aDiagDataFlags);
return error;
}

void CommissionerApp::OnDiagGetAnswerMessage(const std::string &aPeerAddr, const NetDiagData &aDiagAnsMsg)
{
Address addr;

SuccessOrDie(addr.Set(aPeerAddr));

mDiagAnsDataMap[addr] = aDiagAnsMsg;
}

const DiagAnsDataMap &CommissionerApp::GetNetDiagTlvs() const
{
return mDiagAnsDataMap;
}

} // namespace commissioner

} // namespace ot
12 changes: 11 additions & 1 deletion src/app/commissioner_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "commissioner/defines.hpp"
#include "commissioner/error.hpp"
#include "commissioner/network_data.hpp"
#include "commissioner/network_diag_data.hpp"
#include "common/address.hpp"

namespace ot {
Expand All @@ -63,6 +64,8 @@ struct EnergyReport
};
using EnergyReportMap = std::map<Address, EnergyReport>;

using DiagAnsDataMap = std::map<Address, NetDiagData>;

/**
* @brief Enumeration of Joiner Type for steering.
*
Expand Down Expand Up @@ -126,6 +129,8 @@ class CommissionerApp : public CommissionerHandler

MOCKABLE void OnDatasetChanged() override;

MOCKABLE void OnDiagGetAnswerMessage(const std::string &aPeerAddr, const NetDiagData &aDiagAnsMsg) override;

MOCKABLE Error Connect(const std::string &aBorderAgentAddr, uint16_t aBorderAgentPort);

MOCKABLE State GetState() const;
Expand Down Expand Up @@ -229,6 +234,9 @@ class CommissionerApp : public CommissionerHandler
// Always send MGMT_PENDING_SET.req.
MOCKABLE Error SetPendingDataset(const PendingOperationalDataset &aDataset);

// Network Diagnostic
MOCKABLE Error CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagDataFlags);

/*
* BBR Dataset APIs
*/
Expand Down Expand Up @@ -273,7 +281,8 @@ class CommissionerApp : public CommissionerHandler
MOCKABLE const EnergyReport *GetEnergyReport(const Address &aDstAddr) const;
MOCKABLE const EnergyReportMap &GetAllEnergyReports() const;

const std::string &GetDomainName() const;
const std::string &GetDomainName() const;
const DiagAnsDataMap &GetNetDiagTlvs() const;

protected:
CommissionerApp() = default;
Expand Down Expand Up @@ -324,6 +333,7 @@ class CommissionerApp : public CommissionerHandler
PendingOperationalDataset mPendingDataset;
CommissionerDataset mCommDataset;
BbrDataset mBbrDataset;
DiagAnsDataMap mDiagAnsDataMap;
};

Error CommissionerAppCreate(std::shared_ptr<CommissionerApp> &aCommApp, const Config &aConfig);
Expand Down
20 changes: 20 additions & 0 deletions src/app/commissioner_app_dummy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "commissioner/defines.hpp"
#include "commissioner/error.hpp"
#include "commissioner/network_data.hpp"
#include "commissioner/network_diag_data.hpp"
#include "common/address.hpp"

#define UNUSED(A) (void)A
Expand Down Expand Up @@ -99,6 +100,12 @@ void CommissionerApp::OnDatasetChanged()
{
}

void CommissionerApp::OnDiagGetAnswerMessage(const std::string &aPeerAddr, const NetDiagData &aDiagAnsMsg)
{
UNUSED(aPeerAddr);
UNUSED(aDiagAnsMsg);
}

Error CommissionerApp::Start(std::string &aExistingCommissionerId,
const std::string &aBorderAgentAddr,
uint16_t aBorderAgentPort)
Expand Down Expand Up @@ -518,6 +525,19 @@ const EnergyReportMap &CommissionerApp::GetAllEnergyReports() const
return sEnergyReportMap;
}

const DiagAnsDataMap &CommissionerApp::GetNetDiagTlvs() const
{
static DiagAnsDataMap sDiagAnsDataMap{};
return sDiagAnsDataMap;
}

Error CommissionerApp::CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagTlvFlags)
{
UNUSED(aAddr);
UNUSED(aDiagTlvFlags);
return Error{};
}

} // namespace commissioner

} // namespace ot
4 changes: 4 additions & 0 deletions src/app/commissioner_app_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "commissioner/defines.hpp"
#include "commissioner/error.hpp"
#include "commissioner/network_data.hpp"
#include "commissioner/network_diag_data.hpp"
#include "common/address.hpp"
#include "gmock/gmock-function-mocker.h"

Expand Down Expand Up @@ -71,6 +72,7 @@ class CommissionerAppMock : public ::ot::commissioner::CommissionerApp
MOCK_METHOD(void, OnPanIdConflict, (const std::string &, const ChannelMask &, uint16_t), (override));
MOCK_METHOD(void, OnEnergyReport, (const std::string &, const ChannelMask &, const ByteArray &), (override));
MOCK_METHOD(void, OnDatasetChanged, (), (override));
MOCK_METHOD(void, OnDiagGetAnswerMessage, (const std::string &, const NetDiagData &), (override));

MOCK_METHOD(Error, Connect, (const std::string &, uint16_t));
MOCK_METHOD(Error, Start, (std::string &, const std::string &, uint16_t));
Expand Down Expand Up @@ -137,6 +139,8 @@ class CommissionerAppMock : public ::ot::commissioner::CommissionerApp
MOCK_METHOD(Error, EnergyScan, (uint32_t, uint8_t, uint16_t, uint16_t, const std::string &));
MOCK_METHOD(const EnergyReport *, GetEnergyReport, (const Address &), (const));
MOCK_METHOD(const EnergyReportMap &, GetAllEnergyReports, (), (const));
MOCK_METHOD(const DiagAnsDataMap &, GetNetDiagTlvs, (), (const));
MOCK_METHOD(Error, CommandDiagGetQuery, (const std::string &, uint64_t));
};

class CommissionerAppStaticExpecter
Expand Down
19 changes: 19 additions & 0 deletions src/app/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,25 @@ std::string EnergyReportMapToJson(const EnergyReportMap &aEnergyReportMap)
return json.dump(JSON_INDENT_DEFAULT);
}

static void to_json(Json &aJson, const NetDiagData &aNetDiagData)
{
#define SET_IF_PRESENT(name) \
if (aNetDiagData.mPresentFlags & NetDiagData::k##name##Bit) \
{ \
aJson[#name] = aNetDiagData.m##name; \
};

SET_IF_PRESENT(ExtMacAddr);
SET_IF_PRESENT(MacAddr);
#undef SET_IF_PRESENT
}

std::string NetDiagDataToJson(const NetDiagData &aNetDiagData)
{
Json json = aNetDiagData;
return json.dump(JSON_INDENT_DEFAULT);
}

Error JsonFromFile(std::string &aJson, const std::string &aPath)
{
Error error;
Expand Down
Loading
Loading