Skip to content

Commit ba33cf2

Browse files
[Fabric-Sync] Implement pair-device command (project-chip#36508)
* [Fabric-Sync] Port pair-device command from fabric-admin * Update examples/fabric-sync/shell/ShellCommands.cpp Co-authored-by: Terence Hampson <thampson@google.com> --------- Co-authored-by: Terence Hampson <thampson@google.com>
1 parent c39a06f commit ba33cf2

File tree

4 files changed

+155
-0
lines changed

4 files changed

+155
-0
lines changed

examples/fabric-sync/shell/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ source_set("shell") {
3333
"AddDeviceCommand.h",
3434
"CommandRegistry.cpp",
3535
"CommandRegistry.h",
36+
"PairDeviceCommand.cpp",
37+
"PairDeviceCommand.h",
3638
"RemoveBridgeCommand.cpp",
3739
"RemoveBridgeCommand.h",
3840
"RemoveDeviceCommand.cpp",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2024 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
#include "PairDeviceCommand.h"
20+
21+
#include <admin/DeviceManager.h>
22+
#include <lib/shell/streamer.h>
23+
24+
using namespace ::chip;
25+
26+
namespace commands {
27+
28+
PairDeviceCommand::PairDeviceCommand(chip::NodeId nodeId, const char * payload) : mNodeId(nodeId), mPayload(payload) {}
29+
30+
void PairDeviceCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err)
31+
{
32+
if (mNodeId != deviceId)
33+
{
34+
if (err != CHIP_NO_ERROR)
35+
{
36+
ChipLogError(NotSpecified,
37+
"Failed to pair non-specified device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
38+
ChipLogValueX64(deviceId), err.Format());
39+
}
40+
else
41+
{
42+
ChipLogProgress(NotSpecified, "Commissioning complete for non-specified device: NodeId: " ChipLogFormatX64,
43+
ChipLogValueX64(deviceId));
44+
}
45+
return;
46+
}
47+
48+
if (err == CHIP_NO_ERROR)
49+
{
50+
ChipLogProgress(NotSpecified, "Successfully paired device: NodeId: " ChipLogFormatX64, ChipLogValueX64(mNodeId));
51+
52+
admin::DeviceManager::Instance().UpdateLastUsedNodeId(mNodeId);
53+
}
54+
else
55+
{
56+
ChipLogError(NotSpecified, "Failed to pair device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
57+
ChipLogValueX64(deviceId), err.Format());
58+
}
59+
60+
CommandRegistry::Instance().ResetActiveCommand();
61+
}
62+
63+
CHIP_ERROR PairDeviceCommand::RunCommand()
64+
{
65+
if (admin::DeviceManager::Instance().IsCurrentBridgeDevice(mNodeId))
66+
{
67+
// print to console
68+
fprintf(stderr, "The specified node ID has been reserved by the Fabric Bridge.\n");
69+
return CHIP_ERROR_INVALID_ARGUMENT;
70+
}
71+
72+
ChipLogProgress(NotSpecified, "Running PairDeviceCommand with Node ID: %lu, Code: %s", mNodeId, mPayload);
73+
74+
admin::PairingManager::Instance().SetPairingDelegate(this);
75+
76+
return admin::PairingManager::Instance().PairDeviceWithCode(mNodeId, mPayload);
77+
}
78+
79+
} // namespace commands
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2024 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
#pragma once
20+
21+
#include <CommandRegistry.h>
22+
#include <admin/PairingManager.h>
23+
24+
namespace commands {
25+
26+
class PairDeviceCommand : public Command, public admin::PairingDelegate
27+
{
28+
public:
29+
PairDeviceCommand(chip::NodeId nodeId, const char * payload);
30+
void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err) override;
31+
CHIP_ERROR RunCommand() override;
32+
33+
private:
34+
chip::NodeId mNodeId;
35+
const char * mPayload;
36+
};
37+
38+
} // namespace commands

examples/fabric-sync/shell/ShellCommands.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "ShellCommands.h"
1818
#include "AddBridgeCommand.h"
1919
#include "AddDeviceCommand.h"
20+
#include "PairDeviceCommand.h"
2021
#include "RemoveBridgeCommand.h"
2122
#include "RemoveDeviceCommand.h"
2223
#include "SyncDeviceCommand.h"
@@ -46,6 +47,7 @@ static CHIP_ERROR PrintAllCommands()
4647
streamer_printf(sout,
4748
" add-device Pair a device to local fabric. Usage: app add-device node-id setup-pin-code "
4849
"device-remote-ip device-remote-port\r\n");
50+
streamer_printf(sout, " pair-device Pair a device to local fabric. Usage: app pair-device node-id code\r\n");
4951
streamer_printf(sout, " remove-device Remove a device from the local fabric. Usage: app remove-device node-id\r\n");
5052
streamer_printf(sout, " sync-device Sync a device from other ecosystem. Usage: app sync-device endpointid\r\n");
5153
streamer_printf(sout, "\r\n");
@@ -145,6 +147,36 @@ static CHIP_ERROR HandleAddDeviceCommand(int argc, char ** argv)
145147
return result;
146148
}
147149

150+
static CHIP_ERROR HandlePairDeviceCommand(int argc, char ** argv)
151+
{
152+
if (argc != 3)
153+
{
154+
fprintf(stderr, "Invalid arguments. Usage: app pair-device node-id code\n");
155+
return CHIP_ERROR_INVALID_ARGUMENT;
156+
}
157+
158+
// Check if there is already an active command
159+
if (commands::CommandRegistry::Instance().IsCommandActive())
160+
{
161+
fprintf(stderr, "Another command is currently active. Please wait until it completes.\n");
162+
return CHIP_ERROR_BUSY;
163+
}
164+
165+
// Parse arguments
166+
chip::NodeId nodeId = static_cast<chip::NodeId>(strtoull(argv[1], nullptr, 10));
167+
const char * setUpCode = argv[2];
168+
169+
auto command = std::make_unique<commands::PairDeviceCommand>(nodeId, setUpCode);
170+
171+
CHIP_ERROR result = command->RunCommand();
172+
if (result == CHIP_NO_ERROR)
173+
{
174+
commands::CommandRegistry::Instance().SetActiveCommand(std::move(command));
175+
}
176+
177+
return result;
178+
}
179+
148180
static CHIP_ERROR HandleRemoveDeviceCommand(int argc, char ** argv)
149181
{
150182
if (argc != 2)
@@ -227,6 +259,10 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv)
227259
{
228260
return HandleAddDeviceCommand(argc, argv);
229261
}
262+
else if (strcmp(argv[0], "pair-device") == 0)
263+
{
264+
return HandlePairDeviceCommand(argc, argv);
265+
}
230266
else if (strcmp(argv[0], "remove-device") == 0)
231267
{
232268
return HandleRemoveDeviceCommand(argc, argv);

0 commit comments

Comments
 (0)