Skip to content

Commit

Permalink
Add SetUpCodePairer::PairDevice to handle scanning from a setup code
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple committed Sep 21, 2021
1 parent 2d5a99b commit 676adf0
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 30 deletions.
22 changes: 2 additions & 20 deletions examples/chip-tool/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,30 +131,12 @@ void PairingCommand::OnDeviceConnectionFailureFn(void * context, NodeId deviceId

CHIP_ERROR PairingCommand::PairWithQRCode(NodeId remoteId)
{
SetupPayload payload;
ReturnErrorOnFailure(QRCodeSetupPayloadParser(mOnboardingPayload).populatePayload(payload));

chip::RendezvousInformationFlags rendezvousInformation = payload.rendezvousInformation;
ReturnErrorCodeIf(rendezvousInformation != RendezvousInformationFlag::kBLE, CHIP_ERROR_INVALID_ARGUMENT);

return PairWithCode(remoteId, payload);
return GetExecContext()->commissioner->PairDevice(remoteId, mOnboardingPayload);
}

CHIP_ERROR PairingCommand::PairWithManualCode(NodeId remoteId)
{
SetupPayload payload;
ReturnErrorOnFailure(ManualSetupPayloadParser(mOnboardingPayload).populatePayload(payload));
return PairWithCode(remoteId, payload);
}

CHIP_ERROR PairingCommand::PairWithCode(NodeId remoteId, SetupPayload payload)
{
RendezvousParameters params = RendezvousParameters()
.SetSetupPINCode(payload.setUpPINCode)
.SetDiscriminator(payload.discriminator)
.SetPeerAddress(PeerAddress::BLE());

return GetExecContext()->commissioner->PairDevice(remoteId, params);
return GetExecContext()->commissioner->PairDevice(remoteId, mOnboardingPayload);
}

CHIP_ERROR PairingCommand::Pair(NodeId remoteId, PeerAddress address)
Expand Down
1 change: 0 additions & 1 deletion examples/chip-tool/commands/pairing/PairingCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ class PairingCommand : public Command,
break;
case PairingMode::QRCode:
case PairingMode::ManualCode:
AddArgument("fabric-id", 0, UINT64_MAX, &mFabricId);
AddArgument("payload", &mOnboardingPayload);
break;
case PairingMode::Ble:
Expand Down
2 changes: 1 addition & 1 deletion scripts/tests/test_suites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ for j in "${iter_array[@]}"; do
# the data is there yet.
background_pid="$(</tmp/pid)"
echo " * Pairing to device"
"${test_case_wrapper[@]}" out/debug/standalone/chip-tool pairing onnetwork-long 20202021 3840
"${test_case_wrapper[@]}" out/debug/standalone/chip-tool pairing qrcode MT:D8XA0CQM00KA0648G00
echo " * Starting test run: $i"
"${test_case_wrapper[@]}" out/debug/standalone/chip-tool tests "$i"
# Prevent cleanup trying to kill a process we already killed.
Expand Down
13 changes: 7 additions & 6 deletions src/ble/BleLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,17 +373,18 @@ CHIP_ERROR BleLayer::CancelBleIncompleteConnection()
return err;
}

CHIP_ERROR BleLayer::NewBleConnectionByDiscriminator(uint16_t connDiscriminator)
CHIP_ERROR BleLayer::NewBleConnectionByDiscriminator(uint16_t connDiscriminator, void * appState,
BleConnectionDelegate::OnConnectionCompleteFunct onSuccess,
BleConnectionDelegate::OnConnectionErrorFunct onError)
{

VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(mConnectionDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(mBleTransport != nullptr, CHIP_ERROR_INCORRECT_STATE);

mConnectionDelegate->OnConnectionComplete = OnConnectionComplete;
mConnectionDelegate->OnConnectionError = OnConnectionError;
// TODO: We are passing the same parameter two times, should take a look at it to see if we can remove one of them.
mConnectionDelegate->NewConnection(this, this, connDiscriminator);
mConnectionDelegate->OnConnectionComplete = onSuccess;
mConnectionDelegate->OnConnectionError = onError;

mConnectionDelegate->NewConnection(this, appState == nullptr ? this : appState, connDiscriminator);

return CHIP_NO_ERROR;
}
Expand Down
4 changes: 3 additions & 1 deletion src/ble/BleLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ class DLL_EXPORT BleLayer
CHIP_ERROR Shutdown();

CHIP_ERROR CancelBleIncompleteConnection();
CHIP_ERROR NewBleConnectionByDiscriminator(uint16_t connDiscriminator);
CHIP_ERROR NewBleConnectionByDiscriminator(uint16_t connDiscriminator, void * appState = nullptr,
BleConnectionDelegate::OnConnectionCompleteFunct onSucess = OnConnectionComplete,
BleConnectionDelegate::OnConnectionErrorFunct onError = OnConnectionError);
CHIP_ERROR NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj);
CHIP_ERROR NewBleEndPoint(BLEEndPoint ** retEndPoint, BLE_CONNECTION_OBJECT connObj, BleRole role, bool autoClose);

