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_RST notify funcation into commissioner #305

Merged
merged 8 commits into from
Dec 3, 2024
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) from a Thread device.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
*
* This method sends a DIAG_RST.ntf message to the specified Thread device,
* resetting the diagnostic TLVs such as MacCounters indicated by `aDiagDataFlags`.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
* 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 from a Thread device.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
*
* This method sends a DIAG_RST.ntf message to the specified Thread device,
* resetting the diagnostic TLVs such as MacCounters indicated by `aDiagDataFlags`.
ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
* 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,
* 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
}
Loading