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 Device Manager to manage assigned node ID and remote bridge #33972

Merged
merged 2 commits into from
Jul 2, 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
2 changes: 2 additions & 0 deletions examples/fabric-admin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static_library("fabric-admin-utils") {
"commands/pairing/OpenCommissioningWindowCommand.h",
"commands/pairing/PairingCommand.cpp",
"commands/pairing/ToTLVCert.cpp",
"device_manager/DeviceManager.cpp",
"device_manager/DeviceManager.h",
]

deps = [ "${chip_root}/src/app:events" ]
Expand Down
3 changes: 3 additions & 0 deletions examples/fabric-admin/commands/clusters/ReportCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "ReportCommand.h"

#include <app/InteractionModelEngine.h>
#include <device_manager/DeviceManager.h>
#include <inttypes.h>

using namespace ::chip;
Expand All @@ -44,6 +45,8 @@ void ReportCommand::OnAttributeData(const app::ConcreteDataAttributePath & path,
}

LogErrorOnFailure(RemoteDataModelLogger::LogAttributeAsJSON(path, data));

DeviceMgr().HanldeAttributeChange(path, data);
}

void ReportCommand::OnEventData(const app::EventHeader & eventHeader, TLV::TLVReader * data, const app::StatusIB * status)
Expand Down
4 changes: 3 additions & 1 deletion examples/fabric-admin/commands/fabric-sync/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ void registerCommandsFabricSync(Commands & commands, CredentialIssuerCommands *
const char * clusterName = "FabricSync";

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

commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for fabric synchronization.");
Expand Down
141 changes: 130 additions & 11 deletions examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "FabricSyncCommand.h"
#include <commands/common/RemoteDataModelLogger.h>
#include <commands/interactive/InteractiveCommands.h>
#include <device_manager/DeviceManager.h>
#include <setup_payload/ManualSetupPayloadGenerator.h>
#include <thread>
#include <unistd.h>
Expand All @@ -39,14 +40,116 @@ constexpr uint16_t kSubscribeMaxInterval = 60;

} // namespace

CHIP_ERROR FabricSyncAddDeviceCommand::RunCommand(NodeId remoteId)
void FabricSyncAddBridgeCommand::OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err)
{
#if defined(PW_RPC_ENABLED)
AddSynchronizedDevice(remoteId);
if (mBridgeNodeId != deviceId)
{
ChipLogProgress(NotSpecified, "Commissioning complete for non-bridge device: NodeId: " ChipLogFormatX64,
ChipLogValueX64(deviceId));
return;
}

if (err == CHIP_NO_ERROR)
{
DeviceMgr().SetRemoteBridgeNodeId(mBridgeNodeId);
ChipLogProgress(NotSpecified, "Successfully paired bridge device: NodeId: " ChipLogFormatX64,
ChipLogValueX64(mBridgeNodeId));

char command[kMaxCommandSize];
snprintf(command, sizeof(command), "descriptor subscribe parts-list %d %d %ld %d", kSubscribeMinInterval,
kSubscribeMaxInterval, mBridgeNodeId, kAggragatorEndpointId);

PushCommand(command);
}
else
{
ChipLogError(NotSpecified, "Failed to pair bridge device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
ChipLogValueX64(deviceId), err.Format());
}

mBridgeNodeId = kUndefinedNodeId;
}

CHIP_ERROR FabricSyncAddBridgeCommand::RunCommand(NodeId remoteId)
{
if (DeviceMgr().IsFabricSyncReady())
{
// print to console
fprintf(stderr, "Remote Fabric Bridge has been alread configured.");
return CHIP_NO_ERROR;
}

char command[kMaxCommandSize];
snprintf(command, sizeof(command), "pairing onnetwork %ld %d", remoteId, kSetupPinCode);

PairingCommand * pairingCommand = static_cast<PairingCommand *>(CommandMgr().GetCommandByName("pairing", "onnetwork"));

if (pairingCommand == nullptr)
{
ChipLogError(NotSpecified, "Pairing onnetwork command is not available");
return CHIP_ERROR_UNINITIALIZED;
}

pairingCommand->RegisterCommissioningDelegate(this);
mBridgeNodeId = remoteId;

PushCommand(command);

return CHIP_NO_ERROR;
}

void FabricSyncRemoveBridgeCommand::OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err)
{
if (mBridgeNodeId != deviceId)
{
ChipLogProgress(NotSpecified, "An non-bridge device: NodeId: " ChipLogFormatX64 " is removed.", ChipLogValueX64(deviceId));
return;
}

if (err == CHIP_NO_ERROR)
{
DeviceMgr().SetRemoteBridgeNodeId(kUndefinedNodeId);
ChipLogProgress(NotSpecified, "Successfully removed bridge device: NodeId: " ChipLogFormatX64,
ChipLogValueX64(mBridgeNodeId));
}
else
{
ChipLogError(NotSpecified, "Failed to remove bridge device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
ChipLogValueX64(deviceId), err.Format());
}

mBridgeNodeId = kUndefinedNodeId;
}

CHIP_ERROR FabricSyncRemoveBridgeCommand::RunCommand()
{
NodeId bridgeNodeId = DeviceMgr().GetRemoteBridgeNodeId();

if (bridgeNodeId == kUndefinedNodeId)
{
// print to console
fprintf(stderr, "Remote Fabric Bridge is not configured yet.");
return CHIP_NO_ERROR;
}

mBridgeNodeId = bridgeNodeId;

char command[kMaxCommandSize];
snprintf(command, sizeof(command), "pairing unpair %ld", mBridgeNodeId);

PairingCommand * pairingCommand = static_cast<PairingCommand *>(CommandMgr().GetCommandByName("pairing", "unpair"));

if (pairingCommand == nullptr)
{
ChipLogError(NotSpecified, "Pairing code command is not available");
return CHIP_ERROR_UNINITIALIZED;
}

pairingCommand->RegisterPairingDelegate(this);

PushCommand(command);

return CHIP_NO_ERROR;
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif
}