Expand Down
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ static_library("controller") {
"EmptyDataModelHandler.cpp",
"ExampleOperationalCredentialsIssuer.cpp",
"ExampleOperationalCredentialsIssuer.h",
"SetUpCodePairer.cpp",
"SetUpCodePairer.h",
]

cflags = [ "-Wconversion" ]
Expand Down
12 changes: 11 additions & 1 deletion src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,8 @@ DeviceCommissioner::DeviceCommissioner() :
mNOCResponseCallback(OnOperationalCertificateAddResponse, this), mRootCertResponseCallback(OnRootCertSuccessResponse, this),
mOnCSRFailureCallback(OnCSRFailureResponse, this), mOnCertFailureCallback(OnAddNOCFailureResponse, this),
mOnRootCertFailureCallback(OnRootCertFailureResponse, this), mOnDeviceConnectedCallback(OnDeviceConnectedFn, this),
mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this), mDeviceNOCChainCallback(OnDeviceNOCChainGeneration, this)
mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this),
mDeviceNOCChainCallback(OnDeviceNOCChainGeneration, this), mSetUpCodePairer(this)
{
mPairingDelegate = nullptr;
mDeviceBeingPaired = kNumMaxActiveDevices;
Expand Down Expand Up @@ -779,6 +780,10 @@ CHIP_ERROR DeviceCommissioner::Init(CommissionerInitParams params)
mUdcServer->SetInstanceNameResolver(this);
mUdcServer->SetUserConfirmationProvider(this);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

#if CONFIG_NETWORK_LAYER_BLE
mSetUpCodePairer.SetBleLayer(mBleLayer);
#endif // CONFIG_NETWORK_LAYER_BLE
return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -811,6 +816,11 @@ CHIP_ERROR DeviceCommissioner::Shutdown()
return CHIP_NO_ERROR;
}

CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, const char * setUpCode)
{
return mSetUpCodePairer.PairDevice(remoteDeviceId, setUpCode);
}

CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParameters & params)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down
17 changes: 17 additions & 0 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <controller/CHIPDevice.h>
#include <controller/DeviceControllerInteractionModelDelegate.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <controller/SetUpCodePairer.h>
#include <credentials/CHIPOperationalCredentials.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
Expand Down Expand Up @@ -399,6 +400,21 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
CHIP_ERROR Shutdown() override;

// ----- Connection Management -----
/**
* @brief
* Pair a CHIP device with the provided code. The code can be either a QRCode
* or a Manual Setup Code.
* Use registered DevicePairingDelegate object to receive notifications on
* pairing status updates.
*
* Note: Pairing process requires that the caller has registered PersistentStorageDelegate
* in the Init() call.
*
* @param[in] remoteDeviceId The remote device Id.
* @param[in] setUpCode The setup code for connecting to the device
*/
CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode);

/**
* @brief
* Pair a CHIP device with the provided Rendezvous connection parameters.
Expand Down Expand Up @@ -682,6 +698,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;

Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
SetUpCodePairer mSetUpCodePairer;

PASESession mPairingSession;
};
Expand Down
177 changes: 177 additions & 0 deletions src/controller/SetUpCodePairer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file
* Implementation of SetUp Code Pairer, a class that parses a given
* setup code and uses the extracted informations to discover and
* filter commissionables nodes, before initiating the pairing process.
*
*/

#include <controller/SetUpCodePairer.h>

#include <controller/CHIPDeviceController.h>
#include <lib/mdns/Resolver.h>
#include <lib/support/CodeUtils.h>

