Skip to content

Commit

Permalink
[api] enable DIAG_RST notify funcation into commissioner (openthread#305
Browse files Browse the repository at this point in the history
)

This commit adds DIAG_RST notify command into the commissioner module,
allowing users to reset MacCounters(9) TLV from a peer Thread device
by settting the device's mesh local address and TLV mask bits flag.
  • Loading branch information
ZhangLe2016 authored Dec 3, 2024
1 parent 3d6e813 commit bb5f9a4
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 1 deletion.
32 changes: 32 additions & 0 deletions include/commissioner/commissioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,38 @@ class Commissioner
*
*/
virtual Error CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagDataFlags) = 0;

/**
* @brief Asynchronously reset dedicated diagnostic TLV(s) on a Thread device.
*
* This method sends a DIAG_RST.ntf message to the specified Thread device,
* resetting the diagnostic TLVs such as MacCounters indicated by `aDiagDataFlags`.
* The response, or any errors encountered, will be delivered to the provided `aHandler`.
*
* @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 used if it is empty.
* @param[in] aDiagDataFlags Diagnostic data flags indicate which TLVs are wanted.
*
*/
virtual void CommandDiagReset(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) = 0;

/**
* @brief Synchronously reset dedicated diagnostic TLVs on a Thread device.
*
* This method sends a DIAG_RST.ntf message to the specified Thread device,
* resetting the diagnostic TLVs such as MacCounters indicated by `aDiagDataFlags`.
* The method blocks until a response is received or an error occurs.
*
* @param[in] aAddr Unicast mesh local address of the target Thread device,
* the leader ALOC will be used if it is empty.
* @param[in] aDiagDataFlags Diagnostic data flags indicate which TLVs are wanted.
*
* @return Error::kNone, succeed; Otherwise, failed.
*
*/
virtual Error CommandDiagReset(const std::string &aAddr, uint64_t aDiagDataFlags) = 0;
};

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

#define DIAG_GET_QRY_TYPE 1
#define DIAG_RST_NTF_TYPE 2

#define COLOR_ALIAS_FAILED Console::Color::kYellow

Expand Down Expand Up @@ -281,7 +282,8 @@ 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>"},
{"netdiag", "netdiag query [extaddr | rloc16] <dest mesh local address>\n"
"netdiag reset maccounters <dest mesh local address>"},
{"exit", "exit"},
{"quit", "quit\n"
"(an alias to 'exit' command)"},
Expand Down Expand Up @@ -2591,6 +2593,10 @@ Interpreter::Value Interpreter::ProcessNetworkDiagJob(CommissionerAppPtr &aCommi
{
operationType = DIAG_GET_QRY_TYPE;
}
else if (CaseInsensitiveEqual(aExpr[1], "reset"))
{
operationType = DIAG_RST_NTF_TYPE;
}
else
{
ExitNow(value = ERROR_INVALID_COMMAND(SYNTAX_INVALID_SUBCOMMAND, aExpr[1]));
Expand Down Expand Up @@ -2628,6 +2634,26 @@ Interpreter::Value Interpreter::ProcessNetworkDiagJob(CommissionerAppPtr &aCommi
}
}
}
if (CaseInsensitiveEqual(aExpr[2], "maccounters"))
{
flags = NetDiagData::kMacCountersBit;
if (operationType == DIAG_RST_NTF_TYPE)
{
SuccessOrExit(value = aCommissioner->CommandDiagReset(dstAddr, flags));
}
else 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;
Expand Down
8 changes: 8 additions & 0 deletions src/app/commissioner_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,14 @@ const DiagAnsDataMap &CommissionerApp::GetNetDiagTlvs() const
return mDiagAnsDataMap;
}

Error CommissionerApp::CommandDiagReset(const std::string &aAddr, uint64_t aDiagDataFlags)
{
Error error;

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

} // namespace commissioner

} // namespace ot
1 change: 1 addition & 0 deletions src/app/commissioner_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class CommissionerApp : public CommissionerHandler

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

