From 78ce5b0ad922ffb12b9c91cca282eb1a6613f88d Mon Sep 17 00:00:00 2001 From: Kiel Oleson Date: Thu, 15 Aug 2024 08:04:12 -0700 Subject: [PATCH] [Darwin] Duplicate / begin raising `MTRDeviceController` (#34832) * Keep MTRDeviceController.mm * Copy MTRDeviceController.mm into MTRDeviceController_Concrete.mm * Set back MTRDeviceController.mm file * Keep MTRDeviceController.h * Copy MTRDeviceController.h into MTRDeviceController_Concrete.h * Set back MTRDeviceController.h file * add `MTRDeviceController_Concrete` files * WIP: bring up `MTRDeviceController_Concrete` * temporary init implementation * only vend `MTRDeviceController` pointers not concrete class (`instancetype`) pointers * add `storedFabricIndex` (currently broken) * reduce access of internal properties * move C++-style fabric index and keypairs to protected ivars * return base class pointer from constructors rather than `instancetype` * clean up property synthesis/ivars in concrete * update merged code * WIP: get us building again, plus plan comments * remove superfluous comments * Update src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h * Restyled by clang-format * move MTRDeviceController protected ivars to standard `MTRDeviceController.h` header * `MTRDeviceController_Concrete` isn't public API thus no `MTR_AVAILABLE` * remove commented code * move ivar extension back to internal header * Fixing TAPI * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Justin Wood Co-authored-by: Restyled.io --- .../Framework/CHIP/MTRDeviceController.h | 4 +- .../Framework/CHIP/MTRDeviceController.mm | 30 +- .../CHIP/MTRDeviceControllerFactory.h | 2 +- .../CHIP/MTRDeviceControllerFactory.mm | 6 +- .../CHIP/MTRDeviceController_Concrete.h | 17 +- .../CHIP/MTRDeviceController_Concrete.mm | 292 +++++++----------- .../CHIP/MTRDeviceController_Internal.h | 38 +++ .../Matter.xcodeproj/project.pbxproj | 8 + 8 files changed, 176 insertions(+), 221 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.h b/src/darwin/Framework/CHIP/MTRDeviceController.h index eaae1fcf7d4c6a..9e2c833f6ef93b 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController.h @@ -57,8 +57,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Once this returns non-nil, it's the caller's responsibility to call shutdown * on the controller to avoid leaking it. */ -- (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters - error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); +- (nullable MTRDeviceController *)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters + error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); /** * If true, the controller has not been shut down yet. diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 25a0e7d4dcd4c1..ee8cc2b7549190 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -108,10 +108,6 @@ using namespace chip::Tracing::DarwinFramework; @implementation MTRDeviceController { - // Atomic because they can be touched from multiple threads. - std::atomic _storedFabricIndex; - std::atomic> _storedCompressedFabricID; - // queue used to serialize all work performed by the MTRDeviceController dispatch_queue_t _chipWorkQueue; @@ -120,8 +116,6 @@ @implementation MTRDeviceController { chip::Credentials::DefaultDACVerifier * _defaultDACVerifier; MTRDeviceControllerDelegateBridge * _deviceControllerDelegateBridge; MTROperationalCredentialsDelegate * _operationalCredentialsDelegate; - MTRP256KeypairBridge _signingKeypairBridge; - MTRP256KeypairBridge _operationalKeypairBridge; MTRDeviceAttestationDelegateBridge * _deviceAttestationDelegateBridge; MTRDeviceControllerFactory * _factory; NSMapTable * _nodeIDToDeviceMap; @@ -133,9 +127,22 @@ @implementation MTRDeviceController { NSMutableArray * _serverEndpoints; MTRDeviceStorageBehaviorConfiguration * _storageBehaviorConfiguration; + std::atomic _storedFabricIndex; + std::atomic> _storedCompressedFabricID; + MTRP256KeypairBridge _signingKeypairBridge; + MTRP256KeypairBridge _operationalKeypairBridge; +} + +- (instancetype)initForSubclasses +{ + if (self = [super init]) { + // nothing, as superclass of MTRDeviceController is NSObject + } + + return self; } -- (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error +- (nullable MTRDeviceController *)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error { if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) { MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters); @@ -1575,15 +1582,6 @@ + (void)forceLocalhostAdvertisingOnly @end -/** - * Shim to allow us to treat an MTRDevicePairingDelegate as an - * MTRDeviceControllerDelegate. - */ -@interface MTRDevicePairingDelegateShim : NSObject -@property (nonatomic, readonly) id delegate; -- (instancetype)initWithDelegate:(id)delegate; -@end - @implementation MTRDevicePairingDelegateShim - (instancetype)initWithDelegate:(id)delegate { diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h index 0f9de90363f821..5d1fc4c1809874 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h @@ -23,6 +23,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -31,7 +32,6 @@ NS_ASSUME_NONNULL_BEGIN @protocol MTROTAProviderDelegate; @protocol MTRKeypair; -@class MTRDeviceController; @class MTRDeviceControllerStartupParams; @class MTRFabricInfo; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 18128249376e21..5b089b392074e6 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -1133,9 +1133,9 @@ - (void)operationalInstanceAdded:(chip::PeerId &)operationalID } } -- (MTRDeviceController * _Nullable)initializeController:(MTRDeviceController *)controller - withParameters:(MTRDeviceControllerParameters *)parameters - error:(NSError * __autoreleasing *)error +- (nullable MTRDeviceController *)initializeController:(MTRDeviceController *)controller + withParameters:(MTRDeviceControllerParameters *)parameters + error:(NSError * __autoreleasing *)error { [self _assertCurrentQueueIsNotMatterQueue]; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h index eaae1fcf7d4c6a..c9587e910d3b1a 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h @@ -19,6 +19,7 @@ #import #import +#import #import @class MTRBaseDevice; @@ -37,15 +38,7 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS @protocol MTRDevicePairingDelegate; @protocol MTRDeviceControllerDelegate; -MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) -@interface MTRDeviceController : NSObject - -/** - * Controllers are created via the MTRDeviceControllerFactory object or - * initialized via initWithParameters:error:. - */ -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; +@interface MTRDeviceController_Concrete : MTRDeviceController /** * Initialize a device controller with the provided parameters. This will: @@ -57,8 +50,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Once this returns non-nil, it's the caller's responsibility to call shutdown * on the controller to avoid leaking it. */ -- (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters - error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); +- (nullable MTRDeviceController *)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters + error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); /** * If true, the controller has not been shut down yet. @@ -262,7 +255,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @end -@interface MTRDeviceController (Deprecated) +@interface MTRDeviceController_Concrete (Deprecated) @property (readonly, nonatomic, nullable) NSNumber * controllerNodeId MTR_DEPRECATED( "Please use controllerNodeID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm index 6c312d510a93a7..c7ccab25e1cdc4 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm @@ -26,11 +26,13 @@ #import "MTRCommissionableBrowserResult_Internal.h" #import "MTRCommissioningParameters.h" #import "MTRConversion.h" +#import "MTRDeviceController.h" #import "MTRDeviceControllerDelegateBridge.h" #import "MTRDeviceControllerFactory_Internal.h" #import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" +#import "MTRDeviceController_Concrete.h" #import "MTRDevice_Concrete.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" @@ -79,61 +81,81 @@ #import -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); typedef BOOL (^SyncWorkQueueBlockWithBoolReturnValue)(void); using namespace chip::Tracing::DarwinFramework; -@implementation MTRDeviceController { - // Atomic because it can be touched from multiple threads. - std::atomic _storedFabricIndex; +@interface MTRDeviceController_Concrete () - // queue used to serialize all work performed by the MTRDeviceController - dispatch_queue_t _chipWorkQueue; +// MTRDeviceController ivar internal access + +@property (nonatomic, readonly) chip::Controller::DeviceCommissioner * cppCommissioner; +@property (nonatomic, readonly) chip::Credentials::PartialDACVerifier * partialDACVerifier; +@property (nonatomic, readonly) chip::Credentials::DefaultDACVerifier * defaultDACVerifier; +@property (nonatomic, readonly) MTRDeviceControllerDelegateBridge * deviceControllerDelegateBridge; +@property (nonatomic, readonly) MTROperationalCredentialsDelegate * operationalCredentialsDelegate; +@property (nonatomic, readonly) MTRDeviceAttestationDelegateBridge * deviceAttestationDelegateBridge; +@property (nonatomic, readwrite) NSUUID * uniqueIdentifier; +@property (nonatomic, readonly) dispatch_queue_t chipWorkQueue; +@property (nonatomic, readonly, nullable) MTRDeviceControllerFactory * factory; +@property (nonatomic, readonly, nullable) NSMapTable * nodeIDToDeviceMap; +@property (nonatomic, readonly) os_unfair_lock deviceMapLock; +@property (nonatomic, readonly, nullable) id otaProviderDelegate; +@property (nonatomic, readonly, nullable) dispatch_queue_t otaProviderDelegateQueue; +@property (nonatomic, readonly, nullable) MTRCommissionableBrowser * commissionableBrowser; +@property (nonatomic, readonly, nullable) MTRAttestationTrustStoreBridge * attestationTrustStoreBridge; +@property (nonatomic, readonly, nullable) NSMutableArray * serverEndpoints; + +@property (nonatomic, readonly) MTRAsyncWorkQueue * concurrentSubscriptionPool; - chip::Controller::DeviceCommissioner * _cppCommissioner; - chip::Credentials::PartialDACVerifier * _partialDACVerifier; - chip::Credentials::DefaultDACVerifier * _defaultDACVerifier; - MTRDeviceControllerDelegateBridge * _deviceControllerDelegateBridge; - MTROperationalCredentialsDelegate * _operationalCredentialsDelegate; +@property (nonatomic, readonly) MTRDeviceStorageBehaviorConfiguration * storageBehaviorConfiguration; + +@end + +@implementation MTRDeviceController_Concrete { + // queue used to serialize all work performed by the MTRDeviceController + std::atomic _storedFabricIndex; + std::atomic> _storedCompressedFabricID; MTRP256KeypairBridge _signingKeypairBridge; MTRP256KeypairBridge _operationalKeypairBridge; - MTRDeviceAttestationDelegateBridge * _deviceAttestationDelegateBridge; - MTRDeviceControllerFactory * _factory; - NSMapTable * _nodeIDToDeviceMap; - os_unfair_lock _deviceMapLock; // protects nodeIDToDeviceMap - MTRCommissionableBrowser * _commissionableBrowser; - MTRAttestationTrustStoreBridge * _attestationTrustStoreBridge; +} - // _serverEndpoints is only touched on the Matter queue. - NSMutableArray * _serverEndpoints; +// MTRDeviceController ivar internal access +@synthesize uniqueIdentifier = _uniqueIdentifier; +@synthesize chipWorkQueue = _chipWorkQueue; +@synthesize controllerDataStore = _controllerDataStore; +@synthesize factory = _factory; +@synthesize deviceMapLock = _deviceMapLock; +@synthesize otaProviderDelegate = _otaProviderDelegate; +@synthesize otaProviderDelegateQueue = _otaProviderDelegateQueue; +@synthesize commissionableBrowser = _commissionableBrowser; +@synthesize concurrentSubscriptionPool = _concurrentSubscriptionPool; +@synthesize storageBehaviorConfiguration = _storageBehaviorConfiguration; + +- (nullable MTRDeviceController_Concrete *)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters + error:(NSError * __autoreleasing *)error +{ + if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) { + MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters); + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]; + } + return nil; + } + auto * controllerParameters = static_cast(parameters); - MTRDeviceStorageBehaviorConfiguration * _storageBehaviorConfiguration; + // or, if necessary, MTRDeviceControllerFactory will auto-start in per-controller-storage mode if necessary + MTRDeviceControllerFactory * factory = MTRDeviceControllerFactory.sharedInstance; + id controller = [factory initializeController:self + withParameters:controllerParameters + error:error]; + return controller; } -- (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error +- (nullable MTRDeviceController *)bogusWithParameters:(MTRDeviceControllerAbstractParameters *)parameters + error:(NSError * __autoreleasing *)error { if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) { MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters); @@ -145,7 +167,11 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete auto * controllerParameters = static_cast(parameters); // MTRDeviceControllerFactory will auto-start in per-controller-storage mode if necessary - return [MTRDeviceControllerFactory.sharedInstance initializeController:self withParameters:controllerParameters error:error]; + MTRDeviceControllerFactory * factory = MTRDeviceControllerFactory.sharedInstance; + MTRDeviceController * controller = [factory initializeController:self + withParameters:controllerParameters + error:error]; + return controller; } - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory @@ -158,7 +184,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration { - if (self = [super init]) { + if (self = [super initForSubclasses]) { // 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; @@ -242,17 +268,17 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory _commissionableBrowser = nil; _deviceControllerDelegateBridge = new MTRDeviceControllerDelegateBridge(); - if ([self checkForInitError:(_deviceControllerDelegateBridge != nullptr) logMsg:kErrorPairingInit]) { + if ([self checkForInitError:(_deviceControllerDelegateBridge != nullptr) logMsg:kDeviceControllerErrorPairingInit]) { return nil; } _partialDACVerifier = new chip::Credentials::PartialDACVerifier(); - if ([self checkForInitError:(_partialDACVerifier != nullptr) logMsg:kErrorPartialDacVerifierInit]) { + if ([self checkForInitError:(_partialDACVerifier != nullptr) logMsg:kDeviceControllerErrorPartialDacVerifierInit]) { return nil; } _operationalCredentialsDelegate = new MTROperationalCredentialsDelegate(self); - if ([self checkForInitError:(_operationalCredentialsDelegate != nullptr) logMsg:kErrorOperationalCredentialsInit]) { + if ([self checkForInitError:(_operationalCredentialsDelegate != nullptr) logMsg:kDeviceControllerErrorOperationalCredentialsInit]) { return nil; } @@ -438,14 +464,14 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams chip::Crypto::P256Keypair * signingKeypair = nullptr; if (startupParams.nocSigner) { errorCode = _signingKeypairBridge.Init(startupParams.nocSigner); - if ([self checkForStartError:errorCode logMsg:kErrorSigningKeypairInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorSigningKeypairInit]) { return; } signingKeypair = &_signingKeypairBridge; } errorCode = _operationalCredentialsDelegate->Init( signingKeypair, startupParams.ipk, startupParams.rootCertificate, startupParams.intermediateCertificate); - if ([self checkForStartError:errorCode logMsg:kErrorOperationalCredentialsInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorOperationalCredentialsInit]) { return; } @@ -469,7 +495,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (startupParams.operationalKeypair != nil) { errorCode = _operationalKeypairBridge.Init(startupParams.operationalKeypair); - if ([self checkForStartError:errorCode logMsg:kErrorOperationalKeypairInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorOperationalKeypairInit]) { return; } commissionerParams.operationalKeypair = &_operationalKeypairBridge; @@ -494,7 +520,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams errorCode = _operationalCredentialsDelegate->GenerateNOC(startupParams.nodeID.unsignedLongLongValue, startupParams.fabricID.unsignedLongLongValue, cats, commissionerParams.operationalKeypair->Pubkey(), noc); - if ([self checkForStartError:errorCode logMsg:kErrorGenerateNOC]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorGenerateNOC]) { return; } } else { @@ -502,20 +528,20 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams 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]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorKeyAllocation]) { return; } chip::Crypto::P256PublicKey pubKey; errorCode = VerifyCertificateSigningRequest(csr.data(), csr.size(), pubKey); - if ([self checkForStartError:errorCode logMsg:kErrorCSRValidation]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorCSRValidation]) { return; } errorCode = _operationalCredentialsDelegate->GenerateNOC( startupParams.nodeID.unsignedLongLongValue, startupParams.fabricID.unsignedLongLongValue, cats, pubKey, noc); - if ([self checkForStartError:errorCode logMsg:kErrorGenerateNOC]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorGenerateNOC]) { return; } } @@ -553,13 +579,13 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (cdTrustStore == nullptr) { errorCode = CHIP_ERROR_INCORRECT_STATE; } - if ([self checkForStartError:errorCode logMsg:kErrorCDCertStoreInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorCDCertStoreInit]) { return; } for (NSData * cdSigningCert in startupParams.certificationDeclarationCertificates) { errorCode = cdTrustStore->AddTrustedKey(AsByteSpan(cdSigningCert)); - if ([self checkForStartError:errorCode logMsg:kErrorCDCertStoreInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorCDCertStoreInit]) { return; } } @@ -570,7 +596,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams auto & factory = chip::Controller::DeviceControllerFactory::GetInstance(); errorCode = factory.SetupCommissioner(commissionerParams, *_cppCommissioner); - if ([self checkForStartError:errorCode logMsg:kErrorCommissionerInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorCommissionerInit]) { return; } @@ -579,13 +605,13 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams uint8_t compressedIdBuffer[sizeof(uint64_t)]; chip::MutableByteSpan compressedId(compressedIdBuffer); errorCode = _cppCommissioner->GetCompressedFabricIdBytes(compressedId); - if ([self checkForStartError:errorCode logMsg:kErrorIPKInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorIPKInit]) { return; } errorCode = chip::Credentials::SetSingleIpkEpochKey( _factory.groupDataProvider, fabricIdx, _operationalCredentialsDelegate->GetIPK(), compressedId); - if ([self checkForStartError:errorCode logMsg:kErrorIPKInit]) { + if ([self checkForStartError:errorCode logMsg:kDeviceControllerErrorIPKInit]) { return; } @@ -688,7 +714,7 @@ - (BOOL)setupCommissioningSessionWithPayload:(MTRSetupPayload *)payload } if (pairingCode == nil) { errorCode = CHIP_ERROR_INVALID_ARGUMENT; - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorSetupCodeGen error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorSetupCodeGen error:error]; } chip::NodeId nodeId = [newNodeID unsignedLongLongValue]; @@ -702,7 +728,7 @@ - (BOOL)setupCommissioningSessionWithPayload:(MTRSetupPayload *)payload MATTER_LOG_METRIC_END(kMetricSetupPASESession, errorCode); } - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; auto success = [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -758,7 +784,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR } if (pairingCode == nil) { errorCode = CHIP_ERROR_INVALID_ARGUMENT; - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorSetupCodeGen error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorSetupCodeGen error:error]; } for (id key in discoveredDevice.interfaces) { @@ -779,7 +805,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR } } - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; auto success = [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -886,7 +912,7 @@ - (BOOL)commissionNodeWithID:(NSNumber *)nodeID self->_operationalCredentialsDelegate->SetDeviceID(deviceId); auto errorCode = self->_cppCommissioner->Commission(deviceId, params); MATTER_LOG_METRIC(kMetricCommissionNode, errorCode); - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; return [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -906,7 +932,7 @@ - (BOOL)continueCommissioningDevice:(void *)device ignoreAttestationFailure ? chip::Credentials::AttestationVerificationResult::kSuccess : lastAttestationResult); // Emit metric on stage after continuing post attestation MATTER_LOG_METRIC(kMetricContinueCommissioningAfterAttestation, errorCode); - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; return [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -919,7 +945,7 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor auto errorCode = self->_cppCommissioner->StopPairing([nodeID unsignedLongLongValue]); // Emit metric on status of cancel MATTER_LOG_METRIC(kMetricCancelCommissioning, errorCode); - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorStopPairing error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorStopPairing error:error]; }; return [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -969,7 +995,7 @@ - (MTRBaseDevice *)deviceBeingCommissionedWithNodeID:(NSNumber *)nodeID error:(N auto errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned(nodeID.unsignedLongLongValue, &deviceProxy); MATTER_LOG_METRIC(kMetricDeviceBeingCommissioned, errorCode); - VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:error], nil); + VerifyOrReturnValue(![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorGetCommissionee error:error], nil); return [[MTRBaseDevice alloc] initWithPASEDevice:deviceProxy controller:self]; }; @@ -989,7 +1015,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N { os_unfair_lock_assert_owner(&_deviceMapLock); - MTRDevice * deviceToReturn = [[MTRDevice_Concrete alloc] initWithNodeID:nodeID controller:self]; + MTRDevice * deviceToReturn = [[MTRDevice alloc] initWithNodeID:nodeID controller:self]; // If we're not running, don't add the device to our map. That would // create a cycle that nothing would break. Just return the device, // which will be in exactly the state it would be in if it were created @@ -1105,14 +1131,14 @@ + (nullable NSData *)computePASEVerifierForSetupPasscode:(NSNumber *)setupPassco MATTER_LOG_METRIC_SCOPE(kMetricPASEVerifierForSetupCode, err); - if ([MTRDeviceController checkForError:err logMsg:kErrorSpake2pVerifierGenerationFailed error:error]) { + if ([MTRDeviceController_Concrete checkForError:err logMsg:kDeviceControllerErrorSpake2pVerifierGenerationFailed error:error]) { return nil; } uint8_t serializedBuffer[chip::Crypto::kSpake2p_VerifierSerialized_Length]; chip::MutableByteSpan serializedBytes(serializedBuffer); err = verifier.Serialize(serializedBytes); - if ([MTRDeviceController checkForError:err logMsg:kErrorSpake2pVerifierSerializationFailed error:error]) { + if ([MTRDeviceController_Concrete checkForError:err logMsg:kDeviceControllerErrorSpake2pVerifierSerializationFailed error:error]) { return nil; } @@ -1129,13 +1155,13 @@ - (NSData * _Nullable)attestationChallengeForDeviceID:(NSNumber *)deviceID MATTER_LOG_METRIC_SCOPE(kMetricAttestationChallengeForDevice, errorCode); errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); - VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:nil], nil); + VerifyOrReturnValue(![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorGetCommissionee error:nil], nil); uint8_t challengeBuffer[chip::Crypto::kAES_CCM128_Key_Length]; chip::ByteSpan challenge(challengeBuffer); errorCode = deviceProxy->GetAttestationChallenge(challenge); - VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetAttestationChallenge error:nil], nil); + VerifyOrReturnValue(![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorGetAttestationChallenge error:nil], nil); return AsData(challenge); }; @@ -1272,7 +1298,7 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error return YES; } - MTR_LOG_ERROR("MTRDeviceController: %@ Error: %s", self, [kErrorNotRunning UTF8String]); + MTR_LOG_ERROR("MTRDeviceController: %@ Error: %s", self, [kDeviceControllerErrorNotRunning UTF8String]); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; } @@ -1582,63 +1608,6 @@ + (void)forceLocalhostAdvertisingOnly @end -/** - * Shim to allow us to treat an MTRDevicePairingDelegate as an - * MTRDeviceControllerDelegate. - */ -@interface MTRDevicePairingDelegateShim : NSObject -@property (nonatomic, readonly) id delegate; -- (instancetype)initWithDelegate:(id)delegate; -@end - -@implementation MTRDevicePairingDelegateShim -- (instancetype)initWithDelegate:(id)delegate -{ - if (self = [super init]) { - _delegate = delegate; - } - return self; -} - -- (BOOL)respondsToSelector:(SEL)selector -{ - if (selector == @selector(controller:statusUpdate:)) { - return [self.delegate respondsToSelector:@selector(onStatusUpdate:)]; - } - - if (selector == @selector(controller:commissioningSessionEstablishmentDone:)) { - return [self.delegate respondsToSelector:@selector(onPairingComplete:)]; - } - - if (selector == @selector(controller:commissioningComplete:)) { - return [self.delegate respondsToSelector:@selector(onCommissioningComplete:)]; - } - - return [super respondsToSelector:selector]; -} - -- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status -{ - [self.delegate onStatusUpdate:static_cast(status)]; -} - -- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error -{ - [self.delegate onPairingComplete:error]; -} - -- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error -{ - [self.delegate onCommissioningComplete:error]; -} - -- (void)onPairingDeleted:(NSError * _Nullable)error -{ - [self.delegate onPairingDeleted:error]; -} - -@end - /** * Shim to allow us to treat an MTRNOCChainIssuer as an * MTROperationalCertificateIssuer. @@ -1649,58 +1618,7 @@ @interface MTROperationalCertificateChainIssuerShim : NSObject )nocChainIssuer; @end -@implementation MTROperationalCertificateChainIssuerShim -- (instancetype)initWithIssuer:(id)nocChainIssuer -{ - if (self = [super init]) { - _nocChainIssuer = nocChainIssuer; - _shouldSkipAttestationCertificateValidation = YES; - } - return self; -} - -- (void)issueOperationalCertificateForRequest:(MTROperationalCSRInfo *)csrInfo - attestationInfo:(MTRDeviceAttestationInfo *)attestationInfo - controller:(MTRDeviceController *)controller - completion:(void (^)(MTROperationalCertificateChain * _Nullable info, - NSError * _Nullable error))completion -{ - CSRInfo * oldCSRInfo = [[CSRInfo alloc] initWithNonce:csrInfo.csrNonce - elements:csrInfo.csrElementsTLV - elementsSignature:csrInfo.attestationSignature - csr:csrInfo.csr]; - NSData * _Nullable firmwareInfo = attestationInfo.firmwareInfo; - if (firmwareInfo == nil) { - firmwareInfo = [NSData data]; - } - AttestationInfo * oldAttestationInfo = - [[AttestationInfo alloc] initWithChallenge:attestationInfo.challenge - nonce:attestationInfo.nonce - elements:attestationInfo.elementsTLV - elementsSignature:attestationInfo.elementsSignature - dac:attestationInfo.deviceAttestationCertificate - pai:attestationInfo.productAttestationIntermediateCertificate - certificationDeclaration:attestationInfo.certificationDeclaration - firmwareInfo:firmwareInfo]; - [self.nocChainIssuer - onNOCChainGenerationNeeded:oldCSRInfo - attestationInfo:oldAttestationInfo - onNOCChainGenerationComplete:^(NSData * operationalCertificate, NSData * intermediateCertificate, NSData * rootCertificate, - NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, NSError * __autoreleasing * error) { - auto * chain = [[MTROperationalCertificateChain alloc] initWithOperationalCertificate:operationalCertificate - intermediateCertificate:intermediateCertificate - rootCertificate:rootCertificate - adminSubject:adminSubject]; - completion(chain, nil); - if (error != nil) { - *error = nil; - } - }]; -} - -@end - -@implementation MTRDeviceController (Deprecated) +@implementation MTRDeviceController_Concrete (Deprecated) - (NSNumber *)controllerNodeId { @@ -1768,7 +1686,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID payload.setUpPINCode = setupPINCode; errorCode = chip::ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(manualPairingCode); - VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorSetupCodeGen error:error], NO); + VerifyOrReturnValue(![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorSetupCodeGen error:error], NO); self->_operationalCredentialsDelegate->SetDeviceID(deviceID); @@ -1780,7 +1698,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID MATTER_LOG_METRIC_END(kMetricSetupPASESession, errorCode); } - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; auto success = [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -1825,7 +1743,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID MATTER_LOG_METRIC_END(kMetricSetupPASESession, errorCode); } - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; auto success = [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -1861,7 +1779,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID onboardingPayload:(NSString *)onboardingPa MATTER_LOG_METRIC_END(kMetricSetupPASESession, errorCode); } - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorPairDevice error:error]; }; auto success = [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -1904,7 +1822,7 @@ - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow( self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); - return ![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error]; + return ![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorOpenPairingWindow error:error]; }; return [self syncRunOnWorkQueueWithBoolReturnValue:block error:error]; @@ -1952,7 +1870,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID static_cast(discriminator), chip::MakeOptional(static_cast(setupPIN)), chip::NullOptional, setupPayload); - VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error], nil); + VerifyOrReturnValue(![MTRDeviceController_Concrete checkForError:errorCode logMsg:kDeviceControllerErrorOpenPairingWindow error:error], nil); chip::ManualSetupPayloadGenerator generator(setupPayload); std::string outCode; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h index 479dd8518d069f..d943775d43475d 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h @@ -32,8 +32,11 @@ #import "MTRBaseDevice.h" #import "MTRDeviceController.h" #import "MTRDeviceControllerDataStore.h" +#import "MTRDeviceControllerDelegate.h" #import "MTRDeviceStorageBehaviorConfiguration.h" +#import + #import #import #import @@ -44,6 +47,9 @@ @class MTRDeviceControllerFactory; @class MTRDevice; @class MTRAsyncWorkQueue; +@protocol MTRDevicePairingDelegate; +@protocol MTRDeviceControllerDelegate; +@class MTRDevice_Concrete; namespace chip { class FabricTable; @@ -57,6 +63,8 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDeviceController () +- (instancetype)initForSubclasses; + #pragma mark - MTRDeviceControllerFactory methods /** @@ -273,4 +281,34 @@ NS_ASSUME_NONNULL_BEGIN @end +/** + * Shim to allow us to treat an MTRDevicePairingDelegate as an + * MTRDeviceControllerDelegate. + */ +@interface MTRDevicePairingDelegateShim : NSObject +@property (nonatomic, readonly) id delegate; +- (instancetype)initWithDelegate:(id)delegate; +@end + +static NSString * const kDeviceControllerErrorCommissionerInit = @"Init failure while initializing a commissioner"; +static NSString * const kDeviceControllerErrorIPKInit = @"Init failure while initializing IPK"; +static NSString * const kDeviceControllerErrorSigningKeypairInit = @"Init failure while creating signing keypair bridge"; +static NSString * const kDeviceControllerErrorOperationalCredentialsInit = @"Init failure while creating operational credentials delegate"; +static NSString * const kDeviceControllerErrorOperationalKeypairInit = @"Init failure while creating operational keypair bridge"; +static NSString * const kDeviceControllerErrorPairingInit = @"Init failure while creating a pairing delegate"; +static NSString * const kDeviceControllerErrorPartialDacVerifierInit = @"Init failure while creating a partial DAC verifier"; +static NSString * const kDeviceControllerErrorPairDevice = @"Failure while pairing the device"; +static NSString * const kDeviceControllerErrorStopPairing = @"Failure while trying to stop the pairing process"; +static NSString * const kDeviceControllerErrorOpenPairingWindow = @"Open Pairing Window failed"; +static NSString * const kDeviceControllerErrorNotRunning = @"Controller is not running. Call startup first."; +static NSString * const kDeviceControllerErrorSetupCodeGen = @"Generating Manual Pairing Code failed"; +static NSString * const kDeviceControllerErrorGenerateNOC = @"Generating operational certificate failed"; +static NSString * const kDeviceControllerErrorKeyAllocation = @"Generating new operational key failed"; +static NSString * const kDeviceControllerErrorCSRValidation = @"Extracting public key from CSR failed"; +static NSString * const kDeviceControllerErrorGetCommissionee = @"Failure obtaining device being commissioned"; +static NSString * const kDeviceControllerErrorGetAttestationChallenge = @"Failure getting attestation challenge"; +static NSString * const kDeviceControllerErrorSpake2pVerifierGenerationFailed = @"PASE verifier generation failed"; +static NSString * const kDeviceControllerErrorSpake2pVerifierSerializationFailed = @"PASE verifier serialization failed"; +static NSString * const kDeviceControllerErrorCDCertStoreInit = @"Init failure while initializing Certificate Declaration Signing Keys store"; + NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index bb5a8ce1801631..2dc7bd266a4335 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -302,6 +302,8 @@ 99AECC802798A57F00B6355B /* MTRCommissioningParameters.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99AECC7F2798A57E00B6355B /* MTRCommissioningParameters.mm */; }; 99C65E10267282F1003402F6 /* MTRControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 99C65E0F267282F1003402F6 /* MTRControllerTests.m */; }; 99D466E12798936D0089A18F /* MTRCommissioningParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D466E02798936D0089A18F /* MTRCommissioningParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9B231B042C62EF650030EB37 /* MTRDeviceController_Concrete.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B231B022C62EF650030EB37 /* MTRDeviceController_Concrete.h */; }; + 9B231B052C62EF650030EB37 /* MTRDeviceController_Concrete.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B231B032C62EF650030EB37 /* MTRDeviceController_Concrete.mm */; }; 9BDA2A062C5D9AF800A32BDD /* MTRDevice_Concrete.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDA2A052C5D9AF800A32BDD /* MTRDevice_Concrete.mm */; }; 9BDA2A082C5D9AFB00A32BDD /* MTRDevice_Concrete.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BDA2A072C5D9AFB00A32BDD /* MTRDevice_Concrete.h */; }; AF1CB86E2874B03B00865A96 /* MTROTAProviderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1CB86D2874B03B00865A96 /* MTROTAProviderDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -731,6 +733,8 @@ 99AECC7F2798A57E00B6355B /* MTRCommissioningParameters.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCommissioningParameters.mm; sourceTree = ""; }; 99C65E0F267282F1003402F6 /* MTRControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRControllerTests.m; sourceTree = ""; }; 99D466E02798936D0089A18F /* MTRCommissioningParameters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommissioningParameters.h; sourceTree = ""; }; + 9B231B022C62EF650030EB37 /* MTRDeviceController_Concrete.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceController_Concrete.h; sourceTree = ""; }; + 9B231B032C62EF650030EB37 /* MTRDeviceController_Concrete.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceController_Concrete.mm; sourceTree = ""; }; 9BDA2A052C5D9AF800A32BDD /* MTRDevice_Concrete.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDevice_Concrete.mm; sourceTree = ""; }; 9BDA2A072C5D9AFB00A32BDD /* MTRDevice_Concrete.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDevice_Concrete.h; sourceTree = ""; }; AF1CB86D2874B03B00865A96 /* MTROTAProviderDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTROTAProviderDelegate.h; sourceTree = ""; }; @@ -1242,6 +1246,8 @@ B202528F2459E34F00F97062 /* CHIP */ = { isa = PBXGroup; children = ( + 9B231B022C62EF650030EB37 /* MTRDeviceController_Concrete.h */, + 9B231B032C62EF650030EB37 /* MTRDeviceController_Concrete.mm */, 88E07D602B9A89A4005FD53E /* MTRMetricKeys.h */, 88FA798B2B7B257100CD4B6F /* MTRMetricsCollector.h */, 88FA798C2B7B257100CD4B6F /* MTRMetricsCollector.mm */, @@ -1676,6 +1682,7 @@ 51E51FC0282AD37A00FC978D /* MTRDeviceControllerStartupParams_Internal.h in Headers */, 3DECCB702934AECD00585AEC /* MTRLogging.h in Headers */, 1E4D654E29C208DD00BC3478 /* MTRCommissionableBrowserResult.h in Headers */, + 9B231B042C62EF650030EB37 /* MTRDeviceController_Concrete.h in Headers */, 515BE4ED2B72C0C5000BC1FD /* MTRUnfairLock.h in Headers */, 998F286F26D55EC5001846C6 /* MTRP256KeypairBridge.h in Headers */, 2C222ADF255C811800E446B9 /* MTRBaseDevice_Internal.h in Headers */, @@ -1986,6 +1993,7 @@ 511913FB28C100EF009235E9 /* MTRBaseSubscriptionCallback.mm in Sources */, 510470FB2A2F7DF60053EA7E /* MTRBackwardsCompatShims.mm in Sources */, 5173A47629C0E2ED00F67F48 /* MTRFabricInfo.mm in Sources */, + 9B231B052C62EF650030EB37 /* MTRDeviceController_Concrete.mm in Sources */, 5ACDDD7D27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm in Sources */, 75B3269E2BCDB9EA00E17C4E /* MTRDeviceConnectivityMonitor.mm in Sources */, 513DDB8A2761F6F900DAA01A /* MTRAttributeTLVValueDecoder.mm in Sources */,