namespace chip {
namespace Controller {

CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode)
{
SetupPayload payload;

bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
ReturnErrorOnFailure(isQRCode ? QRCodeSetupPayloadParser(setUpCode).populatePayload(payload)
: ManualSetupPayloadParser(setUpCode).populatePayload(payload));

mRemoteId = remoteId;
mSetUpPINCode = payload.setUpPINCode;

return Connect(payload.rendezvousInformation, payload.discriminator, !isQRCode);
}

CHIP_ERROR SetUpCodePairer::Connect(RendezvousInformationFlag rendezvousInformation, uint16_t discriminator, bool isShort)
{
CHIP_ERROR err = CHIP_NO_ERROR;
bool isRunning = false;

bool searchOverAll = rendezvousInformation == RendezvousInformationFlag::kNone;
if (searchOverAll || rendezvousInformation == RendezvousInformationFlag::kBLE)
{
if (CHIP_NO_ERROR == (err = StartDiscoverOverBle(discriminator, isShort)))
{
isRunning = true;
}
VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
}

if (searchOverAll || rendezvousInformation == RendezvousInformationFlag::kOnNetwork)
{
if (CHIP_NO_ERROR == (err = StartDiscoverOverIP(discriminator, isShort)))
{
isRunning = true;
}
VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
}

if (searchOverAll || rendezvousInformation == RendezvousInformationFlag::kSoftAP)
{
if (CHIP_NO_ERROR == (err = StartDiscoverOverSoftAP(discriminator, isShort)))
{
isRunning = true;
}
VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
}

return isRunning ? CHIP_NO_ERROR : CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

CHIP_ERROR SetUpCodePairer::StartDiscoverOverBle(uint16_t discriminator, bool isShort)
{
#if CONFIG_NETWORK_LAYER_BLE
VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
return mBleLayer->NewBleConnectionByDiscriminator(discriminator, this, OnDiscoveredDeviceOverBleSuccess,
OnDiscoveredDeviceOverBleError);
#else
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#endif // CONFIG_NETWORK_LAYER_BLE
}

CHIP_ERROR SetUpCodePairer::StopConnectOverBle()
{
#if CONFIG_NETWORK_LAYER_BLE
VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
return mBleLayer->CancelBleIncompleteConnection();
#else
return CHIP_NO_ERROR;
#endif // CONFIG_NETWORK_LAYER_BLE
}

CHIP_ERROR SetUpCodePairer::StartDiscoverOverIP(uint16_t discriminator, bool isShort)
{
#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
mCommissioner->RegisterDeviceDiscoveryDelegate(this);
Mdns::DiscoveryFilter filter(isShort ? Mdns::DiscoveryFilterType::kShort : Mdns::DiscoveryFilterType::kLong, discriminator);
return mCommissioner->DiscoverCommissionableNodes(filter);
#else
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS
}

CHIP_ERROR SetUpCodePairer::StopConnectOverIP()
{
#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
mCommissioner->RegisterDeviceDiscoveryDelegate(nullptr);
#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS
return CHIP_NO_ERROR;
}

CHIP_ERROR SetUpCodePairer::StartDiscoverOverSoftAP(uint16_t discriminator, bool isShort)
{
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

CHIP_ERROR SetUpCodePairer::StopConnectOverSoftAP()
{
return CHIP_NO_ERROR;
}

void SetUpCodePairer::OnDeviceDiscovered(RendezvousParameters & params)
{
LogErrorOnFailure(mCommissioner->PairDevice(mRemoteId, params.SetSetupPINCode(mSetUpPINCode)));
}

#if CONFIG_NETWORK_LAYER_BLE
void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj)
{
LogErrorOnFailure(StopConnectOverIP());
LogErrorOnFailure(StopConnectOverSoftAP());

Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE();
RendezvousParameters params = RendezvousParameters().SetPeerAddress(peerAddress).SetConnectionObject(connObj);
OnDeviceDiscovered(params);
}

void SetUpCodePairer::OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj)
{
(static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj);
}

void SetUpCodePairer::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err)
{
LogErrorOnFailure(err);
}
#endif // CONFIG_NETWORK_LAYER_BLE

#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
void SetUpCodePairer::OnDiscoveredDevice(const Mdns::DiscoveredNodeData & nodeData)
{
LogErrorOnFailure(StopConnectOverBle());
LogErrorOnFailure(StopConnectOverIP());
LogErrorOnFailure(StopConnectOverSoftAP());

Transport::PeerAddress peerAddress = Transport::PeerAddress::UDP(nodeData.ipAddress[0], nodeData.port, nodeData.interfaceId[0]);
RendezvousParameters params = RendezvousParameters().SetPeerAddress(peerAddress);
OnDeviceDiscovered(params);
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS

} // namespace Controller
} // namespace chip
Loading

0 comments on commit 676adf0

Please sign in to comment.