Skip to content

Commit

Permalink
Allow creating Darwin controllers via alloc/initWithParameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
bzbarsky-apple committed Sep 1, 2023
1 parent 6cb9720 commit f17493f
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 145 deletions.
17 changes: 16 additions & 1 deletion src/darwin/Framework/CHIP/MTRDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#import <Matter/MTROperationalCertificateIssuer.h>

@class MTRBaseDevice;
@class MTRDeviceControllerParameters;

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -37,11 +38,25 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS
@interface MTRDeviceController : NSObject

/**
* Controllers are created via the MTRDeviceControllerFactory object.
* Controllers are created via the MTRDeviceControllerFactory object or
* initialized via initWithParameters:error:.
*/
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

/**
* Initialize a device controller with the provided parameters. This will:
*
* 1) Auto-start the MTRDeviceControllerFactory in storage-per-controller mode
* if it has not already been started.
* 2) Return nil or a running controller.
*
* Once this returns non-nil, it's the caller's resposibility to call shutdown
* on the controller to avoid leaking it.
*/
- (nullable instancetype)initWithParameters:(MTRDeviceControllerParameters *)parameters
error:(NSError * __autoreleasing *)error MTR_NEWLY_AVAILABLE;

/**
* If true, the controller has not been shut down yet.
*/
Expand Down
15 changes: 15 additions & 0 deletions src/darwin/Framework/CHIP/MTRDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/
#import <Matter/MTRDefines.h>
#import <Matter/MTRDeviceControllerParameters.h>

#import "MTRDeviceController_Internal.h"

Expand Down Expand Up @@ -119,6 +120,20 @@ @interface MTRDeviceController () {

@implementation MTRDeviceController

- (nullable instancetype)initWithParameters:(MTRDeviceControllerParameters *)parameters error:(NSError * __autoreleasing *)error
{
__auto_type * factory = [MTRDeviceControllerFactory sharedInstance];
if (!factory.isRunning) {
auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage];

if (![factory startControllerFactory:params error:error]) {
return nil;
}
}

return [factory initializeController:self withParameters:parameters error:error];
}

- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory
queue:(dispatch_queue_t)queue
storageDelegate:(id<MTRDeviceControllerStorageDelegate> _Nullable)storageDelegate
Expand Down
22 changes: 3 additions & 19 deletions src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#import <Foundation/Foundation.h>
#import <Matter/MTRCertificates.h>
#import <Matter/MTRDeviceControllerStartupParameters.h>

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -37,6 +36,9 @@ NS_ASSUME_NONNULL_BEGIN

API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
@interface MTRDeviceControllerFactoryParams : NSObject

- (instancetype)init NS_UNAVAILABLE;

/*
* Storage used to store persistent information for the fabrics the
* controllers ends up interacting with. This is only used if "initWithStorage"
Expand Down Expand Up @@ -93,12 +95,6 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
*/
- (instancetype)initWithStorage:(id<MTRStorage>)storage;

/*
* Initialize the device controller factory without storage. In this mode,
* device controllers will need to have per-controller storage provided to allow
* storing controller-specific information.
*/
- (instancetype)init MTR_NEWLY_AVAILABLE;
@end

