Skip to content

Commit e8e9fc5

Browse files
[Fabric-Admin] Add API to commission local bridge within its own fabric (project-chip#35020)
* Add local bridge handle API * Update examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp Co-authored-by: saurabhst <s.kumar9@samsung.com> * Update examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp Co-authored-by: saurabhst <s.kumar9@samsung.com> * Use VerifyOrDie to check pairingCommand --------- Co-authored-by: saurabhst <s.kumar9@samsung.com>
1 parent 6cdd274 commit e8e9fc5

File tree

5 files changed

+210
-15
lines changed

5 files changed

+210
-15
lines changed

examples/fabric-admin/commands/fabric-sync/Commands.h

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ void registerCommandsFabricSync(Commands & commands, CredentialIssuerCommands *
2828
commands_list clusterCommands = {
2929
make_unique<FabricSyncAddBridgeCommand>(credsIssuerConfig),
3030
make_unique<FabricSyncRemoveBridgeCommand>(credsIssuerConfig),
31+
make_unique<FabricSyncAddLocalBridgeCommand>(credsIssuerConfig),
32+
make_unique<FabricSyncRemoveLocalBridgeCommand>(credsIssuerConfig),
3133
make_unique<FabricSyncDeviceCommand>(credsIssuerConfig),
3234
make_unique<FabricAutoSyncCommand>(credsIssuerConfig),
3335
};

examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp

+110-11
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,14 @@ using namespace ::chip;
3232

3333
namespace {
3434

35-
// Constants
36-
constexpr uint32_t kCommissionPrepareTimeMs = 500;
37-
constexpr uint16_t kMaxManaulCodeLength = 21;
38-
3935
void CheckFabricBridgeSynchronizationSupport(intptr_t ignored)
4036
{
4137
DeviceMgr().ReadSupportedDeviceCategories();
4238
}
4339

4440
} // namespace
4541

46-
void FabricSyncAddBridgeCommand::OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err)
42+
void FabricSyncAddBridgeCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err)
4743
{
4844
if (mBridgeNodeId != deviceId)
4945
{
@@ -90,15 +86,15 @@ CHIP_ERROR FabricSyncAddBridgeCommand::RunCommand(NodeId remoteId)
9086
if (DeviceMgr().IsFabricSyncReady())
9187
{
9288
// print to console
93-
fprintf(stderr, "Remote Fabric Bridge has been alread configured.");
89+
fprintf(stderr, "Remote Fabric Bridge has already been configured.");
9490
return CHIP_NO_ERROR;
9591
}
9692

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

9995
if (pairingCommand == nullptr)
10096
{
101-
ChipLogError(NotSpecified, "Pairing onnetwork command is not available");
97+
ChipLogError(NotSpecified, "Pairing already-discovered command is not available");
10298
return CHIP_ERROR_NOT_IMPLEMENTED;
10399
}
104100

@@ -110,7 +106,7 @@ CHIP_ERROR FabricSyncAddBridgeCommand::RunCommand(NodeId remoteId)
110106
return CHIP_NO_ERROR;
111107
}
112108

113-
void FabricSyncRemoveBridgeCommand::OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err)
109+
void FabricSyncRemoveBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err)
114110
{
115111
if (mBridgeNodeId != deviceId)
116112
{
@@ -150,7 +146,7 @@ CHIP_ERROR FabricSyncRemoveBridgeCommand::RunCommand()
150146

151147
if (pairingCommand == nullptr)
152148
{
153-
ChipLogError(NotSpecified, "Pairing code command is not available");
149+
ChipLogError(NotSpecified, "Pairing unpair command is not available");
154150
return CHIP_ERROR_NOT_IMPLEMENTED;
155151
}
156152

@@ -161,13 +157,116 @@ CHIP_ERROR FabricSyncRemoveBridgeCommand::RunCommand()
161157
return CHIP_NO_ERROR;
162158
}
163159

160+
void FabricSyncAddLocalBridgeCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err)
161+
{
162+
if (mLocalBridgeNodeId != deviceId)
163+
{
164+
if (err != CHIP_NO_ERROR)
165+
{
166+
ChipLogError(NotSpecified, "Failed to pair non-bridge device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
167+
ChipLogValueX64(deviceId), err.Format());
168+
}
169+
else
170+
{
171+
ChipLogProgress(NotSpecified, "Commissioning complete for non-bridge device: NodeId: " ChipLogFormatX64,
172+
ChipLogValueX64(deviceId));
173+
}
174+
return;
175+
}
176+
177+
if (err == CHIP_NO_ERROR)
178+
{
179+
DeviceMgr().SetLocalBridgeNodeId(mLocalBridgeNodeId);
180+
ChipLogProgress(NotSpecified, "Successfully paired local bridge device: NodeId: " ChipLogFormatX64,
181+
ChipLogValueX64(mLocalBridgeNodeId));
182+
}
183+
else
184+
{
185+
ChipLogError(NotSpecified, "Failed to pair local bridge device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
186+
ChipLogValueX64(deviceId), err.Format());
187+
}
188+
189+
mLocalBridgeNodeId = kUndefinedNodeId;
190+
}
191+
192+
CHIP_ERROR FabricSyncAddLocalBridgeCommand::RunCommand(NodeId deviceId)
193+
{
194+
if (DeviceMgr().IsLocalBridgeReady())
195+
{
196+
// print to console
197+
fprintf(stderr, "Local Fabric Bridge has already been configured.");
198+
return CHIP_NO_ERROR;
199+
}
200+
201+
PairingCommand * pairingCommand = static_cast<PairingCommand *>(CommandMgr().GetCommandByName("pairing", "already-discovered"));
202+
VerifyOrDie(pairingCommand != nullptr);
203+
204+
pairingCommand->RegisterCommissioningDelegate(this);
205+
mLocalBridgeNodeId = deviceId;
206+
207+
DeviceMgr().PairLocalFabricBridge(deviceId);
208+
209+
return CHIP_NO_ERROR;
210+
}
211+
212+
void FabricSyncRemoveLocalBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err)
213+
{
214+
if (mLocalBridgeNodeId != deviceId)
215+
{
216+
ChipLogProgress(NotSpecified, "A non-bridge device: NodeId: " ChipLogFormatX64 " is removed.", ChipLogValueX64(deviceId));
217+
return;
218+
}
219+
220+
if (err == CHIP_NO_ERROR)
221+
{
222+
DeviceMgr().SetLocalBridgeNodeId(kUndefinedNodeId);
223+
ChipLogProgress(NotSpecified, "Successfully removed local bridge device: NodeId: " ChipLogFormatX64,
224+
ChipLogValueX64(mLocalBridgeNodeId));
225+
}
226+
else
227+
{
228+
ChipLogError(NotSpecified, "Failed to remove local bridge device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
229+
ChipLogValueX64(deviceId), err.Format());
230+
}
231+
232+
mLocalBridgeNodeId = kUndefinedNodeId;
233+
}
234+
235+
CHIP_ERROR FabricSyncRemoveLocalBridgeCommand::RunCommand()
236+
{
237+
NodeId bridgeNodeId = DeviceMgr().GetLocalBridgeNodeId();
238+
239+
if (bridgeNodeId == kUndefinedNodeId)
240+
{
241+
// print to console
242+
fprintf(stderr, "Local Fabric Bridge is not configured yet, nothing to remove.");
243+
return CHIP_NO_ERROR;
244+
}
245+
246+
mLocalBridgeNodeId = bridgeNodeId;
247+
248+
PairingCommand * pairingCommand = static_cast<PairingCommand *>(CommandMgr().GetCommandByName("pairing", "unpair"));
249+
250+
if (pairingCommand == nullptr)
251+
{
252+
ChipLogError(NotSpecified, "Pairing unpair command is not available");
253+
return CHIP_ERROR_NOT_IMPLEMENTED;
254+
}
255+
256+
pairingCommand->RegisterPairingDelegate(this);
257+
258+
DeviceMgr().UnpairLocalFabricBridge();
259+
260+
return CHIP_NO_ERROR;
261+
}
262+
164263
void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_ERROR err, chip::SetupPayload payload)
165264
{
166265
ChipLogProgress(NotSpecified, "FabricSyncDeviceCommand::OnCommissioningWindowOpened");
167266

168267
if (err == CHIP_NO_ERROR)
169268
{
170-
char payloadBuffer[kMaxManaulCodeLength + 1];
269+
char payloadBuffer[kMaxManualCodeLength + 1];
171270
MutableCharSpan manualCode(payloadBuffer);
172271
CHIP_ERROR error = ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(manualCode);
173272
if (error == CHIP_NO_ERROR)
@@ -202,7 +301,7 @@ void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_
202301
}
203302
}
204303

