Skip to content

Commit

Permalink
[api] enable DIAG_GET query function into commissioner (#304)
Browse files Browse the repository at this point in the history
This commit adds DIAG_GET query command into the commissioner module,
all owing users to query diagnostic TLV (ExtMacAddr) from a peer
Thread device by setting the device's mesh local address than TLV mask
bits flag.

Test:
```
> config set pskc 445f2b5ca6f2a93a55ce570a70efeecb

[done]
> start 192.168.9.2 49154
[done]
> netdiag query extaddr

Peer Address: fda1:7966:fc90:d97:0:ff:fe00:bc00
Content: {
    "ExtMacAddr": "6e56946f67040080"
}
[done]
```
  • Loading branch information
ZhangLe2016 authored Nov 26, 2024
1 parent 67c828a commit 3d6e813
Show file tree
Hide file tree
Showing 14 changed files with 337 additions and 14 deletions.
48 changes: 48 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,40 @@ 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 ACK, or any errors encountered, will be delivered to the provided `aHandler`,
* and the diag data will be obtained by the callback of OnDiagGetAnswerMessage.
*
* @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,
* the leader ALOC will be set by default if it is empty.
* @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 ack is received, an error occurs, and the diag data
* will be obtained by the callback OnDiagGetAnswerMessage of CommissionerHandler.
*
* @param[in] aAddr Unicast mesh local address of the target Thread device,
* the leader ALOC will be set by default if it is empty.
* @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
82 changes: 81 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}, {"netdiag", &Interpreter::ProcessNetworkDiag},
};

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>]"},
{"netdiag", "netdiag query [extaddr | rloc16] <dest mesh local address>"},
{"exit", "exit"},
{"quit", "quit\n"
"(an alias to 'exit' command)"},
Expand Down Expand Up @@ -2553,6 +2556,83 @@ Interpreter::Value Interpreter::ProcessEnergy(const Expression &aExpr)
return value;
}

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

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

Interpreter::Value Interpreter::ProcessNetworkDiagJob(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,
"netdiag [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 ProcessNetworkDiag(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 ProcessNetworkDiagJob(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

0 comments on commit 3d6e813

Please sign in to comment.