API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
Expand Down Expand Up @@ -180,18 +176,6 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
- (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams
error:(NSError * __autoreleasing *)error;

/**
* Create an MTRDeviceController. Returns nil on failure.
*
* This method will fail if there is already a controller running for the given
* node identity.
*
* This method will fail if the controller factory was not initialized in
* storage-per-controller mode.
*/
- (MTRDeviceController * _Nullable)createController:(MTRDeviceControllerStartupParameters *)startupParameters
error:(NSError * __autoreleasing *)error MTR_NEWLY_AVAILABLE;

@end

MTR_DEPRECATED(
Expand Down
105 changes: 60 additions & 45 deletions src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,13 @@ - (void)stopControllerFactory
* The fabricChecker block will run on the Matter queue, and is expected to
* return nil if pre-startup fabric table checks fail, and set fabricError to
* the right error value in that situation.
*
* existingController can be provided if the controller object has already been
* allocated but not yet initialized. If not provided, a new controller object
* will be created.
*/
- (MTRDeviceController * _Nullable)_startDeviceController:(id)startupParams
- (MTRDeviceController * _Nullable)_startDeviceController:(nullable MTRDeviceController *)existingController
startupParams:(id)startupParams
fabricChecker:(MTRDeviceControllerStartupParamsInternal * (^)(FabricTable * fabricTable,
MTRDeviceController * controller,
CHIP_ERROR & fabricError))fabricChecker
Expand All @@ -563,8 +568,8 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(id)startupParams
NSUUID * uniqueIdentifier;
id<MTROTAProviderDelegate> _Nullable otaProviderDelegate;
dispatch_queue_t _Nullable otaProviderDelegateQueue;
if ([startupParams isKindOfClass:[MTRDeviceControllerStartupParameters class]]) {
MTRDeviceControllerStartupParameters * params = startupParams;
if ([startupParams isKindOfClass:[MTRDeviceControllerParameters class]]) {
MTRDeviceControllerParameters * params = startupParams;
storageDelegate = params.storageDelegate;
storageDelegateQueue = params.storageDelegateQueue;
uniqueIdentifier = params.uniqueIdentifier;
Expand Down Expand Up @@ -607,7 +612,8 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(id)startupParams

// Create the controller, so we start the event loop, since we plan to do
// our fabric table operations there.
auto * controller = [self _createController:storageDelegate
auto * controller = [self _createController:existingController
storageDelegate:storageDelegate
storageDelegateQueue:storageDelegateQueue
otaProviderDelegate:otaProviderDelegate
otaProviderDelegateQueue:otaProviderDelegateQueue
Expand Down Expand Up @@ -713,7 +719,8 @@ - (MTRDeviceController * _Nullable)createControllerOnExistingFabric:(MTRDeviceCo
return nil;
}

return [self _startDeviceController:startupParams
return [self _startDeviceController:nil
startupParams:startupParams
fabricChecker:^MTRDeviceControllerStartupParamsInternal *(
FabricTable * fabricTable, MTRDeviceController * controller, CHIP_ERROR & fabricError) {
const FabricInfo * fabric = nullptr;
Expand Down Expand Up @@ -789,7 +796,8 @@ - (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControl
return nil;
}

return [self _startDeviceController:startupParams
return [self _startDeviceController:nil
startupParams:startupParams
fabricChecker:^MTRDeviceControllerStartupParamsInternal *(
FabricTable * fabricTable, MTRDeviceController * controller, CHIP_ERROR & fabricError) {
const FabricInfo * fabric = nullptr;
Expand Down Expand Up @@ -822,50 +830,26 @@ - (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControl
error:error];
}

- (MTRDeviceController * _Nullable)createController:(MTRDeviceControllerStartupParameters *)startupParameters
error:(NSError * __autoreleasing *)error
{
[self _assertCurrentQueueIsNotMatterQueue];

return [self _startDeviceController:startupParameters
fabricChecker:^MTRDeviceControllerStartupParamsInternal *(
FabricTable * fabricTable, MTRDeviceController * controller, CHIP_ERROR & fabricError) {
auto advertiseOperational = self.advertiseOperational && startupParameters.shouldAdvertiseOperational;
auto * params =
[[MTRDeviceControllerStartupParamsInternal alloc] initForNewController:controller
fabricTable:fabricTable
keystore:self->_keystore
advertiseOperational:advertiseOperational
params:startupParameters
error:fabricError];
if (params != nil) {
if (params.productAttestationAuthorityCertificates == nil) {
params.productAttestationAuthorityCertificates = self.productAttestationAuthorityCertificates;
}
if (params.certificationDeclarationCertificates == nil) {
params.certificationDeclarationCertificates = self.certificationDeclarationCertificates;
}
}
return params;
}
error:error];
}

- (MTRDeviceController * _Nullable)_createController:(id<MTRDeviceControllerStorageDelegate> _Nullable)storageDelegate
- (MTRDeviceController * _Nullable)_createController:(nullable MTRDeviceController *)existingController
storageDelegate:(id<MTRDeviceControllerStorageDelegate> _Nullable)storageDelegate
storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue
otaProviderDelegate:(id<MTROTAProviderDelegate> _Nullable)otaProviderDelegate
otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue
uniqueIdentifier:(NSUUID *)uniqueIdentifier
{
[self _assertCurrentQueueIsNotMatterQueue];

MTRDeviceController * controller = [[MTRDeviceController alloc] initWithFactory:self
queue:_chipWorkQueue
storageDelegate:storageDelegate
storageDelegateQueue:storageDelegateQueue
otaProviderDelegate:otaProviderDelegate
otaProviderDelegateQueue:otaProviderDelegateQueue
uniqueIdentifier:uniqueIdentifier];
MTRDeviceController * controller = existingController;
if (controller == nil) {
controller = [MTRDeviceController alloc];
}
controller = [controller initWithFactory:self
queue:_chipWorkQueue
storageDelegate:storageDelegate
storageDelegateQueue:storageDelegateQueue
otaProviderDelegate:otaProviderDelegate
otaProviderDelegateQueue:otaProviderDelegateQueue
uniqueIdentifier:uniqueIdentifier];
if (controller == nil) {
MTR_LOG_ERROR("Failed to init controller");
return nil;
Expand Down Expand Up @@ -1123,6 +1107,37 @@ - (void)operationalInstanceAdded:(chip::PeerId &)operationalID
}
}

- (MTRDeviceController * _Nullable)initializeController:(MTRDeviceController *)controller
withParameters:(MTRDeviceControllerParameters *)parameters
error:(NSError * __autoreleasing *)error
{
[self _assertCurrentQueueIsNotMatterQueue];

return [self _startDeviceController:controller
startupParams:parameters
fabricChecker:^MTRDeviceControllerStartupParamsInternal *(
FabricTable * fabricTable, MTRDeviceController * controller, CHIP_ERROR & fabricError) {
auto advertiseOperational = self.advertiseOperational && parameters.shouldAdvertiseOperational;
auto * params =
[[MTRDeviceControllerStartupParamsInternal alloc] initForNewController:controller
fabricTable:fabricTable
keystore:self->_keystore
advertiseOperational:advertiseOperational
params:parameters
error:fabricError];
if (params != nil) {
if (params.productAttestationAuthorityCertificates == nil) {
params.productAttestationAuthorityCertificates = self.productAttestationAuthorityCertificates;
}
if (params.certificationDeclarationCertificates == nil) {
params.certificationDeclarationCertificates = self.certificationDeclarationCertificates;
}
}
return params;
}
error:error];
}

- (PersistentStorageDelegate *)storageDelegate
{
return _persistentStorageDelegate;
Expand Down Expand Up @@ -1173,7 +1188,7 @@ - (instancetype)initWithStorage:(id<MTRStorage>)storage
return self;
}

- (instancetype)init
- (instancetype)initWithoutStorage
{
if (!(self = [super init])) {
return nil;
Expand All @@ -1188,7 +1203,7 @@ - (instancetype)init
_productAttestationAuthorityCertificates = nil;
_certificationDeclarationCertificates = nil;
_port = nil;
_shouldStartServer = NO;
_shouldStartServer = YES;

return self;
}
Expand Down
18 changes: 18 additions & 0 deletions src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/

#import <Foundation/Foundation.h>
#import <Matter/MTRDeviceController.h>
#import <Matter/MTRDeviceControllerParameters.h>

#import "MTRDeviceControllerFactory.h"

Expand Down Expand Up @@ -67,9 +69,25 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)operationalInstanceAdded:(chip::PeerId &)operationalID;

/**
* Initialize an MTRDeviceController with the given parameters.
*/
- (nullable MTRDeviceController *)initializeController:(MTRDeviceController *)controller
withParameters:(MTRDeviceControllerParameters *)parameters
error:(NSError * __autoreleasing *)error;

@property (readonly) chip::PersistentStorageDelegate * storageDelegate;
@property (readonly) chip::Credentials::GroupDataProvider * groupData;

@end

@interface MTRDeviceControllerFactoryParams ()
/*
* Initialize the device controller factory without storage. In this mode,
* device controllers will need to have per-controller storage provided to allow
* storing controller-specific information.
*/
- (instancetype)initWithoutStorage;
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
NS_ASSUME_NONNULL_BEGIN

MTR_NEWLY_AVAILABLE
@interface MTRDeviceControllerStartupParameters : NSObject
@interface MTRDeviceControllerParameters : NSObject

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
Expand Down Expand Up @@ -69,7 +69,7 @@ MTR_NEWLY_AVAILABLE
@end

MTR_NEWLY_AVAILABLE
@interface MTRDeviceControllerExternalCertificateStartupParameters : MTRDeviceControllerStartupParameters
@interface MTRDeviceControllerExternalCertificateParameters : MTRDeviceControllerParameters

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
Expand Down
12 changes: 6 additions & 6 deletions src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,15 @@ - (instancetype)initWithParams:(MTRDeviceControllerStartupParams *)params
return self;
}

- (instancetype)initWithParameters:(MTRDeviceControllerStartupParameters *)params error:(CHIP_ERROR &)error
- (instancetype)initWithParameters:(MTRDeviceControllerParameters *)params error:(CHIP_ERROR &)error
{
if (!(self = [super init])) {
error = CHIP_ERROR_INCORRECT_STATE;
return nil;
}

if (![params isKindOfClass:[MTRDeviceControllerExternalCertificateStartupParameters class]]) {
MTR_LOG_ERROR("Unexpected subclass of MTRDeviceControllerStartupParameters");
if (![params isKindOfClass:[MTRDeviceControllerExternalCertificateParameters class]]) {
MTR_LOG_ERROR("Unexpected subclass of MTRDeviceControllerParameters");
error = CHIP_ERROR_INVALID_ARGUMENT;
return nil;
}
Expand Down Expand Up @@ -247,7 +247,7 @@ - (instancetype)initWithOperationalKeypair:(id<MTRKeypair>)operationalKeypair

@end

@implementation MTRDeviceControllerStartupParameters
@implementation MTRDeviceControllerParameters
- (instancetype)initWithStorageDelegate:(id<MTRDeviceControllerStorageDelegate>)storageDelegate
storageDelegateQueue:(dispatch_queue_t)storageDelegateQueue
uniqueIdentifier:(NSUUID *)uniqueIdentifier
Expand Down Expand Up @@ -297,7 +297,7 @@ - (void)setOTAProviderDelegate:(id<MTROTAProviderDelegate>)otaProviderDelegate q

@end

@implementation MTRDeviceControllerExternalCertificateStartupParameters
@implementation MTRDeviceControllerExternalCertificateParameters
- (instancetype)initWithStorageDelegate:(id<MTRDeviceControllerStorageDelegate>)storageDelegate
storageDelegateQueue:(dispatch_queue_t)storageDelegateQueue
uniqueIdentifier:(NSUUID *)uniqueIdentifier
Expand Down Expand Up @@ -538,7 +538,7 @@ - (instancetype)initForNewController:(MTRDeviceController *)controller
fabricTable:(chip::FabricTable *)fabricTable
keystore:(chip::Crypto::OperationalKeystore *)keystore
advertiseOperational:(BOOL)advertiseOperational
params:(MTRDeviceControllerStartupParameters *)params
params:(MTRDeviceControllerParameters *)params
error:(CHIP_ERROR &)error
{
if (!(self = [super initWithParameters:params error:error])) {
Expand Down
Loading

0 comments on commit f17493f

Please sign in to comment.