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

[Fabric-Admin] Add sync-device command to sync a device from another fabric #33912

Merged
merged 6 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions examples/fabric-admin/commands/common/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ static void DetectAndLogMismatchedDoubleQuotes(int argc, char ** argv)

} // namespace

// Define the static member
Commands Commands::sInstance;

void Commands::Register(const char * commandSetName, commands_list commandsList, const char * helpText, bool isCluster)
{
VerifyOrDieWithMsg(isCluster || helpText != nullptr, NotSpecified, "Non-cluster command sets must have help text");
Expand Down Expand Up @@ -337,6 +340,7 @@ Commands::CommandSetMap::iterator Commands::GetCommandSet(std::string commandSet
{
std::string key(commandSet.first);
std::transform(key.begin(), key.end(), key.begin(), ::tolower);

if (key.compare(commandSetName) == 0)
{
return mCommandSets.find(commandSet.first);
Expand All @@ -346,6 +350,23 @@ Commands::CommandSetMap::iterator Commands::GetCommandSet(std::string commandSet
return mCommandSets.end();
}

Command * Commands::GetCommandByName(std::string commandSetName, std::string commandName)
{
auto commandSetIter = GetCommandSet(commandSetName);
if (commandSetIter != mCommandSets.end())
{
auto & commandList = commandSetIter->second.commands;
for (auto & command : commandList)
{
if (command->GetName() == commandName)
{
return command.get();
}
}
}
return nullptr;
}

Command * Commands::GetCommand(CommandsVector & commands, std::string commandName)
{
for (auto & command : commands)
Expand Down
16 changes: 16 additions & 0 deletions examples/fabric-admin/commands/common/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class Commands
int Run(int argc, char ** argv);
int RunInteractive(const char * command, const chip::Optional<char *> & storageDirectory, bool advertiseOperational);

Command * GetCommandByName(std::string commandSetName, std::string commandName);

private:
struct CommandSet
{
Expand Down Expand Up @@ -87,4 +89,18 @@ class Commands
#ifdef CONFIG_USE_LOCAL_STORAGE
PersistentStorage mStorage;
#endif // CONFIG_USE_LOCAL_STORAGE

friend Commands & CommandMgr();
static Commands sInstance;
};

/**
* Returns the public interface of the CommandManager singleton object.
*
* Applications should use this to access features of the CommandManager
* object.
*/
inline Commands & CommandMgr()
{
return Commands::sInstance;
}
1 change: 1 addition & 0 deletions examples/fabric-admin/commands/fabric-sync/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void registerCommandsFabricSync(Commands & commands, CredentialIssuerCommands *

commands_list clusterCommands = {
make_unique<FabricSyncAddDeviceCommand>(credsIssuerConfig),
make_unique<FabricSyncDeviceCommand>(credsIssuerConfig),
};

commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for fabric synchronization.");
Expand Down
49 changes: 49 additions & 0 deletions examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "FabricSyncCommand.h"
#include <commands/common/RemoteDataModelLogger.h>
#include <commands/interactive/InteractiveCommands.h>
#include <setup_payload/ManualSetupPayloadGenerator.h>
#include <thread>
#include <unistd.h>

Expand All @@ -27,6 +29,13 @@

using namespace ::chip;

namespace {

constexpr uint16_t kRetryIntervalS = 3;
constexpr uint16_t kMaxManaulCodeLength = 11;

} // namespace

CHIP_ERROR FabricSyncAddDeviceCommand::RunCommand(NodeId remoteId)
{
#if defined(PW_RPC_ENABLED)
Expand All @@ -36,3 +45,43 @@ CHIP_ERROR FabricSyncAddDeviceCommand::RunCommand(NodeId remoteId)
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif
}

void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_ERROR err, chip::SetupPayload payload)
{
if (err == CHIP_NO_ERROR)
{
char payloadBuffer[kMaxManaulCodeLength + 1];
MutableCharSpan manualCode(payloadBuffer);
CHIP_ERROR error = ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(manualCode);
if (error == CHIP_NO_ERROR)
{
char command[64];
snprintf(command, sizeof(command), "pairing code 3 %s", payloadBuffer);
PushCommand(command);
}
else
{
ChipLogError(NotSpecified, "Unable to generate manual code for setup payload: %" CHIP_ERROR_FORMAT, error.Format());
}
}
}

CHIP_ERROR FabricSyncDeviceCommand::RunCommand(EndpointId remoteId)
{
char command[64];
snprintf(command, sizeof(command), "pairing open-commissioning-window 1 %d 1 300 1000 3840", remoteId);

OpenCommissioningWindowCommand * openCommand =
static_cast<OpenCommissioningWindowCommand *>(CommandMgr().GetCommandByName("pairing", "open-commissioning-window"));

if (openCommand == nullptr)
{
return CHIP_ERROR_UNINITIALIZED;
}

openCommand->RegisterDelegate(this);

PushCommand(command);

return CHIP_NO_ERROR;
}
22 changes: 22 additions & 0 deletions examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include <commands/common/CHIPCommand.h>
#include <commands/pairing/OpenCommissioningWindowCommand.h>

class FabricSyncAddDeviceCommand : public CHIPCommand
{
Expand All @@ -38,3 +39,24 @@ class FabricSyncAddDeviceCommand : public CHIPCommand

CHIP_ERROR RunCommand(NodeId remoteId);
};

class FabricSyncDeviceCommand : public CHIPCommand, CommissioningWindowDelegate
{
public:
FabricSyncDeviceCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("sync-device", credIssuerCommands)
{
AddArgument("endpointid", 0, UINT16_MAX, &mEndpointId);
}

void OnCommissioningWindowOpened(NodeId deviceId, CHIP_ERROR status, chip::SetupPayload payload) override;

/////////// CHIPCommand Interface /////////
CHIP_ERROR RunCommand() override { return RunCommand(mEndpointId); }

chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(1); }

private:
chip::EndpointId mEndpointId;

CHIP_ERROR RunCommand(chip::EndpointId remoteId);
};
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ char * InteractiveStartCommand::GetCommand(char * command)
command = new char[cmd.length() + 1];
strcpy(command, cmd.c_str());

ChipLogProgress(NotSpecified, "GetCommand: %s", command);

// Do not save empty lines
if (command != nullptr && *command)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@ CHIP_ERROR OpenCommissioningWindowCommand::RunCommand()
void OpenCommissioningWindowCommand::OnOpenCommissioningWindowResponse(void * context, NodeId remoteId, CHIP_ERROR err,
chip::SetupPayload payload)
{
LogErrorOnFailure(err);
OpenCommissioningWindowCommand * self = static_cast<OpenCommissioningWindowCommand *>(context);
if (self->mDelegate)
{
self->mDelegate->OnCommissioningWindowOpened(remoteId, err, payload);
self->UnregisterDelegate();
}

LogErrorOnFailure(err);
OnOpenBasicCommissioningWindowResponse(context, remoteId, err);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
#include <controller/CommissioningWindowOpener.h>
#include <lib/support/CHIPMem.h>

class CommissioningWindowDelegate
{
public:
virtual void OnCommissioningWindowOpened(chip::NodeId deviceId, CHIP_ERROR err, chip::SetupPayload payload) = 0;
virtual ~CommissioningWindowDelegate() = default;
};

class OpenCommissioningWindowCommand : public CHIPCommand
{
public:
Expand All @@ -31,6 +38,7 @@ class OpenCommissioningWindowCommand : public CHIPCommand
mOnOpenBasicCommissioningWindowCallback(OnOpenBasicCommissioningWindowResponse, this)
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId, "Node to send command to.");
AddArgument("endpoint-id", 0, UINT16_MAX, &mEndpointId, "Endpoint to send command to.");
AddArgument("option", 0, 2, &mCommissioningWindowOption,
"1 to use Enhanced Commissioning Method.\n 0 to use Basic Commissioning Method.");
AddArgument("window-timeout", 0, UINT16_MAX, &mCommissioningWindowTimeout,
Expand All @@ -41,6 +49,9 @@ class OpenCommissioningWindowCommand : public CHIPCommand
AddArgument("timeout", 0, UINT16_MAX, &mTimeout, "Time, in seconds, before this command is considered to have timed out.");
}

void RegisterDelegate(CommissioningWindowDelegate * delegate) { mDelegate = delegate; }
void UnregisterDelegate() { mDelegate = nullptr; }

/////////// CHIPCommand Interface /////////
CHIP_ERROR RunCommand() override;

Expand All @@ -50,7 +61,9 @@ class OpenCommissioningWindowCommand : public CHIPCommand

private:
NodeId mNodeId;
chip::EndpointId mEndpointId;
chip::Controller::CommissioningWindowOpener::CommissioningWindowOption mCommissioningWindowOption;
CommissioningWindowDelegate * mDelegate = nullptr;
uint16_t mCommissioningWindowTimeout;
uint32_t mIteration;
uint16_t mDiscriminator;
Expand Down
10 changes: 9 additions & 1 deletion examples/fabric-admin/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include <string>

#if defined(PW_RPC_ENABLED)
#include <rpc/RpcClient.h>
#endif

using namespace ::chip;
using namespace ::chip::Controller;

Expand Down Expand Up @@ -389,7 +393,11 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err)
{
if (err == CHIP_NO_ERROR)
{
ChipLogProgress(NotSpecified, "Device commissioning completed with success");
fprintf(stderr, "New device with Node ID: 0x%lx has been successfully added.\n", nodeId);

#if defined(PW_RPC_ENABLED)
AddSynchronizedDevice(nodeId);
#endif
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion examples/fabric-admin/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int main(int argc, char * argv[])
}

ExampleCredentialIssuerCommands credIssuerCommands;
Commands commands;
Commands & commands = CommandMgr();

registerCommandsFabricSync(commands, &credIssuerCommands);
registerCommandsInteractive(commands, &credIssuerCommands);
Expand Down
Loading