void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_ERROR err, chip::SetupPayload payload)
Expand All @@ -59,7 +162,7 @@ void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_
if (error == CHIP_NO_ERROR)
{
char command[kMaxCommandSize];
NodeId nodeId = 2; // TODO: (Issue #33947) need to switch to dynamically assigned ID
NodeId nodeId = DeviceMgr().GetNextAvailableNodeId();
snprintf(command, sizeof(command), "pairing code %ld %s", nodeId, payloadBuffer);

PairingCommand * pairingCommand = static_cast<PairingCommand *>(CommandMgr().GetCommandByName("pairing", "code"));
Expand Down Expand Up @@ -101,7 +204,7 @@ void FabricSyncDeviceCommand::OnCommissioningComplete(chip::NodeId deviceId, CHI

if (err == CHIP_NO_ERROR)
{
// TODO: (Issue #33947) Add Synced Device to device manager
DeviceMgr().AddSyncedDevice(Device(mAssignedNodeId, mRemoteEndpointId));
}
else
{
Expand All @@ -112,10 +215,16 @@ void FabricSyncDeviceCommand::OnCommissioningComplete(chip::NodeId deviceId, CHI

CHIP_ERROR FabricSyncDeviceCommand::RunCommand(EndpointId remoteId)
{
if (!DeviceMgr().IsFabricSyncReady())
{
// print to console
fprintf(stderr, "Remote Fabric Bridge is not configured yet.");
return CHIP_NO_ERROR;
}

char command[kMaxCommandSize];
NodeId bridgeNodeId = 1; // TODO: (Issue #33947) need to switch to configured ID
snprintf(command, sizeof(command), "pairing open-commissioning-window %ld %d %d %d %d %d", bridgeNodeId, remoteId,
kEnhancedCommissioningMethod, kWindowTimeout, kIteration, kDiscriminator);
snprintf(command, sizeof(command), "pairing open-commissioning-window %ld %d %d %d %d %d", DeviceMgr().GetRemoteBridgeNodeId(),
remoteId, kEnhancedCommissioningMethod, kWindowTimeout, kIteration, kDiscriminator);

OpenCommissioningWindowCommand * openCommand =
static_cast<OpenCommissioningWindowCommand *>(CommandMgr().GetCommandByName("pairing", "open-commissioning-window"));
Expand All @@ -131,3 +240,13 @@ CHIP_ERROR FabricSyncDeviceCommand::RunCommand(EndpointId remoteId)

return CHIP_NO_ERROR;
}

CHIP_ERROR FabricAutoSyncCommand::RunCommand(bool enableAutoSync)
{
DeviceMgr().EnableAutoSync(enableAutoSync);

// print to console
fprintf(stderr, "Auto Fabric Sync is %s.\n", enableAutoSync ? "enabled" : "disabled");

return CHIP_NO_ERROR;
}
45 changes: 43 additions & 2 deletions examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,53 @@
#include <commands/pairing/OpenCommissioningWindowCommand.h>
#include <commands/pairing/PairingCommand.h>

constexpr uint32_t kSetupPinCode = 20202021;
constexpr uint16_t kMaxCommandSize = 64;
constexpr uint16_t kDiscriminator = 3840;
constexpr uint16_t kWindowTimeout = 300;
constexpr uint16_t kIteration = 1000;
constexpr uint16_t kAggragatorEndpointId = 1;
constexpr uint8_t kEnhancedCommissioningMethod = 1;

class FabricSyncAddDeviceCommand : public CHIPCommand
class FabricSyncAddBridgeCommand : public CHIPCommand, public CommissioningDelegate
{
public:
FabricSyncAddDeviceCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("add-device", credIssuerCommands)
FabricSyncAddBridgeCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("add-bridge", credIssuerCommands)
{
AddArgument("nodeid", 0, UINT64_MAX, &mNodeId);
}

void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) override;

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

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

private:
chip::NodeId mNodeId;
chip::NodeId mBridgeNodeId;

CHIP_ERROR RunCommand(NodeId remoteId);
};

class FabricSyncRemoveBridgeCommand : public CHIPCommand, public PairingDelegate
{
public:
FabricSyncRemoveBridgeCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("remove-bridge", credIssuerCommands)
{}

void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) override;

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

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

private:
chip::NodeId mBridgeNodeId;
};

class FabricSyncDeviceCommand : public CHIPCommand, public CommissioningWindowDelegate, public CommissioningDelegate
{
public:
Expand All @@ -69,3 +91,22 @@ class FabricSyncDeviceCommand : public CHIPCommand, public CommissioningWindowDe

CHIP_ERROR RunCommand(chip::EndpointId remoteId);
};

class FabricAutoSyncCommand : public CHIPCommand
{
public:
FabricAutoSyncCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("enable-auto-sync", credIssuerCommands)
{
AddArgument("state", 0, 1, &mEnableAutoSync, "Set to true to enable auto Fabric Sync, false to disable.");
}

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

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

private:
bool mEnableAutoSync;

CHIP_ERROR RunCommand(bool enableAutoSync);
};
Loading
Loading