From 1239033b8eea69d3fff1fdcb8fd1156e351add82 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 12 Dec 2022 17:44:33 +0100 Subject: [PATCH] [Darwin / BLE] Add some code to scan without a discriminator in order to prewarm for commissioning (#24033) * [Darwin / BLE] Add some code to scan without a discriminator in order to prewarm for commissioning * [Darwin] Add an API to prepare the stack for commissioning * [darwin-framework-tool] Add a prepare-commissioning command --- .../commands/pairing/Commands.h | 2 + .../pairing/PrepareCommissioningCommand.h | 53 ++++++++ .../Framework/CHIP/MTRDeviceController.h | 10 ++ .../Framework/CHIP/MTRDeviceController.mm | 14 ++ src/platform/Darwin/BLEManagerImpl.cpp | 10 ++ src/platform/Darwin/BLEManagerImpl.h | 1 + src/platform/Darwin/BleConnectionDelegate.h | 1 + .../Darwin/BleConnectionDelegateImpl.mm | 126 ++++++++++++++++-- src/platform/Darwin/PlatformManagerImpl.cpp | 9 ++ src/platform/Darwin/PlatformManagerImpl.h | 2 + 10 files changed, 219 insertions(+), 9 deletions(-) create mode 100644 examples/darwin-framework-tool/commands/pairing/PrepareCommissioningCommand.h diff --git a/examples/darwin-framework-tool/commands/pairing/Commands.h b/examples/darwin-framework-tool/commands/pairing/Commands.h index ffda27b9e3d348..16c57b5d4ddd0f 100644 --- a/examples/darwin-framework-tool/commands/pairing/Commands.h +++ b/examples/darwin-framework-tool/commands/pairing/Commands.h @@ -22,6 +22,7 @@ #include "OpenCommissioningWindowCommand.h" #include "PairingCommandBridge.h" +#include "PrepareCommissioningCommand.h" class PairCode : public PairingCommandBridge { @@ -71,6 +72,7 @@ void registerCommandsPairing(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); diff --git a/examples/darwin-framework-tool/commands/pairing/PrepareCommissioningCommand.h b/examples/darwin-framework-tool/commands/pairing/PrepareCommissioningCommand.h new file mode 100644 index 00000000000000..c1fd777cf1146a --- /dev/null +++ b/examples/darwin-framework-tool/commands/pairing/PrepareCommissioningCommand.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 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. + */ + +#pragma once + +#import + +#include "../common/CHIPCommandBridge.h" + +#import "MTRError_Utils.h" + +class PrepareCommissioningCommand : public CHIPCommandBridge { +public: + PrepareCommissioningCommand() + : CHIPCommandBridge("prepare-commissioning") + { + } + +protected: + /////////// CHIPCommandBridge Interface ///////// + CHIP_ERROR RunCommand() override + { + auto * controller = CurrentCommissioner(); + NSError * error; + if (![controller prepareCommissioningSession:&error]) { + auto err = MTRErrorToCHIPErrorCode(error); + SetCommandExitStatus(err); + return err; + } + + // In interactive mode, we don't want to block the UI until the end of `GetWaitDuration`. So returns early. + if (IsInteractive()) { + SetCommandExitStatus(CHIP_NO_ERROR); + } + return CHIP_NO_ERROR; + } + + chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(30); } +}; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.h b/src/darwin/Framework/CHIP/MTRDeviceController.h index 6a2616a53eeb00..5bff3ebb76aaae 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController.h @@ -102,6 +102,16 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS - (nullable MTRBaseDevice *)deviceBeingCommissionedWithNodeID:(NSNumber *)nodeID error:(NSError * __autoreleasing *)error MTR_NEWLY_AVAILABLE; +/** + * Prepare the controller for setting up a commissioning session. + * + * This method is intended to be used when it is known that a setting up a commissioning session + * will happen soon. + * For example it may ask different subsystems to look for useful informations onto the network + * ahead of commissioning that may then be re-used during commissioning. + */ +- (BOOL)prepareCommissioningSession:(NSError * __autoreleasing *)error MTR_NEWLY_AVAILABLE; + /** * Controllers are created via the MTRDeviceControllerFactory object. */ diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index c9446ffcbbde0b..38abb49b1439f2 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -64,6 +64,7 @@ static NSString * const kErrorPairDevice = @"Failure while pairing the device"; static NSString * const kErrorUnpairDevice = @"Failure while unpairing the device"; static NSString * const kErrorStopPairing = @"Failure while trying to stop the pairing process"; +static NSString * const kErrorPrepareCommissioning = @"Failure while trying to prepare the commissioning process"; static NSString * const kErrorOpenPairingWindow = @"Open Pairing Window failed"; static NSString * const kErrorGetPairedDevice = @"Failure while trying to retrieve a paired device"; static NSString * const kErrorNotRunning = @"Controller is not running. Call startup first."; @@ -493,6 +494,19 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor return success; } +- (BOOL)prepareCommissioningSession:(NSError * __autoreleasing *)error +{ + __block BOOL success = NO; + dispatch_sync(_chipWorkQueue, ^{ + VerifyOrReturn([self checkIsRunning:error]); + + auto errorCode = chip::DeviceLayer::PlatformMgrImpl().PrepareCommissioning(); + success = ![MTRDeviceController checkForError:errorCode logMsg:kErrorPrepareCommissioning error:error]; + }); + + return success; +} + - (MTRBaseDevice *)deviceBeingCommissionedWithNodeID:(NSNumber *)nodeID error:(NSError * __autoreleasing *)error { VerifyOrReturnValue([self checkIsRunning:error], nil); diff --git a/src/platform/Darwin/BLEManagerImpl.cpp b/src/platform/Darwin/BLEManagerImpl.cpp index 97853f783fd2d4..0472f1908d9cbb 100644 --- a/src/platform/Darwin/BLEManagerImpl.cpp +++ b/src/platform/Darwin/BLEManagerImpl.cpp @@ -88,6 +88,16 @@ void BLEManagerImpl::_Shutdown() } } +CHIP_ERROR BLEManagerImpl::PrepareConnection() +{ + if (mConnectionDelegate) + { + static_cast(mConnectionDelegate)->PrepareConnection(); + return CHIP_NO_ERROR; + } + return CHIP_ERROR_INCORRECT_STATE; +} + bool BLEManagerImpl::_IsAdvertisingEnabled() { ChipLogDetail(DeviceLayer, "%s", __FUNCTION__); diff --git a/src/platform/Darwin/BLEManagerImpl.h b/src/platform/Darwin/BLEManagerImpl.h index 049df893702466..9d54d7d01a967f 100644 --- a/src/platform/Darwin/BLEManagerImpl.h +++ b/src/platform/Darwin/BLEManagerImpl.h @@ -42,6 +42,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer public: CHIP_ERROR ConfigureBle(uint32_t aNodeId, bool aIsCentral) { return CHIP_NO_ERROR; } + CHIP_ERROR PrepareConnection(); private: // ===== Members that implement the BLEManager internal interface. diff --git a/src/platform/Darwin/BleConnectionDelegate.h b/src/platform/Darwin/BleConnectionDelegate.h index 1a7057ee43c48a..072145e47f466a 100644 --- a/src/platform/Darwin/BleConnectionDelegate.h +++ b/src/platform/Darwin/BleConnectionDelegate.h @@ -26,6 +26,7 @@ namespace Internal { class BleConnectionDelegateImpl : public Ble::BleConnectionDelegate { public: + void PrepareConnection(); virtual void NewConnection(Ble::BleLayer * bleLayer, void * appState, const SetupDiscriminator & connDiscriminator); virtual CHIP_ERROR CancelConnection(); }; diff --git a/src/platform/Darwin/BleConnectionDelegateImpl.mm b/src/platform/Darwin/BleConnectionDelegateImpl.mm index e5cfd39778b9f8..aa891b1fc7ae4a 100644 --- a/src/platform/Darwin/BleConnectionDelegateImpl.mm +++ b/src/platform/Darwin/BleConnectionDelegateImpl.mm @@ -38,7 +38,8 @@ using namespace chip::Ble; -constexpr uint64_t kScanningTimeoutInSeconds = 60; +constexpr uint64_t kScanningWithDiscriminatorTimeoutInSeconds = 60; +constexpr uint64_t kScanningWithoutDiscriminatorTimeoutInSeconds = 120; @interface BleConnection : NSObject @@ -48,6 +49,8 @@ @interface BleConnection : NSObject