Skip to content

Commit 3326715

Browse files
Josh V [Apple]pull[bot]
Josh V [Apple]
authored andcommitted
Add Pairing Commands to chip-tool-darwin (#14662)
1 parent 45c58f8 commit 3326715

File tree

15 files changed

+575
-9
lines changed

15 files changed

+575
-9
lines changed

examples/chip-tool-darwin/.gn

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020 Project CHIP Authors
1+
# Copyright (c) 2022 Project CHIP Authors
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

examples/chip-tool-darwin/BUILD.gn

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020 Project CHIP Authors
1+
# Copyright (c) 2022 Project CHIP Authors
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -20,14 +20,24 @@ import("${chip_root}/build/chip/tools.gni")
2020
assert(chip_build_tools)
2121

2222
executable("chip-tool-darwin") {
23-
sources = [ "main.m" ]
23+
sources = [
24+
"commands/common/CHIPCommandBridge.mm",
25+
"commands/pairing/Commands.h",
26+
"commands/pairing/PairingCommandBridge.mm",
27+
"commands/pairing/PairingDelegateBridge.mm",
28+
"main.mm",
29+
]
30+
31+
include_dirs = [ "." ]
2432

2533
deps = [
34+
"${chip_root}/examples/chip-tool:chip-tool-utils",
2635
"${chip_root}/src/app/server",
2736
"${chip_root}/src/darwin/Framework/CHIP",
2837
"${chip_root}/src/lib",
2938
"${chip_root}/src/platform",
3039
"${chip_root}/third_party/inipp",
40+
"${chip_root}/third_party/jsoncpp",
3141
]
3242

3343
cflags = [
@@ -37,3 +47,21 @@ executable("chip-tool-darwin") {
3747

3848
output_dir = root_out_dir
3949
}
50+
51+
action("codesign") {
52+
script = "entitlements/codesign.py"
53+
sources = [ "entitlements/chip-tool-darwin.entitlements" ]
54+
public_deps = [ ":chip-tool-darwin" ]
55+
56+
args = [
57+
"--target_path",
58+
rebase_path("${root_build_dir}/chip-tool-darwin", root_build_dir),
59+
"--entitlements_path",
60+
rebase_path("entitlements/chip-tool-darwin.entitlements", root_build_dir),
61+
"--log_path",
62+
rebase_path("${root_build_dir}/codesign_log.txt", root_build_dir),
63+
]
64+
65+
output_name = "codesign_log.txt"
66+
outputs = [ "${root_build_dir}/${output_name}" ]
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2022 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+
#import <CHIP/CHIPDeviceController.h>
21+
#include <commands/common/Command.h>
22+
#include <commands/common/CredentialIssuerCommands.h>
23+
24+
#pragma once
25+
26+
class CHIPCommandBridge : public Command
27+
{
28+
public:
29+
CHIPCommandBridge(const char * commandName) : Command(commandName) {}
30+
31+
CHIPCommandBridge(const char * commandName, CredentialIssuerCommands * credIssuerCmds) : CHIPCommandBridge(commandName) {}
32+
33+
/////////// Command Interface /////////
34+
CHIP_ERROR Run() override;
35+
36+
void SetCommandExitStatus(CHIP_ERROR status)
37+
{
38+
mCommandExitStatus = status;
39+
ShutdownCommissioner();
40+
StopWaiting();
41+
}
42+
43+
protected:
44+
// Will be called in a setting in which it's safe to touch the CHIP
45+
// stack. The rules for Run() are as follows:
46+
//
47+
// 1) If error is returned, Run() must not call SetCommandExitStatus.
48+
// 2) If success is returned Run() must either have called
49+
// SetCommandExitStatus() or scheduled async work that will do that.
50+
virtual CHIP_ERROR RunCommand() = 0;
51+
52+
// Get the wait duration, in seconds, before the command times out.
53+
virtual chip::System::Clock::Timeout GetWaitDuration() const = 0;
54+
55+
// Shut down the command, in case any work needs to be done after the event
56+
// loop has been stopped.
57+
virtual void Shutdown() {}
58+
59+
void SetIdentity(const char * name);
60+
61+
// This method returns the commissioner instance to be used for running the command.
62+
CHIPDeviceController * CurrentCommissioner();
63+
64+
private:
65+
CHIP_ERROR InitializeCommissioner(std::string key, chip::FabricId fabricId);
66+
CHIP_ERROR ShutdownCommissioner();
67+
uint16_t CurrentCommissionerIndex();
68+
69+
CHIP_ERROR mCommandExitStatus = CHIP_ERROR_INTERNAL;
70+
71+
CHIP_ERROR StartWaiting(chip::System::Clock::Timeout seconds);
72+
void StopWaiting();
73+
CHIPDeviceController * mController;
74+
75+
#if CONFIG_USE_SEPARATE_EVENTLOOP
76+
std::condition_variable cvWaitingForResponse;
77+
std::mutex cvWaitingForResponseMutex;
78+
bool mWaitingForResponse{ true };
79+
#endif // CONFIG_USE_SEPARATE_EVENTLOOP
80+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2022 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 "CHIPCommandBridge.h"
20+
21+
#import <CHIP/CHIPDeviceController.h>
22+
#include <core/CHIPBuildConfig.h>
23+
#include <lib/support/CodeUtils.h>
24+
25+
const uint16_t kListenPort = 5541;
26+
27+
CHIP_ERROR CHIPCommandBridge::Run()
28+
{
29+
NSLog(@"Running Command");
30+
31+
mController = [CHIPDeviceController sharedController];
32+
[mController setListenPort:kListenPort];
33+
[mController startup:nil vendorId:0 nocSigner:nil];
34+
35+
RunCommand();
36+
ReturnLogErrorOnFailure(StartWaiting(GetWaitDuration()));
37+
return CHIP_NO_ERROR;
38+
}
39+
40+
CHIPDeviceController * CHIPCommandBridge::CurrentCommissioner() { return mController; }
41+
42+
CHIP_ERROR CHIPCommandBridge::ShutdownCommissioner()
43+
{
44+
NSLog(@"Shutting down controller");
45+
BOOL result = [CurrentCommissioner() shutdown];
46+
if (!result) {
47+
NSLog(@"Unable to shut down controller");
48+
return CHIP_ERROR_INTERNAL;
49+
}
50+
return CHIP_NO_ERROR;
51+
}
52+
53+
#if !CONFIG_USE_SEPARATE_EVENTLOOP
54+
static void OnResponseTimeout(chip::System::Layer *, void * appState)
55+
{
56+
(reinterpret_cast<CHIPCommandBridge *>(appState))->SetCommandExitStatus(CHIP_ERROR_TIMEOUT);
57+
}
58+
#endif // !CONFIG_USE_SEPARATE_EVENTLOOP
59+
60+
CHIP_ERROR CHIPCommandBridge::StartWaiting(chip::System::Clock::Timeout duration)
61+
{
62+
#if CONFIG_USE_SEPARATE_EVENTLOOP
63+
chip::DeviceLayer::PlatformMgr().StartEventLoopTask();
64+
auto waitingUntil = std::chrono::system_clock::now() + std::chrono::duration_cast<std::chrono::seconds>(duration);
65+
{
66+
std::unique_lock<std::mutex> lk(cvWaitingForResponseMutex);
67+
if (!cvWaitingForResponse.wait_until(lk, waitingUntil, [this]() { return !this->mWaitingForResponse; })) {
68+
mCommandExitStatus = CHIP_ERROR_TIMEOUT;
69+
}
70+
}
71+
LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask());
72+
#else
73+
ReturnLogErrorOnFailure(chip::DeviceLayer::SystemLayer().StartTimer(duration, OnResponseTimeout, this));
74+
chip::DeviceLayer::PlatformMgr().RunEventLoop();
75+
#endif // CONFIG_USE_SEPARATE_EVENTLOOP
76+
77+
return mCommandExitStatus;
78+
}
79+
80+
void CHIPCommandBridge::StopWaiting()
81+
{
82+
#if CONFIG_USE_SEPARATE_EVENTLOOP
83+
{
84+
std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
85+
mWaitingForResponse = false;
86+
}
87+
cvWaitingForResponse.notify_all();
88+
#else // CONFIG_USE_SEPARATE_EVENTLOOP
89+
LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask());
90+
#endif // CONFIG_USE_SEPARATE_EVENTLOOP
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2022 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 "PairingCommandBridge.h"
22+
23+
class Unpair : public PairingCommandBridge
24+
{
25+
public:
26+
Unpair() : PairingCommandBridge("unpair", PairingMode::None) {}
27+
};
28+
29+
class PairQRCode : public PairingCommandBridge
30+
{
31+
public:
32+
PairQRCode() : PairingCommandBridge("qrcode", PairingMode::QRCode) {}
33+
};
34+
35+
class PairManualCode : public PairingCommandBridge
36+
{
37+
public:
38+
PairManualCode() : PairingCommandBridge("manualcode", PairingMode::ManualCode) {}
39+
};
40+
41+
class PairWithIPAddress : public PairingCommandBridge
42+
{
43+
public:
44+
PairWithIPAddress() : PairingCommandBridge("ethernet", PairingMode::Ethernet) {}
45+
};
46+
47+
void registerCommandsPairing(Commands & commands)
48+
{
49+
const char * clusterName = "Pairing";
50+
51+
commands_list clusterCommands = {
52+
make_unique<Unpair>(),
53+
make_unique<PairQRCode>(),
54+
make_unique<PairManualCode>(),
55+
make_unique<PairWithIPAddress>(),
56+
};
57+
58+
commands.Register(clusterName, clusterCommands);
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2022 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+
#include "../common/CHIPCommandBridge.h"
21+
#import <CHIP/CHIPClustersObjc.h>
22+
#import <CHIP/CHIPDevicePairingDelegate.h>
23+
24+
enum class PairingMode
25+
{
26+
None,
27+
QRCode,
28+
ManualCode,
29+
Ethernet
30+
};
31+
32+
class PairingCommandBridge : public CHIPCommandBridge
33+
{
34+
public:
35+
PairingCommandBridge(const char * commandName, PairingMode mode) : CHIPCommandBridge(commandName), mPairingMode(mode)
36+
{
37+
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
38+
39+
switch (mode)
40+
{
41+
case PairingMode::None:
42+
break;
43+
case PairingMode::QRCode:
44+
AddArgument("payload", &mOnboardingPayload);
45+
break;
46+
case PairingMode::ManualCode:
47+
AddArgument("payload", &mOnboardingPayload);
48+
break;
49+
case PairingMode::Ethernet:
50+
AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
51+
AddArgument("discriminator", 0, 4096, &mDiscriminator);
52+
AddArgument("device-remote-ip", &ipAddress);
53+
AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
54+
break;
55+
}
56+
}
57+
58+
/////////// CHIPCommandBridge Interface /////////
59+
CHIP_ERROR RunCommand() override;
60+
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(120); }
61+
62+
private:
63+
void PairWithCode(NSError * error);
64+
void PairWithIPAddress(NSError * error);
65+
void Unpair(NSError * error);
66+
void SetUpPairingDelegate();
67+
68+
const PairingMode mPairingMode;
69+
chip::NodeId mNodeId;
70+
uint16_t mRemotePort;
71+
uint16_t mDiscriminator;
72+
uint32_t mSetupPINCode;
73+
char * mOnboardingPayload;
74+
char * ipAddress;
75+
};

0 commit comments

Comments
 (0)