/*
* BBR Dataset APIs
Expand Down
7 changes: 7 additions & 0 deletions src/app/commissioner_app_dummy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,13 @@ Error CommissionerApp::CommandDiagGetQuery(const std::string &aAddr, uint64_t aD
return Error{};
}

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

} // namespace commissioner

} // namespace ot
1 change: 1 addition & 0 deletions src/app/commissioner_app_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class CommissionerAppMock : public ::ot::commissioner::CommissionerApp
MOCK_METHOD(const EnergyReportMap &, GetAllEnergyReports, (), (const));
MOCK_METHOD(const DiagAnsDataMap &, GetNetDiagTlvs, (), (const));
MOCK_METHOD(Error, CommandDiagGetQuery, (const std::string &, uint64_t));
MOCK_METHOD(Error, CommandDiagReset, (const std::string &, uint64_t));
};

class CommissionerAppStaticExpecter
Expand Down
25 changes: 25 additions & 0 deletions src/app/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,10 @@ static void to_json(Json &aJson, const NetDiagData &aNetDiagData)
SET_IF_PRESENT(ExtMacAddr);
SET_IF_PRESENT(MacAddr);
#undef SET_IF_PRESENT
if (aNetDiagData.mPresentFlags & NetDiagData::kMacCountersBit)
{
aJson["MacCounters"] = MacCountersToJson(aNetDiagData.mMacCounters);
}
}

std::string NetDiagDataToJson(const NetDiagData &aNetDiagData)
Expand All @@ -785,6 +789,27 @@ std::string NetDiagDataToJson(const NetDiagData &aNetDiagData)
return json.dump(JSON_INDENT_DEFAULT);
}

static void to_json(Json &aJson, const MacCounters &aMacCounters)
{
#define SET(name) aJson[#name] = aMacCounters.m##name;
SET(IfInUnknownProtos);
SET(IfInErrors);
SET(IfOutErrors);
SET(IfInUcastPkts);
SET(IfInBroadcastPkts);
SET(IfInDiscards);
SET(IfOutUcastPkts);
SET(IfOutBroadcastPkts);
SET(IfOutDiscards);
#undef SET
}

std::string MacCountersToJson(const MacCounters &aMacCounters)
{
Json json = aMacCounters;
return json.dump(JSON_INDENT_DEFAULT);
}

Error JsonFromFile(std::string &aJson, const std::string &aPath)
{
Error error;
Expand Down
1 change: 1 addition & 0 deletions src/app/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct NetworkData

Error NetworkDataFromJson(NetworkData &aNetworkData, const std::string &aJson);
std::string NetworkDataToJson(const NetworkData &aNetworkData);
std::string MacCountersToJson(const MacCounters &aMacCounters);

Error CommissionerDatasetFromJson(CommissionerDataset &aDataset, const std::string &aJson);
std::string CommissionerDatasetToJson(const CommissionerDataset &aDataset);
Expand Down
46 changes: 46 additions & 0 deletions src/library/commissioner_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,52 @@ void CommissionerImpl::HandleDiagGetAnswer(const coap::Request &aRequest)
}
}

void CommissionerImpl::CommandDiagReset(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags)
{
Error error;
Address dstAddr;
coap::Request request{coap::Type::kConfirmable, coap::Code::kPost};
auto onResponse = [aHandler](const coap::Response *aResponse, Error aError) {
Error error;

SuccessOrExit(error = aError);
SuccessOrExit(error = CheckCoapResponseCode(*aResponse));

exit:
aHandler(error);
};

VerifyOrExit(IsActive(), error = ERROR_INVALID_STATE("commissioner is not active"));
SuccessOrExit(error = request.SetUriPath(uri::kDiagRst));
SuccessOrExit(error = AppendTlv(request, {tlv::Type::kNetworkDiagTypeList, GetNetDiagTlvTypes(aDiagDataFlags),
tlv::Scope::kNetworkDiag}));

#if OT_COMM_CONFIG_CCM_ENABLE
if (IsCcmMode())
{
SuccessOrExit(error = SignRequest(request));
}
#endif

LOG_INFO(LOG_REGION_MESHDIAG, "sending DIAG_RST.ntf");
if (aAddr.empty())
{
mProxyClient.SendRequest(request, onResponse, kLeaderAloc16, kDefaultMmPort);
}
else
{
SuccessOrExit(error = dstAddr.Set(aAddr));
mProxyClient.SendRequest(request, onResponse, dstAddr, kDefaultMmPort);
}
LOG_INFO(LOG_REGION_MESHDIAG, "sent DIAG_RST.ntf");

exit:
if (error != ErrorCode::kNone)
{
aHandler(error);
}
}

void CommissionerImpl::SetPendingDataset(ErrorHandler aHandler, const PendingOperationalDataset &aPendingDataset)
{
Error error;
Expand Down
2 changes: 2 additions & 0 deletions src/library/commissioner_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ class CommissionerImpl : public Commissioner

void CommandDiagGetQuery(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) override;
Error CommandDiagGetQuery(const std::string &, uint64_t) override { return ERROR_UNIMPLEMENTED(""); }
void CommandDiagReset(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) override;
Error CommandDiagReset(const std::string &, uint64_t) override { return ERROR_UNIMPLEMENTED(""); }

Error SetToken(const ByteArray &aSignedToken) override;

Expand Down
13 changes: 13 additions & 0 deletions src/library/commissioner_safe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,19 @@ void CommissionerSafe::Invoke(evutil_socket_t, short, void *aContext)
}
}

void CommissionerSafe::CommandDiagReset(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags)
{
PushAsyncRequest([=]() { mImpl->CommandDiagReset(aHandler, aAddr, aDiagDataFlags); });
}

Error CommissionerSafe::CommandDiagReset(const std::string &aAddr, uint64_t aDiagDataFlags)
{
std::promise<Error> pro;
auto wait = [&pro](Error error) { pro.set_value(error); };
CommandDiagReset(wait, aAddr, aDiagDataFlags);
return pro.get_future().get();
}

void CommissionerSafe::PushAsyncRequest(AsyncRequest &&aAsyncRequest)
{
std::lock_guard<std::mutex> _(mInvokeMutex);
Expand Down
2 changes: 2 additions & 0 deletions src/library/commissioner_safe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ class CommissionerSafe : public Commissioner

void CommandDiagGetQuery(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) override;
Error CommandDiagGetQuery(const std::string &aAddr, uint64_t aDiagDataFlags) override;
void CommandDiagReset(ErrorHandler aHandler, const std::string &aAddr, uint64_t aDiagDataFlags) override;
Error CommandDiagReset(const std::string &aAddr, uint64_t aDiagDataFlags) override;

void CommandMigrate(ErrorHandler aHandler,
const std::string &aDstAddr,
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/test_cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,16 @@ test_execute_diag_command()

stop_daemon
}

test_execute_diag_command()
{
start_daemon
form_network "${PSKC}"

start_commissioner "${NON_CCM_CONFIG}"
petition_commissioner
send_command_to_commissioner "netdiag reset maccounters"
stop_commissioner

stop_daemon
}

0 comments on commit bb5f9a4

Please sign in to comment.