diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 83c6faeef7a337..aaf1289f184f98 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -88,26 +88,15 @@ // TODO: These strings and their consumers in this file should probably go away, // since none of them really apply to all controllers. -static NSString * const kErrorCommissionerInit = @"Init failure while initializing a commissioner"; -static NSString * const kErrorIPKInit = @"Init failure while initializing IPK"; -static NSString * const kErrorSigningKeypairInit = @"Init failure while creating signing keypair bridge"; -static NSString * const kErrorOperationalCredentialsInit = @"Init failure while creating operational credentials delegate"; -static NSString * const kErrorOperationalKeypairInit = @"Init failure while creating operational keypair bridge"; -static NSString * const kErrorPairingInit = @"Init failure while creating a pairing delegate"; -static NSString * const kErrorPartialDacVerifierInit = @"Init failure while creating a partial DAC verifier"; static NSString * const kErrorPairDevice = @"Failure while pairing the device"; static NSString * const kErrorStopPairing = @"Failure while trying to stop the pairing process"; static NSString * const kErrorOpenPairingWindow = @"Open Pairing Window failed"; static NSString * const kErrorNotRunning = @"Controller is not running. Call startup first."; static NSString * const kErrorSetupCodeGen = @"Generating Manual Pairing Code failed"; -static NSString * const kErrorGenerateNOC = @"Generating operational certificate failed"; -static NSString * const kErrorKeyAllocation = @"Generating new operational key failed"; -static NSString * const kErrorCSRValidation = @"Extracting public key from CSR failed"; static NSString * const kErrorGetCommissionee = @"Failure obtaining device being commissioned"; static NSString * const kErrorGetAttestationChallenge = @"Failure getting attestation challenge"; static NSString * const kErrorSpake2pVerifierGenerationFailed = @"PASE verifier generation failed"; static NSString * const kErrorSpake2pVerifierSerializationFailed = @"PASE verifier serialization failed"; -static NSString * const kErrorCDCertStoreInit = @"Init failure while initializing Certificate Declaration Signing Keys store"; typedef void (^SyncWorkQueueBlock)(void); typedef id (^SyncWorkQueueBlockWithReturnValue)(void); @@ -219,150 +208,6 @@ - (nullable MTRDeviceController *)initWithParameters:(MTRDeviceControllerAbstrac return nil; } -- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory - queue:(dispatch_queue_t)queue - storageDelegate:(id _Nullable)storageDelegate - storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue - otaProviderDelegate:(id _Nullable)otaProviderDelegate - otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue - uniqueIdentifier:(NSUUID *)uniqueIdentifier - concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize - storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration - startSuspended:(BOOL)startSuspended -{ - if (self = [super init]) { - // Make sure our storage is all set up to work as early as possible, - // before we start doing anything else with the controller. - _uniqueIdentifier = uniqueIdentifier; - - _suspended = startSuspended; - - if (storageDelegate != nil) { - if (storageDelegateQueue == nil) { - MTR_LOG_ERROR("storageDelegate provided without storageDelegateQueue"); - return nil; - } - - id storageDelegateToUse = storageDelegate; - if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { - storageDelegateToUse = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:storageDelegate]; - } - _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self - storageDelegate:storageDelegateToUse - storageDelegateQueue:storageDelegateQueue]; - if (_controllerDataStore == nil) { - return nil; - } - } else { - if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { - dispatch_queue_t localTestStorageQueue = dispatch_queue_create("org.csa-iot.matter.framework.devicecontroller.localteststorage", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - MTRDeviceControllerLocalTestStorage * localTestStorage = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:nil]; - _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self - storageDelegate:localTestStorage - storageDelegateQueue:localTestStorageQueue]; - if (_controllerDataStore == nil) { - return nil; - } - } - } - - // Ensure the otaProviderDelegate, if any, is valid. - if (otaProviderDelegate == nil && otaProviderDelegateQueue != nil) { - MTR_LOG_ERROR("Must have otaProviderDelegate when we have otaProviderDelegateQueue"); - return nil; - } - - if (otaProviderDelegate != nil && otaProviderDelegateQueue == nil) { - MTR_LOG_ERROR("Must have otaProviderDelegateQueue when we have otaProviderDelegate"); - return nil; - } - - if (otaProviderDelegate != nil) { - if (![otaProviderDelegate respondsToSelector:@selector(handleQueryImageForNodeID:controller:params:completion:)] - && ![otaProviderDelegate respondsToSelector:@selector(handleQueryImageForNodeID:controller:params:completionHandler:)]) { - MTR_LOG_ERROR("Error: MTROTAProviderDelegate does not support handleQueryImageForNodeID"); - return nil; - } - if (![otaProviderDelegate respondsToSelector:@selector(handleApplyUpdateRequestForNodeID:controller:params:completion:)] - && ![otaProviderDelegate respondsToSelector:@selector(handleApplyUpdateRequestForNodeID:controller:params:completionHandler:)]) { - MTR_LOG_ERROR("Error: MTROTAProviderDelegate does not support handleApplyUpdateRequestForNodeID"); - return nil; - } - if (![otaProviderDelegate respondsToSelector:@selector(handleNotifyUpdateAppliedForNodeID:controller:params:completion:)] - && ![otaProviderDelegate - respondsToSelector:@selector(handleNotifyUpdateAppliedForNodeID:controller:params:completionHandler:)]) { - MTR_LOG_ERROR("Error: MTROTAProviderDelegate does not support handleNotifyUpdateAppliedForNodeID"); - return nil; - } - if (![otaProviderDelegate respondsToSelector:@selector(handleBDXTransferSessionBeginForNodeID:controller:fileDesignator:offset:completion:)] - && ![otaProviderDelegate respondsToSelector:@selector(handleBDXTransferSessionBeginForNodeID:controller:fileDesignator:offset:completionHandler:)]) { - MTR_LOG_ERROR("Error: MTROTAProviderDelegate does not support handleBDXTransferSessionBeginForNodeID"); - return nil; - } - if (![otaProviderDelegate respondsToSelector:@selector(handleBDXQueryForNodeID:controller:blockSize:blockIndex:bytesToSkip:completion:)] - && ![otaProviderDelegate respondsToSelector:@selector(handleBDXQueryForNodeID:controller:blockSize:blockIndex:bytesToSkip:completionHandler:)]) { - MTR_LOG_ERROR("Error: MTROTAProviderDelegate does not support handleBDXQueryForNodeID"); - return nil; - } - } - - _otaProviderDelegate = otaProviderDelegate; - _otaProviderDelegateQueue = otaProviderDelegateQueue; - - _chipWorkQueue = queue; - _factory = factory; - _underlyingDeviceMapLock = OS_UNFAIR_LOCK_INIT; - _nodeIDToDeviceMap = [NSMapTable strongToWeakObjectsMapTable]; - _serverEndpoints = [[NSMutableArray alloc] init]; - _commissionableBrowser = nil; - - _deviceControllerDelegateBridge = new MTRDeviceControllerDelegateBridge(); - if ([self checkForInitError:(_deviceControllerDelegateBridge != nullptr) logMsg:kErrorPairingInit]) { - return nil; - } - - _partialDACVerifier = new chip::Credentials::PartialDACVerifier(); - if ([self checkForInitError:(_partialDACVerifier != nullptr) logMsg:kErrorPartialDacVerifierInit]) { - return nil; - } - - _operationalCredentialsDelegate = new MTROperationalCredentialsDelegate(self); - if ([self checkForInitError:(_operationalCredentialsDelegate != nullptr) logMsg:kErrorOperationalCredentialsInit]) { - return nil; - } - - // Provide a way to test different subscription pool sizes without code change - NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults objectForKey:kDefaultSubscriptionPoolSizeOverrideKey]) { - NSInteger subscriptionPoolSizeOverride = [defaults integerForKey:kDefaultSubscriptionPoolSizeOverrideKey]; - if (subscriptionPoolSizeOverride < 1) { - concurrentSubscriptionPoolSize = 1; - } else { - concurrentSubscriptionPoolSize = static_cast(subscriptionPoolSizeOverride); - } - - MTR_LOG(" *** Overriding pool size of MTRDeviceController with: %lu", static_cast(concurrentSubscriptionPoolSize)); - } - - if (!concurrentSubscriptionPoolSize) { - concurrentSubscriptionPoolSize = 1; - } - - MTR_LOG("%@ Setting up pool size of MTRDeviceController with: %lu", self, static_cast(concurrentSubscriptionPoolSize)); - - _concurrentSubscriptionPool = [[MTRAsyncWorkQueue alloc] initWithContext:self width:concurrentSubscriptionPoolSize]; - - _storedFabricIndex = chip::kUndefinedFabricIndex; - _storedCompressedFabricID = std::nullopt; - self.nodeID = nil; - self.fabricID = nil; - self.rootPublicKey = nil; - - _storageBehaviorConfiguration = storageBehaviorConfiguration; - } - return self; -} - - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, uuid: %@, suspended: %@>", NSStringFromClass(self.class), self, self.uniqueIdentifier, MTR_YES_NO(self.suspended)]; @@ -593,261 +438,6 @@ - (void)cleanup } } -- (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams -{ - __block BOOL commissionerInitialized = NO; - if ([self isRunning]) { - MTR_LOG_ERROR("%@ Unexpected duplicate call to startup", self); - return NO; - } - - dispatch_sync(_chipWorkQueue, ^{ - if ([self isRunning]) { - return; - } - - if (startupParams.vendorID == nil || [startupParams.vendorID unsignedShortValue] == chip::VendorId::Common) { - // Shouldn't be using the "standard" vendor ID for actual devices. - MTR_LOG_ERROR("%@ %@ is not a valid vendorID to initialize a device controller with", self, startupParams.vendorID); - return; - } - - if (startupParams.operationalCertificate == nil && startupParams.nodeID == nil) { - MTR_LOG_ERROR("%@ Can't start a controller if we don't know what node id it is", self); - return; - } - - if ([startupParams keypairsMatchCertificates] == NO) { - MTR_LOG_ERROR("%@ Provided keypairs do not match certificates", self); - return; - } - - if (startupParams.operationalCertificate != nil && startupParams.operationalKeypair == nil - && (!startupParams.fabricIndex.HasValue() - || !startupParams.keystore->HasOpKeypairForFabric(startupParams.fabricIndex.Value()))) { - MTR_LOG_ERROR("%@ Have no operational keypair for our operational certificate", self); - return; - } - - CHIP_ERROR errorCode = CHIP_ERROR_INCORRECT_STATE; - - // create a MTRP256KeypairBridge here and pass it to the operationalCredentialsDelegate - chip::Crypto::P256Keypair * signingKeypair = nullptr; - if (startupParams.nocSigner) { - errorCode = _signingKeypairBridge.Init(startupParams.nocSigner); - if ([self checkForStartError:errorCode logMsg:kErrorSigningKeypairInit]) { - return; - } - signingKeypair = &_signingKeypairBridge; - } - errorCode = _operationalCredentialsDelegate->Init( - signingKeypair, startupParams.ipk, startupParams.rootCertificate, startupParams.intermediateCertificate); - if ([self checkForStartError:errorCode logMsg:kErrorOperationalCredentialsInit]) { - return; - } - - _cppCommissioner = new chip::Controller::DeviceCommissioner(); - - // nocBuffer might not be used, but if it is it needs to live - // long enough (until after we are done using - // commissionerParams). - uint8_t nocBuffer[chip::Controller::kMaxCHIPDERCertLength]; - - chip::Controller::SetupParams commissionerParams; - - commissionerParams.pairingDelegate = _deviceControllerDelegateBridge; - - _operationalCredentialsDelegate->SetDeviceCommissioner(_cppCommissioner); - - commissionerParams.operationalCredentialsDelegate = _operationalCredentialsDelegate; - - commissionerParams.controllerRCAC = _operationalCredentialsDelegate->RootCertSpan(); - commissionerParams.controllerICAC = _operationalCredentialsDelegate->IntermediateCertSpan(); - - if (startupParams.operationalKeypair != nil) { - errorCode = _operationalKeypairBridge.Init(startupParams.operationalKeypair); - if ([self checkForStartError:errorCode logMsg:kErrorOperationalKeypairInit]) { - return; - } - commissionerParams.operationalKeypair = &_operationalKeypairBridge; - commissionerParams.hasExternallyOwnedOperationalKeypair = true; - } - - if (startupParams.operationalCertificate) { - commissionerParams.controllerNOC = AsByteSpan(startupParams.operationalCertificate); - } else { - chip::MutableByteSpan noc(nocBuffer); - - chip::CATValues cats = chip::kUndefinedCATs; - if (startupParams.caseAuthenticatedTags != nil) { - errorCode = SetToCATValues(startupParams.caseAuthenticatedTags, cats); - if (errorCode != CHIP_NO_ERROR) { - // SetToCATValues already handles logging. - return; - } - } - - if (commissionerParams.operationalKeypair != nullptr) { - errorCode = _operationalCredentialsDelegate->GenerateNOC(startupParams.nodeID.unsignedLongLongValue, - startupParams.fabricID.unsignedLongLongValue, cats, commissionerParams.operationalKeypair->Pubkey(), noc); - - if ([self checkForStartError:errorCode logMsg:kErrorGenerateNOC]) { - return; - } - } else { - // Generate a new random keypair. - uint8_t csrBuffer[chip::Crypto::kMIN_CSR_Buffer_Size]; - chip::MutableByteSpan csr(csrBuffer); - errorCode = startupParams.fabricTable->AllocatePendingOperationalKey(startupParams.fabricIndex, csr); - if ([self checkForStartError:errorCode logMsg:kErrorKeyAllocation]) { - return; - } - - chip::Crypto::P256PublicKey pubKey; - errorCode = VerifyCertificateSigningRequest(csr.data(), csr.size(), pubKey); - if ([self checkForStartError:errorCode logMsg:kErrorCSRValidation]) { - return; - } - - errorCode = _operationalCredentialsDelegate->GenerateNOC( - startupParams.nodeID.unsignedLongLongValue, startupParams.fabricID.unsignedLongLongValue, cats, pubKey, noc); - - if ([self checkForStartError:errorCode logMsg:kErrorGenerateNOC]) { - return; - } - } - commissionerParams.controllerNOC = noc; - } - commissionerParams.controllerVendorId = static_cast([startupParams.vendorID unsignedShortValue]); - commissionerParams.enableServerInteractions = startupParams.advertiseOperational; - - // We never want plain "removal" from the fabric table since this leaves - // the in-memory state out of sync with what's in storage. In per-controller - // storage mode, have the controller delete itself from the fabric table on shutdown. - // In factory storage mode we need to keep fabric information around so we can - // start another controller on that existing fabric at a later time. - commissionerParams.removeFromFabricTableOnShutdown = false; - commissionerParams.deleteFromFabricTableOnShutdown = (startupParams.storageDelegate != nil); - - commissionerParams.permitMultiControllerFabrics = startupParams.allowMultipleControllersPerFabric; - - // Set up our attestation verifier. Assume we want to use the default - // one, until something tells us otherwise. - const chip::Credentials::AttestationTrustStore * trustStore; - if (startupParams.productAttestationAuthorityCertificates) { - _attestationTrustStoreBridge - = new MTRAttestationTrustStoreBridge(startupParams.productAttestationAuthorityCertificates); - trustStore = _attestationTrustStoreBridge; - } else { - // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available - trustStore = chip::Credentials::GetTestAttestationTrustStore(); - } - - _defaultDACVerifier = new chip::Credentials::DefaultDACVerifier(trustStore); - - if (startupParams.certificationDeclarationCertificates) { - auto cdTrustStore = _defaultDACVerifier->GetCertificationDeclarationTrustStore(); - if (cdTrustStore == nullptr) { - errorCode = CHIP_ERROR_INCORRECT_STATE; - } - if ([self checkForStartError:errorCode logMsg:kErrorCDCertStoreInit]) { - return; - } - - for (NSData * cdSigningCert in startupParams.certificationDeclarationCertificates) { - errorCode = cdTrustStore->AddTrustedKey(AsByteSpan(cdSigningCert)); - if ([self checkForStartError:errorCode logMsg:kErrorCDCertStoreInit]) { - return; - } - } - } - - commissionerParams.deviceAttestationVerifier = _defaultDACVerifier; - - auto & factory = chip::Controller::DeviceControllerFactory::GetInstance(); - - errorCode = factory.SetupCommissioner(commissionerParams, *_cppCommissioner); - if ([self checkForStartError:errorCode logMsg:kErrorCommissionerInit]) { - return; - } - - chip::FabricIndex fabricIdx = _cppCommissioner->GetFabricIndex(); - - uint8_t compressedIdBuffer[sizeof(uint64_t)]; - chip::MutableByteSpan compressedId(compressedIdBuffer); - errorCode = _cppCommissioner->GetCompressedFabricIdBytes(compressedId); - if ([self checkForStartError:errorCode logMsg:kErrorIPKInit]) { - return; - } - - errorCode = chip::Credentials::SetSingleIpkEpochKey( - _factory.groupDataProvider, fabricIdx, _operationalCredentialsDelegate->GetIPK(), compressedId); - if ([self checkForStartError:errorCode logMsg:kErrorIPKInit]) { - return; - } - - self->_storedFabricIndex = fabricIdx; - self->_storedCompressedFabricID = _cppCommissioner->GetCompressedFabricId(); - - chip::Crypto::P256PublicKey rootPublicKey; - if (_cppCommissioner->GetRootPublicKey(rootPublicKey) == CHIP_NO_ERROR) { - self.rootPublicKey = [NSData dataWithBytes:rootPublicKey.Bytes() length:rootPublicKey.Length()]; - self.nodeID = @(_cppCommissioner->GetNodeId()); - self.fabricID = @(_cppCommissioner->GetFabricId()); - } - - commissionerInitialized = YES; - - MTR_LOG("%@ startup succeeded for nodeID 0x%016llX", self, self->_cppCommissioner->GetNodeId()); - }); - - if (commissionerInitialized == NO) { - MTR_LOG_ERROR("%@ startup failed", self); - [self cleanupAfterStartup]; - return NO; - } - - // TODO: Once setNocChainIssuer no longer needs to be supported, - // we can just move the internals of - // setOperationalCertificateIssuer into the sync-dispatched block - // above. - if (![self setOperationalCertificateIssuer:startupParams.operationalCertificateIssuer - queue:startupParams.operationalCertificateIssuerQueue]) { - MTR_LOG_ERROR("%@ operationalCertificateIssuer and operationalCertificateIssuerQueue must both be nil or both be non-nil", self); - [self cleanupAfterStartup]; - return NO; - } - - if (_controllerDataStore) { - // If the storage delegate supports the bulk read API, then a dictionary of nodeID => cluster data dictionary would be passed to the handler. Otherwise this would be a no-op, and stored attributes for MTRDevice objects will be loaded lazily in -deviceForNodeID:. - [_controllerDataStore fetchAttributeDataForAllDevices:^(NSDictionary *> * _Nonnull clusterDataByNode) { - MTR_LOG("%@ Loaded attribute values for %lu nodes from storage for controller uuid %@", self, static_cast(clusterDataByNode.count), self->_uniqueIdentifier); - - std::lock_guard lock(*self.deviceMapLock); - NSMutableArray * deviceList = [NSMutableArray array]; - for (NSNumber * nodeID in clusterDataByNode) { - NSDictionary * clusterData = clusterDataByNode[nodeID]; - MTRDevice * device = [self _setupDeviceForNodeID:nodeID prefetchedClusterData:clusterData]; - MTR_LOG("%@ Loaded %lu cluster data from storage for %@", self, static_cast(clusterData.count), device); - - [deviceList addObject:device]; - } - -#define kSecondsToWaitBeforeAPIClientRetainsMTRDevice 60 - // Keep the devices retained for a while, in case API client doesn't immediately retain them. - // - // Note that this is just an optimization to avoid throwing the information away and immediately - // re-reading it from storage. - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (kSecondsToWaitBeforeAPIClientRetainsMTRDevice * NSEC_PER_SEC)), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ - MTR_LOG("%@ un-retain devices loaded at startup %lu", self, static_cast(deviceList.count)); - }); - }]; - } - MTR_LOG("%@ startup: %@", NSStringFromClass(self.class), self); - - return YES; -} - - (NSNumber *)controllerNodeID { auto block = ^NSNumber * { return @(self->_cppCommissioner->GetNodeId()); }; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index c44b6e3bfb25dc..d052eef51d0414 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -461,7 +461,7 @@ - (void)stopControllerFactory * The provided controller is expected to have just been allocated and to not be * initialized yet. */ -- (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController *)controller +- (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController_Concrete *)controller startupParams:(id)startupParams fabricChecker:(MTRDeviceControllerStartupParamsInternal * (^)(FabricTable * fabricTable, MTRDeviceController * controller, @@ -834,7 +834,7 @@ - (BOOL)findMatchingFabric:(FabricTable &)fabricTable // Returns nil on failure, the input controller on success. // If the provider has been initialized already, it is not considered as a failure. // -- (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceController * _Nonnull)controller +- (MTRDeviceController_Concrete * _Nullable)maybeInitializeOTAProvider:(MTRDeviceController_Concrete * _Nonnull)controller { [self _assertCurrentQueueIsNotMatterQueue]; @@ -1156,7 +1156,7 @@ - (nullable MTRDeviceController *)_findPendingShutdownControllerWithOperationalC return nil; } -- (nullable MTRDeviceController *)initializeController:(MTRDeviceController *)controller +- (nullable MTRDeviceController *)initializeController:(MTRDeviceController_Concrete *)controller withParameters:(MTRDeviceControllerParameters *)parameters error:(NSError * __autoreleasing *)error { diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h index 7c59a65dba42c2..55c67ed8043c70 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h @@ -30,6 +30,7 @@ #import "MTRDefines_Internal.h" #import "MTRDeviceControllerFactory.h" +#import "MTRDeviceController_Concrete.h" #import "MTROperationalBrowser.h" #include @@ -89,9 +90,9 @@ MTR_DIRECT_MEMBERS completion:(void (^)(NSURL * _Nullable url, NSError * _Nullable error))completion; /** - * Initialize an MTRDeviceController with the given parameters. + * Initialize an MTRDeviceController_Concrete with the given parameters. */ -- (nullable MTRDeviceController *)initializeController:(MTRDeviceController *)controller +- (nullable MTRDeviceController *)initializeController:(MTRDeviceController_Concrete *)controller withParameters:(MTRDeviceControllerParameters *)parameters error:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h index 59dd42c04a97f4..615765fc84dae1 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h @@ -20,10 +20,40 @@ #import #import +#import "MTRDeviceControllerStartupParams_Internal.h" + NS_ASSUME_NONNULL_BEGIN @interface MTRDeviceController_Concrete : MTRDeviceController +/** + * Init a newly created controller. + * + * Only MTRDeviceControllerFactory should be calling this. + */ +- (nullable instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory + queue:(dispatch_queue_t)queue + storageDelegate:(id _Nullable)storageDelegate + storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue + otaProviderDelegate:(id _Nullable)otaProviderDelegate + otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue + uniqueIdentifier:(NSUUID *)uniqueIdentifier + concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration + startSuspended:(BOOL)startSuspended; + +/** + * Start a new controller. Returns whether startup succeeded. If this fails, + * it guarantees that it has called controllerShuttingDown on the + * MTRDeviceControllerFactory. + * + * The return value will always match [controller isRunning] for this + * controller. + * + * Only MTRDeviceControllerFactory should be calling this. + */ +- (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams; + /** * Takes an assertion to keep the controller running. If `-[MTRDeviceController shutdown]` is called while an assertion * is held, the shutdown will be honored only after all assertions are released. Invoking this method multiple times increases diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm index 8784b61d63cb88..0c768b2ece0671 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm @@ -163,16 +163,16 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete return controller; } -- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory - queue:(dispatch_queue_t)queue - storageDelegate:(id _Nullable)storageDelegate - storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue - otaProviderDelegate:(id _Nullable)otaProviderDelegate - otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue - uniqueIdentifier:(NSUUID *)uniqueIdentifier - concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize - storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration - startSuspended:(BOOL)startSuspended +- (nullable instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory + queue:(dispatch_queue_t)queue + storageDelegate:(id _Nullable)storageDelegate + storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue + otaProviderDelegate:(id _Nullable)otaProviderDelegate + otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue + uniqueIdentifier:(NSUUID *)uniqueIdentifier + concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration + startSuspended:(BOOL)startSuspended { if (self = [super initForSubclasses:startSuspended]) { // Make sure our storage is all set up to work as early as possible, diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h index 8eb21aef64eb9e..d57a6e88a48d09 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h @@ -40,13 +40,11 @@ #import #import -#import #import #import #import @class MTRDeviceControllerParameters; -@class MTRDeviceControllerStartupParamsInternal; @class MTRDeviceControllerFactory; @class MTRDevice; @class MTRAsyncWorkQueue; @@ -79,18 +77,6 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - MTRDeviceControllerFactory methods -/** - * Start a new controller. Returns whether startup succeeded. If this fails, - * it guarantees that it has called controllerShuttingDown on the - * MTRDeviceControllerFactory. - * - * The return value will always match [controller isRunning] for this - * controller. - * - * Only MTRDeviceControllerFactory should be calling this. - */ -- (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams; - /** * Will return chip::kUndefinedFabricIndex if we do not have a fabric index. */ @@ -135,22 +121,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, retain, nullable) NSData * rootPublicKey; -/** - * Init a newly created controller. - * - * Only MTRDeviceControllerFactory should be calling this. - */ -- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory - queue:(dispatch_queue_t)queue - storageDelegate:(id _Nullable)storageDelegate - storageDelegateQueue:(dispatch_queue_t _Nullable)storageDelegateQueue - otaProviderDelegate:(id _Nullable)otaProviderDelegate - otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue - uniqueIdentifier:(NSUUID *)uniqueIdentifier - concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize - storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration - startSuspended:(BOOL)startSuspended; - /** * Check whether this controller is running on the given fabric, as represented * by the provided FabricTable and fabric index. The provided fabric table may