205-
void FabricSyncDeviceCommand::OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err)
304+
void FabricSyncDeviceCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err)
206305
{
207306
if (mAssignedNodeId != deviceId)
208307
{

examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h

+46-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <commands/pairing/OpenCommissioningWindowCommand.h>
2323
#include <commands/pairing/PairingCommand.h>
2424

25+
// Constants
26+
constexpr uint32_t kCommissionPrepareTimeMs = 500;
27+
constexpr uint16_t kMaxManualCodeLength = 21;
28+
2529
class FabricSyncAddBridgeCommand : public CHIPCommand, public CommissioningDelegate
2630
{
2731
public:
@@ -31,7 +35,7 @@ class FabricSyncAddBridgeCommand : public CHIPCommand, public CommissioningDeleg
3135
AddArgument("device-remote-ip", &mRemoteAddr);
3236
}
3337

34-
void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) override;
38+
void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err) override;
3539

3640
/////////// CHIPCommand Interface /////////
3741
CHIP_ERROR RunCommand() override { return RunCommand(mNodeId); }
@@ -63,6 +67,47 @@ class FabricSyncRemoveBridgeCommand : public CHIPCommand, public PairingDelegate
6367
chip::NodeId mBridgeNodeId;
6468
};
6569

70+
class FabricSyncAddLocalBridgeCommand : public CHIPCommand, public CommissioningDelegate
71+
{
72+
public:
73+
FabricSyncAddLocalBridgeCommand(CredentialIssuerCommands * credIssuerCommands) :
74+
CHIPCommand("add-local-bridge", credIssuerCommands)
75+
{
76+
AddArgument("nodeid", 0, UINT64_MAX, &mNodeId);
77+
}
78+
79+
void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) override;
80+
81+
/////////// CHIPCommand Interface /////////
82+
CHIP_ERROR RunCommand() override { return RunCommand(mNodeId); }
83+
84+
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(1); }
85+
86+
private:
87+
chip::NodeId mNodeId;
88+
chip::NodeId mLocalBridgeNodeId;
89+
90+
CHIP_ERROR RunCommand(chip::NodeId deviceId);
91+
};
92+
93+
class FabricSyncRemoveLocalBridgeCommand : public CHIPCommand, public PairingDelegate
94+
{
95+
public:
96+
FabricSyncRemoveLocalBridgeCommand(CredentialIssuerCommands * credIssuerCommands) :
97+
CHIPCommand("remove-local-bridge", credIssuerCommands)
98+
{}
99+
100+
void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) override;
101+
102+
/////////// CHIPCommand Interface /////////
103+
CHIP_ERROR RunCommand() override;
104+
105+
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(1); }
106+
107+
private:
108+
chip::NodeId mLocalBridgeNodeId;
109+
};
110+
66111
class FabricSyncDeviceCommand : public CHIPCommand, public CommissioningWindowDelegate, public CommissioningDelegate
67112
{
68113
public:

examples/fabric-admin/device_manager/DeviceManager.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace {
3333
// Constants
3434
constexpr uint32_t kSetupPinCode = 20202021;
3535
constexpr uint16_t kRemoteBridgePort = 5540;
36+
constexpr uint16_t kLocalBridgePort = 5540;
3637
constexpr uint16_t kWindowTimeout = 300;
3738
constexpr uint16_t kIteration = 1000;
3839
constexpr uint16_t kSubscribeMinInterval = 0;
@@ -117,6 +118,8 @@ void DeviceManager::RemoveSyncedDevice(NodeId nodeId)
117118
void DeviceManager::OpenDeviceCommissioningWindow(NodeId nodeId, uint32_t commissioningTimeout, uint32_t iterations,
118119
uint32_t discriminator, const char * saltHex, const char * verifierHex)
119120
{
121+
ChipLogProgress(NotSpecified, "Open the commissioning window of device with NodeId:" ChipLogFormatX64, ChipLogValueX64(nodeId));
122+
120123
// Open the commissioning window of a device within its own fabric.
121124
StringBuilder<kMaxCommandSize> commandBuilder;
122125

@@ -132,7 +135,7 @@ void DeviceManager::OpenRemoteDeviceCommissioningWindow(EndpointId remoteEndpoin
132135
// Open the commissioning window of a device from another fabric via its fabric bridge.
133136
// This method constructs and sends a command to open the commissioning window for a device
134137
// that is part of a different fabric, accessed through a fabric bridge.
135-
StringBuilder<512> commandBuilder;
138+
StringBuilder<kMaxCommandSize> commandBuilder;
136139

137140
// Use random discriminator to have less chance of collission.
138141
uint16_t discriminator =
@@ -166,6 +169,16 @@ void DeviceManager::PairRemoteDevice(chip::NodeId nodeId, const char * payload)
166169
PushCommand(commandBuilder.c_str());
167170
}
168171

172+
void DeviceManager::PairLocalFabricBridge(NodeId nodeId)
173+
{
174+
StringBuilder<kMaxCommandSize> commandBuilder;
175+
176+
commandBuilder.Add("pairing already-discovered ");
177+
commandBuilder.AddFormat("%lu %d ::1 %d", nodeId, kSetupPinCode, kLocalBridgePort);
178+
179+
PushCommand(commandBuilder.c_str());
180+
}
181+
169182
void DeviceManager::UnpairRemoteFabricBridge()
170183
{
171184
StringBuilder<kMaxCommandSize> commandBuilder;
@@ -176,6 +189,16 @@ void DeviceManager::UnpairRemoteFabricBridge()
176189
PushCommand(commandBuilder.c_str());
177190
}
178191

192+
void DeviceManager::UnpairLocalFabricBridge()
193+
{
194+
StringBuilder<kMaxCommandSize> commandBuilder;
195+
196+
commandBuilder.Add("pairing unpair ");
197+
commandBuilder.AddFormat("%lu", mLocalBridgeNodeId);
198+
199+
PushCommand(commandBuilder.c_str());
200+
}
201+
179202
void DeviceManager::SubscribeRemoteFabricBridge()
180203
{
181204
// Listen to the state changes of the remote fabric bridge.

examples/fabric-admin/device_manager/DeviceManager.h

+28-2
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,20 @@ class DeviceManager : public PairingDelegate
5555

5656
chip::NodeId GetRemoteBridgeNodeId() const { return mRemoteBridgeNodeId; }
5757

58+
chip::NodeId GetLocalBridgeNodeId() const { return mLocalBridgeNodeId; }
59+
5860
void UpdateLastUsedNodeId(chip::NodeId nodeId);
5961

60-
void SetRemoteBridgeNodeId(chip::NodeId remoteBridgeNodeId) { mRemoteBridgeNodeId = remoteBridgeNodeId; }
62+
void SetRemoteBridgeNodeId(chip::NodeId nodeId) { mRemoteBridgeNodeId = nodeId; }
63+
64+
void SetLocalBridgeNodeId(chip::NodeId nodeId) { mLocalBridgeNodeId = nodeId; }
6165

6266
bool IsAutoSyncEnabled() const { return mAutoSyncEnabled; }
6367

6468
bool IsFabricSyncReady() const { return mRemoteBridgeNodeId != chip::kUndefinedNodeId; }
6569

70+
bool IsLocalBridgeReady() const { return mLocalBridgeNodeId != chip::kUndefinedNodeId; }
71+
6672
void EnableAutoSync(bool state) { mAutoSyncEnabled = state; }
6773

6874
void AddSyncedDevice(const Device & device);
@@ -126,8 +132,20 @@ class DeviceManager : public PairingDelegate
126132
*/
127133
void PairRemoteDevice(chip::NodeId nodeId, const char * payload);
128134

135+
/**
136+
* @brief Pair a local fabric bridge with a given node ID.
137+
*
138+
* This function initiates the pairing process for the local fabric bridge using the specified parameters.
139+
140+
* @param nodeId The user-defined ID for the node being commissioned. It doesn’t need to be the same ID,
141+
* as for the first fabric.
142+
*/
143+
void PairLocalFabricBridge(chip::NodeId nodeId);
144+
129145
void UnpairRemoteFabricBridge();
130146

147+
void UnpairLocalFabricBridge();
148+
131149
void SubscribeRemoteFabricBridge();
132150

133151
void StartReverseCommissioning();
@@ -147,8 +165,16 @@ class DeviceManager : public PairingDelegate
147165

148166
static DeviceManager sInstance;
149167

150-
chip::NodeId mLastUsedNodeId = 0;
168+
chip::NodeId mLastUsedNodeId = 0;
169+
170+
// The Node ID of the remote bridge used for Fabric-Sync
171+
// This represents the bridge on the other ecosystem.
151172
chip::NodeId mRemoteBridgeNodeId = chip::kUndefinedNodeId;
173+
174+
// The Node ID of the local bridge used for Fabric-Sync
175+
// This represents the bridge within its own ecosystem.
176+
chip::NodeId mLocalBridgeNodeId = chip::kUndefinedNodeId;
177+
152178
std::set<Device> mSyncedDevices;
153179
bool mAutoSyncEnabled = false;
154180
bool mInitialized = false;

0 commit comments

Comments
 (0)