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 all commits
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().HandleAttributeChange(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
145 changes: 133 additions & 12 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 @@ -36,17 +37,121 @@ constexpr uint32_t kCommissionPrepareTimeMs = 500;
constexpr uint16_t kMaxManaulCodeLength = 21;
constexpr uint16_t kSubscribeMinInterval = 0;
constexpr uint16_t kSubscribeMaxInterval = 60;
constexpr uint16_t kRemoteBridgePort = 5540;

} // 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.");
yufengwangca marked this conversation as resolved.
Show resolved Hide resolved
return CHIP_NO_ERROR;
}

char command[kMaxCommandSize];
snprintf(command, sizeof(command), "pairing already-discovered %ld %d %s %d", remoteId, kSetupPinCode,
reinterpret_cast<const char *>(mRemoteAddr.data()), kRemoteBridgePort);

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

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

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;
yufengwangca marked this conversation as resolved.
Show resolved Hide resolved
}

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

if (bridgeNodeId == kUndefinedNodeId)
yufengwangca marked this conversation as resolved.
Show resolved Hide resolved
{
// print to console
fprintf(stderr, "Remote Fabric Bridge is not configured yet, nothing to remove.");
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_NOT_IMPLEMENTED;
}
yufengwangca marked this conversation as resolved.
Show resolved Hide resolved

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 +164,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 +206,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,17 +217,23 @@ 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"));

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

openCommand->RegisterDelegate(this);
Expand All @@ -131,3 +242,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;
}
47 changes: 45 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,55 @@
#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);
AddArgument("device-remote-ip", &mRemoteAddr);
}

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;
yufengwangca marked this conversation as resolved.
Show resolved Hide resolved
chip::NodeId mBridgeNodeId;
chip::ByteSpan mRemoteAddr;

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 +93,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);
};
4 changes: 1 addition & 3 deletions examples/fabric-admin/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,9 +538,7 @@ void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_E
// print to console
fprintf(stderr, "Device with Node ID: 0x%lx has been successfully removed.\n", nodeId);

#if defined(PW_RPC_ENABLED)
RemoveSynchronizedDevice(nodeId);
#endif
// TODO: (#33973) Add RPC method RemoveSynchronizedDevice
}
else
{
Expand Down
Loading
Loading