From 1052239ba63d3ed0ba9387260584ed70d8b256a8 Mon Sep 17 00:00:00 2001 From: Song Guo Date: Sun, 7 Apr 2024 03:00:08 +0000 Subject: [PATCH] [chip-tool] Implement wait-for-device command --- .../commands/clusters/ModelCommand.h | 8 +++- .../commands/common/ChipToolCheckInDelegate.h | 4 +- .../chip-tool/commands/icd/ICDCommand.cpp | 44 +++++++++++++++++++ examples/chip-tool/commands/icd/ICDCommand.h | 27 ++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ModelCommand.h b/examples/chip-tool/commands/clusters/ModelCommand.h index 9561932c9b74e0..af3aae26b21b00 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.h +++ b/examples/chip-tool/commands/clusters/ModelCommand.h @@ -70,7 +70,13 @@ class ModelCommand : public CHIPCommand void Shutdown() override; protected: - bool IsPeerLIT() { return mIsPeerLIT.ValueOr(false); } + bool IsPeerLIT() + { + CheckPeerICDType(); + return mIsPeerLIT.ValueOr(false); + } + + chip::NodeId GetDestinationId() const { return mDestinationId; } chip::Optional mTimeout; diff --git a/examples/chip-tool/commands/common/ChipToolCheckInDelegate.h b/examples/chip-tool/commands/common/ChipToolCheckInDelegate.h index b32356ab23b148..a6865951972b45 100644 --- a/examples/chip-tool/commands/common/ChipToolCheckInDelegate.h +++ b/examples/chip-tool/commands/common/ChipToolCheckInDelegate.h @@ -32,12 +32,12 @@ class CheckInCompleteCallback /** * @brief Callback used to let the application know that a check-in message was received and validated. * - * The callback will be executed in CHIP main loop. Implementations avoid blocking in this callback. + * The callback will be executed in CHIP main loop. Implementations should avoid blocking in this callback. * * @param[in] clientInfo - ICDClientInfo object representing the state associated with the * node that sent the check-in message. */ - virtual void OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo); + virtual void OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo) = 0; }; class ChipToolCheckInDelegate : public chip::app::CheckInDelegate diff --git a/examples/chip-tool/commands/icd/ICDCommand.cpp b/examples/chip-tool/commands/icd/ICDCommand.cpp index fbfc6a2083a5d5..b3190073fa6790 100644 --- a/examples/chip-tool/commands/icd/ICDCommand.cpp +++ b/examples/chip-tool/commands/icd/ICDCommand.cpp @@ -23,6 +23,7 @@ #include using namespace ::chip; +using namespace ::chip::app; CHIP_ERROR ICDListCommand::RunCommand() { @@ -64,12 +65,55 @@ CHIP_ERROR ICDListCommand::RunCommand() return CHIP_NO_ERROR; } +CHIP_ERROR ICDWaitForDeviceCommand::RunCommand() +{ + if (!IsPeerLIT()) + { + ChipLogError(chipTool, "The device is not a registered LIT-ICD device."); + return CHIP_ERROR_NOT_FOUND; + } + mInterestedNode = ScopedNodeId(GetDestinationId(), CurrentCommissioner().GetFabricIndex()); + RegisterOnCheckInCompleteCallback(this); + ChipLogError(chipTool, "Please trigger the device active mode."); + return CHIP_NO_ERROR; +} + +void ICDWaitForDeviceCommand::OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo) +{ + if (clientInfo.peer_node != mInterestedNode) + { + ChipLogDetail(chipTool, "The node " ChipLogFormatScopedNodeId " is not the one we are interested in.", + ChipLogValueScopedNodeId(clientInfo.peer_node)); + return; + } + + ChipLogDetail(chipTool, "Received check-in message from the node, send stay active request to the device."); + UnregisterOnCheckInCompleteCallback(this); + + CHIP_ERROR err = ClusterCommand::RunCommand(); + if (err != CHIP_NO_ERROR) + { + SetCommandExitStatus(err); + return; + } +} + +CHIP_ERROR ICDWaitForDeviceCommand::SendCommand(chip::DeviceProxy * device, + std::vector /* not used, always send to endpoint 0 */) +{ + chip::app::Clusters::IcdManagement::Commands::StayActiveRequest::Type request; + request.stayActiveDuration = mStayActiveDurationSeconds; + return ClusterCommand::SendCommand(device, kRootEndpointId, Clusters::IcdManagement::Id, + Clusters::IcdManagement::Commands::StayActiveRequest::Id, request); +} + void registerCommandsICD(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { const char * name = "ICD"; commands_list list = { make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), }; commands.RegisterCommandSet(name, list, "Commands for client-side ICD management."); diff --git a/examples/chip-tool/commands/icd/ICDCommand.h b/examples/chip-tool/commands/icd/ICDCommand.h index b36d66a7dbfcb9..5a81469285ad74 100644 --- a/examples/chip-tool/commands/icd/ICDCommand.h +++ b/examples/chip-tool/commands/icd/ICDCommand.h @@ -19,8 +19,12 @@ #pragma once #include "../common/CHIPCommand.h" +#include "commands/clusters/ClusterCommand.h" #include "commands/common/Commands.h" +#include +#include +#include #include class ICDCommand : public CHIPCommand @@ -42,4 +46,27 @@ class ICDListCommand : public ICDCommand CHIP_ERROR RunCommand() override; }; +class ICDWaitForDeviceCommand : public ClusterCommand, public CheckInCompleteCallback +{ +public: + ICDWaitForDeviceCommand(CredentialIssuerCommands * credIssuerCmds) : ClusterCommand("wait-for-device", credIssuerCmds) + { + ModelCommand::AddArguments(/*skipEndpoints=*/true); + AddArgument("stay-active-duration-seconds", 1, UINT32_MAX, &mStayActiveDurationSeconds, + "The duration in seconds for the device to stay active after check-in completes."); + } + + virtual ~ICDWaitForDeviceCommand() = default; + + CHIP_ERROR RunCommand() override; + + void OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo) override; + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endPointIds) override; + +private: + chip::ScopedNodeId mInterestedNode; + uint32_t mStayActiveDurationSeconds; +}; + void registerCommandsICD(Commands & commands, CredentialIssuerCommands * credsIssuerConfig);