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

darwin-framework-tool: Add support for paseonly pairing #35206

Merged
merged 1 commit into from
Aug 27, 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
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@

CHIP_ERROR ModelCommand::RunCommand()
{
MTRDeviceController * commissioner = CurrentCommissioner();
ChipLogProgress(chipTool, "Sending command to node 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId));
auto * device = [MTRBaseDevice deviceWithNodeID:@(mNodeId) controller:commissioner];
auto * device = BaseDeviceWithNodeId(mNodeId);
VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE);

CHIP_ERROR err = SendCommand(device, mEndPointId);

if (err != CHIP_NO_ERROR) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#pragma once

#import <Matter/Matter.h>
#include <commands/common/Command.h>
#include <commands/common/CredentialIssuerCommands.h>
Expand All @@ -26,8 +27,6 @@

#include "../provider/OTAProviderDelegate.h"

#pragma once

inline constexpr char kIdentityAlpha[] = "alpha";
inline constexpr char kIdentityBeta[] = "beta";
inline constexpr char kIdentityGamma[] = "gamma";
Expand Down Expand Up @@ -91,6 +90,10 @@ class CHIPCommandBridge : public Command {

MTRDeviceController * GetCommissioner(const char * identity);

// Returns the MTRBaseDevice for the specified node ID.
// Will utilize an existing PASE connection if the device is being commissioned.
MTRBaseDevice * BaseDeviceWithNodeId(chip::NodeId nodeId);

// Will log the given string and given error (as progress if success, error
// if failure).
void LogNSError(const char * logString, NSError * error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@

MTRDeviceController * CHIPCommandBridge::GetCommissioner(const char * identity) { return mControllers[identity]; }

MTRBaseDevice * CHIPCommandBridge::BaseDeviceWithNodeId(chip::NodeId nodeId)
{
MTRDeviceController * controller = CurrentCommissioner();
VerifyOrReturnValue(controller != nil, nil);
return [controller deviceBeingCommissionedWithNodeID:@(nodeId) error:nullptr]
?: [MTRBaseDevice deviceWithNodeID:@(nodeId) controller:controller];
}

void CHIPCommandBridge::StopCommissioners()
{
for (auto & pair : mControllers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@

CHIP_ERROR WaitForCommissioneeCommand::RunCommand()
{
MTRDeviceController * commissioner = CurrentCommissioner();
VerifyOrReturnError(nil != commissioner, CHIP_ERROR_INCORRECT_STATE);

auto * base_device = [MTRBaseDevice deviceWithNodeID:@(mNodeId) controller:commissioner];
auto * base_device = BaseDeviceWithNodeId(mNodeId);
ksperling-apple marked this conversation as resolved.
Show resolved Hide resolved
VerifyOrReturnError(base_device != nil, CHIP_ERROR_INCORRECT_STATE);

if (mExpireExistingSession.ValueOr(true)) {
Expand Down
34 changes: 25 additions & 9 deletions examples/darwin-framework-tool/commands/pairing/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,61 +28,75 @@
class PairCode : public PairingCommandBridge
{
public:
PairCode() : PairingCommandBridge("code", PairingMode::Code, PairingNetworkType::None) {}
PairCode() : PairingCommandBridge("code", PairingMode::Code, CommissioningType::NoNetwork) {}
};

class PairCodePASEOnly : public PairingCommandBridge
{
public:
PairCodePASEOnly() : PairingCommandBridge("code-paseonly", PairingMode::Code, CommissioningType::None) {}
};

class PairCodeWifi : public PairingCommandBridge
{
public:
PairCodeWifi() : PairingCommandBridge("code-wifi", PairingMode::Code, PairingNetworkType::WiFi) {}
PairCodeWifi() : PairingCommandBridge("code-wifi", PairingMode::Code, CommissioningType::WiFi) {}
};

class PairCodeThread : public PairingCommandBridge
{
public:
PairCodeThread() : PairingCommandBridge("code-thread", PairingMode::Code, PairingNetworkType::Thread) {}
PairCodeThread() : PairingCommandBridge("code-thread", PairingMode::Code, CommissioningType::Thread) {}
};

class PairBleWiFi : public PairingCommandBridge
{
public:
PairBleWiFi() : PairingCommandBridge("ble-wifi", PairingMode::Ble, PairingNetworkType::WiFi) {}
PairBleWiFi() : PairingCommandBridge("ble-wifi", PairingMode::Ble, CommissioningType::WiFi) {}
};

class PairBleThread : public PairingCommandBridge
{
public:
PairBleThread() : PairingCommandBridge("ble-thread", PairingMode::Ble, PairingNetworkType::Thread) {}
PairBleThread() : PairingCommandBridge("ble-thread", PairingMode::Ble, CommissioningType::Thread) {}
};

class PairAlreadyDiscoveredByIndex : public PairingCommandBridge
{
public:
PairAlreadyDiscoveredByIndex() :
PairingCommandBridge("by-index", PairingMode::AlreadyDiscoveredByIndex, PairingNetworkType::None)
PairingCommandBridge("by-index", PairingMode::AlreadyDiscoveredByIndex, CommissioningType::NoNetwork)
{}
};

class PairAlreadyDiscoveredByIndexPASEOnly : public PairingCommandBridge
{
public:
PairAlreadyDiscoveredByIndexPASEOnly() :
PairingCommandBridge("by-index-paseonly", PairingMode::AlreadyDiscoveredByIndex, CommissioningType::None)
{}
};

class PairAlreadyDiscoveredByIndexWithWiFi : public PairingCommandBridge
{
public:
PairAlreadyDiscoveredByIndexWithWiFi() :
PairingCommandBridge("by-index-with-wifi", PairingMode::AlreadyDiscoveredByIndex, PairingNetworkType::WiFi)
PairingCommandBridge("by-index-with-wifi", PairingMode::AlreadyDiscoveredByIndex, CommissioningType::WiFi)
{}
};

class PairAlreadyDiscoveredByIndexWithThread : public PairingCommandBridge
{
public:
PairAlreadyDiscoveredByIndexWithThread() :
PairingCommandBridge("by-index-with-thread", PairingMode::AlreadyDiscoveredByIndex, PairingNetworkType::Thread)
PairingCommandBridge("by-index-with-thread", PairingMode::AlreadyDiscoveredByIndex, CommissioningType::Thread)
{}
};

class Unpair : public PairingCommandBridge
{
public:
Unpair() : PairingCommandBridge("unpair", PairingMode::None, PairingNetworkType::None) {}
Unpair() : PairingCommandBridge("unpair", PairingMode::Unpair, CommissioningType::None) {}
};

void registerCommandsPairing(Commands & commands)
Expand All @@ -91,11 +105,13 @@ void registerCommandsPairing(Commands & commands)

commands_list clusterCommands = {
make_unique<PairCode>(),
make_unique<PairCodePASEOnly>(),
make_unique<PairCodeWifi>(),
make_unique<PairCodeThread>(),
make_unique<PairBleWiFi>(),
make_unique<PairBleThread>(),
make_unique<PairAlreadyDiscoveredByIndex>(),
make_unique<PairAlreadyDiscoveredByIndexPASEOnly>(),
make_unique<Unpair>(),
make_unique<OpenCommissioningWindowCommand>(),
make_unique<PreWarmCommissioningCommand>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ - (void)controller:(MTRDeviceController *)controller commissioningSessionEstabli
}
ChipLogProgress(chipTool, "Pairing Success");
ChipLogProgress(chipTool, "PASE establishment successful");
if (_params == nil) {
_commandBridge->SetCommandExitStatus(nil);
return;
}

NSError * commissionError;
[_commissioner commissionNodeWithID:@(_deviceID) commissioningParams:_params error:&commissionError];
if (commissionError != nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@

enum class PairingMode
{
None,
Unpair,
Code,
Ble,
AlreadyDiscoveredByIndex,
};

enum class PairingNetworkType
enum class CommissioningType
{
None,
None, // establish PASE only
NoNetwork,
ksperling-apple marked this conversation as resolved.
Show resolved Hide resolved
WiFi,
Thread,
Ethernet,
Expand All @@ -39,27 +40,28 @@ enum class PairingNetworkType
class PairingCommandBridge : public CHIPCommandBridge
{
public:
PairingCommandBridge(const char * commandName, PairingMode mode, PairingNetworkType networkType) :
CHIPCommandBridge(commandName), mPairingMode(mode), mNetworkType(networkType)
PairingCommandBridge(const char * commandName, PairingMode mode, CommissioningType commissioningType) :
CHIPCommandBridge(commandName), mPairingMode(mode), mCommissioningType(commissioningType)
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
switch (networkType)
switch (commissioningType)
{
case PairingNetworkType::None:
case PairingNetworkType::Ethernet:
case CommissioningType::None:
case CommissioningType::NoNetwork:
case CommissioningType::Ethernet:
break;
case PairingNetworkType::WiFi:
case CommissioningType::WiFi:
AddArgument("ssid", &mSSID);
AddArgument("password", &mPassword);
break;
case PairingNetworkType::Thread:
case CommissioningType::Thread:
AddArgument("operationalDataset", &mOperationalDataset);
break;
}

switch (mode)
{
case PairingMode::None:
case PairingMode::Unpair:
break;
case PairingMode::Code:
AddArgument("payload", &mOnboardingPayload);
Expand All @@ -74,17 +76,16 @@ class PairingCommandBridge : public CHIPCommandBridge
break;
}

if (mode != PairingMode::None)
if (commissioningType != CommissioningType::None)
{
AddArgument("country-code", &mCountryCode,
"Country code to use to set the Basic Information cluster's Location attribute");
AddArgument("use-device-attestation-delegate", 0, 1, &mUseDeviceAttestationDelegate,
"If true, use a device attestation delegate that always wants to be notified about attestation results. "
"Defaults to false.");
AddArgument("device-attestation-failsafe-time", 0, UINT16_MAX, &mDeviceAttestationFailsafeTime,
"If set, the time to extend the failsafe to before calling the device attestation delegate");
}

AddArgument("use-device-attestation-delegate", 0, 1, &mUseDeviceAttestationDelegate,
"If true, use a device attestation delegate that always wants to be notified about attestation results. "
"Defaults to false.");
AddArgument("device-attestation-failsafe-time", 0, UINT16_MAX, &mDeviceAttestationFailsafeTime,
"If set, the time to extend the failsafe to before calling the device attestation delegate");
}

/////////// CHIPCommandBridge Interface /////////
Expand All @@ -99,7 +100,7 @@ class PairingCommandBridge : public CHIPCommandBridge
void SetUpDeviceControllerDelegate();

const PairingMode mPairingMode;
const PairingNetworkType mNetworkType;
const CommissioningType mCommissioningType;
chip::ByteSpan mOperationalDataset;
chip::ByteSpan mSSID;
chip::ByteSpan mPassword;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,48 +48,51 @@ - (void)deviceAttestationCompletedForController:(MTRDeviceController *)controlle

void PairingCommandBridge::SetUpDeviceControllerDelegate()
{
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.pairing", DISPATCH_QUEUE_SERIAL);
CHIPToolDeviceControllerDelegate * deviceControllerDelegate = [[CHIPToolDeviceControllerDelegate alloc] init];
MTRCommissioningParameters * params = [[MTRCommissioningParameters alloc] init];
MTRDeviceController * commissioner = CurrentCommissioner();

[deviceControllerDelegate setCommandBridge:this];
[deviceControllerDelegate setDeviceID:mNodeId];
switch (mNetworkType) {
case PairingNetworkType::None:
case PairingNetworkType::Ethernet:
break;
case PairingNetworkType::WiFi:
[params setWifiSSID:[NSData dataWithBytes:mSSID.data() length:mSSID.size()]];
[params setWifiCredentials:[NSData dataWithBytes:mPassword.data() length:mPassword.size()]];
break;
case PairingNetworkType::Thread:
[params setThreadOperationalDataset:[NSData dataWithBytes:mOperationalDataset.data() length:mOperationalDataset.size()]];
break;
}

if (mUseDeviceAttestationDelegate.ValueOr(false)) {
params.deviceAttestationDelegate = [[NoOpAttestationDelegate alloc] init];
if (mDeviceAttestationFailsafeTime.HasValue()) {
params.failSafeTimeout = @(mDeviceAttestationFailsafeTime.Value());
if (mCommissioningType != CommissioningType::None) {
MTRCommissioningParameters * params = [[MTRCommissioningParameters alloc] init];
switch (mCommissioningType) {
case CommissioningType::None:
case CommissioningType::NoNetwork:
case CommissioningType::Ethernet:
break;
case CommissioningType::WiFi:
[params setWifiSSID:[NSData dataWithBytes:mSSID.data() length:mSSID.size()]];
[params setWifiCredentials:[NSData dataWithBytes:mPassword.data() length:mPassword.size()]];
break;
case CommissioningType::Thread:
[params setThreadOperationalDataset:[NSData dataWithBytes:mOperationalDataset.data() length:mOperationalDataset.size()]];
break;
}
}

if (mCountryCode.HasValue()) {
params.countryCode = [NSString stringWithUTF8String:mCountryCode.Value()];
if (mUseDeviceAttestationDelegate.ValueOr(false)) {
params.deviceAttestationDelegate = [[NoOpAttestationDelegate alloc] init];
if (mDeviceAttestationFailsafeTime.HasValue()) {
params.failSafeTimeout = @(mDeviceAttestationFailsafeTime.Value());
}
}

if (mCountryCode.HasValue()) {
params.countryCode = [NSString stringWithUTF8String:mCountryCode.Value()];
}

[deviceControllerDelegate setParams:params];
}

[deviceControllerDelegate setCommandBridge:this];
[deviceControllerDelegate setParams:params];
MTRDeviceController * commissioner = CurrentCommissioner();
[deviceControllerDelegate setCommissioner:commissioner];

dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.pairing", DISPATCH_QUEUE_SERIAL);
[commissioner setDeviceControllerDelegate:deviceControllerDelegate queue:callbackQueue];
}

CHIP_ERROR PairingCommandBridge::RunCommand()
{
NSError * error;
switch (mPairingMode) {
case PairingMode::None:
case PairingMode::Unpair:
Unpair();
break;
case PairingMode::Code:
Expand Down Expand Up @@ -155,8 +158,7 @@ - (void)deviceAttestationCompletedForController:(MTRDeviceController *)controlle
void PairingCommandBridge::Unpair()
{
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip-tool.command", DISPATCH_QUEUE_SERIAL);
MTRDeviceController * commissioner = CurrentCommissioner();
auto * device = [MTRBaseDevice deviceWithNodeID:@(mNodeId) controller:commissioner];
auto * device = BaseDeviceWithNodeId(mNodeId);

ChipLogProgress(chipTool, "Attempting to unpair device %llu", mNodeId);
MTRBaseClusterOperationalCredentials * opCredsCluster =
Expand Down
Loading