diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h index 7d5b19d68bacca..4392b7f56d98ec 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN +@protocol MTRDiagnosticLogsDelegate; @protocol MTRStorage; @protocol MTRPersistentStorageDelegate; @protocol MTROTAProviderDelegate; @@ -58,6 +59,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) */ @property (nonatomic, strong, nullable) id otaProviderDelegate; +/* + * Diagnostic Logs delegate to be called when a BDX transfer request for logs is received. + * + * Calls to this delegate can happen on an arbitrary thread, but will not happen + * concurrently. + */ +@property (nonatomic, strong, nullable) id diagnosticLogsDelegate; + /* * The Product Attestation Authority certificates that are trusted to sign * device attestation information (and in particular to sign Product Attestation diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index b87155b0f17b13..f72f987326250c 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -31,6 +31,7 @@ #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDeviceController_Internal.h" +#import "MTRDiagnosticLogsDelegateBridge.h" #import "MTRError_Internal.h" #import "MTRFabricInfo_Internal.h" #import "MTRFramework.h" @@ -80,6 +81,7 @@ @interface MTRDeviceControllerFactory () @property (readonly) DeviceControllerFactory * controllerFactory; @property (readonly) PersistentStorageDelegate * persistentStorageDelegate; @property (readonly) MTROTAProviderDelegateBridge * otaProviderDelegateBridge; +@property (readonly) MTRDiagnosticLogsDelegateBridge * diagnosticLogsDelegateBridge; @property (readonly) Crypto::RawKeySessionKeystore * sessionKeystore; // We use TestPersistentStorageDelegate just to get an in-memory store to back // our group data provider impl. We initialize this store correctly on every @@ -133,11 +135,14 @@ @interface MTRDeviceControllerFactory () @property (nonatomic, readonly, nullable) id otaProviderDelegate; @property (nonatomic, readonly, nullable) dispatch_queue_t otaProviderDelegateQueue; +@property (nonatomic, readonly, nullable) id diagnosticLogsDelegate; + - (BOOL)findMatchingFabric:(FabricTable &)fabricTable params:(MTRDeviceControllerStartupParams *)params fabric:(const FabricInfo * _Nullable * _Nonnull)fabric; - (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceController * _Nonnull)controller; +- (MTRDeviceController * _Nullable)maybeInitializeDiagnosticLogsDelegate:(MTRDeviceController * _Nonnull)controller; @end @interface MTRDeviceControllerFactoryParams () @@ -323,6 +328,12 @@ - (void)cleanupStartupObjects _otaProviderDelegateQueue = nil; _otaProviderDelegate = nil; + if (_diagnosticLogsDelegateBridge) { + delete _diagnosticLogsDelegateBridge; + _diagnosticLogsDelegateBridge = nullptr; + } + _diagnosticLogsDelegate = nil; + if (_sessionResumptionStorage) { delete _sessionResumptionStorage; _sessionResumptionStorage = nullptr; @@ -436,6 +447,10 @@ - (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams } _otaProviderDelegateBridge = new MTROTAProviderDelegateBridge(); + _diagnosticLogsDelegateBridge = new MTRDiagnosticLogsDelegateBridge(); + _diagnosticLogsDelegate = startupParams.diagnosticLogsDelegate; + _diagnosticLogsDelegateBridge->SetDelegate(_diagnosticLogsDelegate); + // TODO: Allow passing a different keystore implementation via startupParams. _keystore = new PersistentStorageOperationalKeystore(); if (_keystore == nullptr) { @@ -722,6 +737,13 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController * *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; } } + + controller = [self maybeInitializeDiagnosticLogsDelegate:controller]; + if (controller == nil) { + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; + } + } return controller; } @@ -912,6 +934,26 @@ - (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceControll return controller; } +// Initialize the MTRDiagnosticLogsDelegateBridge if it has not been initialized already +// +// Returns nil on failure, the input controller on success. +// If the delegate has been initialized already, it is not considered as a failure. +// +- (MTRDeviceController * _Nullable)maybeInitializeDiagnosticLogsDelegate:(MTRDeviceController * _Nonnull)controller +{ + [self _assertCurrentQueueIsNotMatterQueue]; + + VerifyOrReturnValue(_diagnosticLogsDelegateBridge != nil, controller); + VerifyOrReturnValue([_controllers count] == 1, controller); + + dispatch_sync(_chipWorkQueue, ^{ + auto systemState = _controllerFactory->GetSystemState(); + systemState->BDXTransferServer()->SetDelegate(_diagnosticLogsDelegateBridge); + }); + + return controller; +} + @end @implementation MTRDeviceControllerFactory (InternalMethods) @@ -1158,6 +1200,7 @@ - (instancetype)initWithStorage:(id)storage _storage = storage; _hasStorage = YES; _otaProviderDelegate = nil; + _diagnosticLogsDelegate = nil; _productAttestationAuthorityCertificates = nil; _certificationDeclarationCertificates = nil; _port = nil; @@ -1178,6 +1221,7 @@ - (instancetype)initWithoutStorage _storage = [[MTRDummyStorage alloc] init]; _hasStorage = NO; _otaProviderDelegate = nil; + _diagnosticLogsDelegate = nil; _productAttestationAuthorityCertificates = nil; _certificationDeclarationCertificates = nil; _port = nil; diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegate.h b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegate.h new file mode 100644 index 00000000000000..fe84e23e10e50c --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegate.h @@ -0,0 +1,73 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +#import +#import +#import + +@class MTRDeviceController; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The protocol definition for the MTRDiagnosticLogsDelegate. + * + */ +@protocol MTRDiagnosticLogsDelegate +/** + * Notify the delegate when a BDX Session starts for some logs. + * The controller identifies the fabric the node is on, and the + * nodeID identifies the node within that fabric. + * + * If completion is passed a non-nil error, that will be converted into + * an error response to the sender. Otherwise a success response will be sent. + */ +- (void)handleBDXTransferSessionBeginForNodeID:(NSNumber *)nodeID + controller:(MTRDeviceController *)controller + fileDesignator:(NSString *)fileDesignator + completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; + +/** + * Notify the delegate when some data is received on the BDX Session. + * The controller identifies the fabric the node is on, and the + * nodeID identifies the node within that fabric. + * + * If completion is passed a non-nil error, that will be converted into + * an error response to the sender. Otherwise a success response will be sent. + */ +- (void)handleBDXTransferSessionDataForNodeID:(NSNumber *)nodeID + controller:(MTRDeviceController *)controller + fileDesignator:(NSString *)fileDesignator + data:(NSData *)data + completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; + +/** + * Notify the delegate when a BDX Session ends for some logs. + * The controller identifies the fabric the node is on, and the + * nodeID identifies the node within that fabric. + */ +- (void)handleBDXTransferSessionEndForNodeID:(NSNumber *)nodeID + controller:(MTRDeviceController *)controller + fileDesignator:(NSString *)fileDesignator + error:(NSError * _Nullable)error + MTR_NEWLY_AVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.h b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.h new file mode 100644 index 00000000000000..76119b123ed2d1 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.h @@ -0,0 +1,42 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +#import + +#include + +NS_ASSUME_NONNULL_BEGIN + +class MTRDiagnosticLogsDelegateBridge : public chip::bdx::BDXTransferServerDelegate +{ +public: + MTRDiagnosticLogsDelegateBridge(); + ~MTRDiagnosticLogsDelegateBridge(); + + void SetDelegate(id delegate) { mDelegate = delegate; }; + + /////////// BDXTransferServerDelegate Interface ///////// + CHIP_ERROR OnTransferBegin(chip::bdx::BDXTransferProxy * transfer) override; + CHIP_ERROR OnTransferEnd(chip::bdx::BDXTransferProxy * transfer, CHIP_ERROR error) override; + CHIP_ERROR OnTransferData(chip::bdx::BDXTransferProxy * transfer, const chip::ByteSpan & data) override; + +private: + id mDelegate; + dispatch_queue_t mDelegateNotificationQueue; +}; + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.mm b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.mm new file mode 100644 index 00000000000000..4941f4e14bc946 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDelegateBridge.mm @@ -0,0 +1,137 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +#import "MTRDiagnosticLogsDelegateBridge.h" + +#import "MTRDeviceControllerFactory_Internal.h" +#import "MTRDeviceController_Internal.h" +#import "MTRError_Internal.h" +#import "NSDataSpanConversion.h" +#import "NSStringSpanConversion.h" + +constexpr const char kQueueName[] = "org.csa-iot.matter.framework.diagnosticlogs.workqueue"; + +MTRDiagnosticLogsDelegateBridge::MTRDiagnosticLogsDelegateBridge() +{ + mDelegateNotificationQueue = dispatch_queue_create(kQueueName, DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); +} + +MTRDiagnosticLogsDelegateBridge::~MTRDiagnosticLogsDelegateBridge() +{ + mDelegateNotificationQueue = nil; + mDelegate = nil; +} + +CHIP_ERROR MTRDiagnosticLogsDelegateBridge::OnTransferBegin(chip::bdx::BDXTransferProxy * transfer) +{ + VerifyOrReturnError(nil != mDelegate, CHIP_ERROR_NOT_IMPLEMENTED); + + auto fileDesignatorSpan = transfer->GetFileDesignator(); + auto fileDesignator = AsString(fileDesignatorSpan); + VerifyOrReturnError(nil != fileDesignator, CHIP_ERROR_INCORRECT_STATE); + + auto nodeId = @(transfer->GetPeerNodeId()); + auto fabricIndex = transfer->GetFabricIndex(); + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:fabricIndex]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + + auto completionHandler = ^(NSError * _Nullable error) { + [controller asyncDispatchToMatterQueue:^() { + if (error != nil) { + auto err = [MTRError errorToCHIPErrorCode:error]; + transfer->Reject(err); + } else { + transfer->Accept(); + } + } errorHandler:^(NSError *) { + // Not much we can do here + }]; + }; + + auto strongDelegate = mDelegate; + dispatch_async( + mDelegateNotificationQueue, ^{ + [strongDelegate handleBDXTransferSessionBeginForNodeID:nodeId controller:controller fileDesignator:fileDesignator completion:completionHandler]; + }); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsDelegateBridge::OnTransferEnd(chip::bdx::BDXTransferProxy * transfer, CHIP_ERROR error) +{ + VerifyOrReturnError(nil != mDelegate, CHIP_ERROR_NOT_IMPLEMENTED); + + auto fileDesignatorSpan = transfer->GetFileDesignator(); + auto fileDesignator = AsString(fileDesignatorSpan); + VerifyOrReturnError(nil != fileDesignator, CHIP_ERROR_INCORRECT_STATE); + + NSError * mtrError = nil; + if (CHIP_NO_ERROR != error) { + mtrError = [MTRError errorForCHIPErrorCode:error]; + } + + auto nodeId = @(transfer->GetPeerNodeId()); + auto fabricIndex = transfer->GetFabricIndex(); + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:fabricIndex]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + + auto strongDelegate = mDelegate; + dispatch_async( + mDelegateNotificationQueue, ^{ + [strongDelegate handleBDXTransferSessionEndForNodeID:nodeId controller:controller fileDesignator:fileDesignator error:mtrError]; + }); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsDelegateBridge::OnTransferData(chip::bdx::BDXTransferProxy * transfer, const chip::ByteSpan & dataSpan) +{ + VerifyOrReturnError(nil != mDelegate, CHIP_ERROR_NOT_IMPLEMENTED); + + auto fileDesignatorSpan = transfer->GetFileDesignator(); + auto fileDesignator = AsString(fileDesignatorSpan); + VerifyOrReturnError(nil != fileDesignator, CHIP_ERROR_INCORRECT_STATE); + + auto data = AsData(dataSpan); + VerifyOrReturnError(nil != data, CHIP_ERROR_INCORRECT_STATE); + + auto nodeId = @(transfer->GetPeerNodeId()); + auto fabricIndex = transfer->GetFabricIndex(); + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:fabricIndex]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + + auto completionHandler = ^(NSError * _Nullable error) { + [controller asyncDispatchToMatterQueue:^() { + if (error != nil) { + auto err = [MTRError errorToCHIPErrorCode:error]; + transfer->Reject(err); + } else { + transfer->Continue(); + } + } errorHandler:^(NSError *) { + // Not much we can do here + }]; + }; + + auto strongDelegate = mDelegate; + dispatch_async( + mDelegateNotificationQueue, ^{ + [strongDelegate handleBDXTransferSessionDataForNodeID:nodeId controller:controller fileDesignator:fileDesignator data:data completion:completionHandler]; + }); + + return CHIP_NO_ERROR; +} diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index 2cf62428bbfc2c..4cd13f875d48ac 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -45,6 +45,7 @@ #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index a7f00d50661487..2447bdd2f650f2 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -299,6 +299,9 @@ B45373FF2A9FEC4F00807602 /* unix-misc.c in Sources */ = {isa = PBXBuildFile; fileRef = B45373F82A9FEC4F00807602 /* unix-misc.c */; }; B45374002A9FEC4F00807602 /* unix-init.c in Sources */ = {isa = PBXBuildFile; fileRef = B45373F92A9FEC4F00807602 /* unix-init.c */; }; B45374012A9FEC4F00807602 /* unix-sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = B45373FA2A9FEC4F00807602 /* unix-sockets.c */; }; + B4C8E6B52B3453AD00FCD54D /* MTRDiagnosticLogsDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = B4C8E6B22B3453AD00FCD54D /* MTRDiagnosticLogsDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B4C8E6B62B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B4C8E6B32B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.h */; }; + B4C8E6B72B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.mm */; }; B4E262162AA0CF1C00DBA5BC /* RemoteDataModelLogger.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E262122AA0C7A300DBA5BC /* RemoteDataModelLogger.mm */; }; B4E262172AA0CF2000DBA5BC /* RemoteDataModelLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = B4E262132AA0C7A300DBA5BC /* RemoteDataModelLogger.h */; }; B4E2621B2AA0D02000DBA5BC /* SleepCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */; }; @@ -669,6 +672,9 @@ B45373F82A9FEC4F00807602 /* unix-misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "unix-misc.c"; path = "repo/lib/plat/unix/unix-misc.c"; sourceTree = ""; }; B45373F92A9FEC4F00807602 /* unix-init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "unix-init.c"; path = "repo/lib/plat/unix/unix-init.c"; sourceTree = ""; }; B45373FA2A9FEC4F00807602 /* unix-sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "unix-sockets.c"; path = "repo/lib/plat/unix/unix-sockets.c"; sourceTree = ""; }; + B4C8E6B22B3453AD00FCD54D /* MTRDiagnosticLogsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDiagnosticLogsDelegate.h; sourceTree = ""; }; + B4C8E6B32B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDiagnosticLogsDelegateBridge.h; sourceTree = ""; }; + B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDiagnosticLogsDelegateBridge.mm; sourceTree = ""; }; B4E262122AA0C7A300DBA5BC /* RemoteDataModelLogger.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteDataModelLogger.mm; sourceTree = ""; }; B4E262132AA0C7A300DBA5BC /* RemoteDataModelLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteDataModelLogger.h; sourceTree = ""; }; B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SleepCommand.mm; sourceTree = ""; }; @@ -1105,6 +1111,9 @@ B202528F2459E34F00F97062 /* CHIP */ = { isa = PBXGroup; children = ( + B4C8E6B22B3453AD00FCD54D /* MTRDiagnosticLogsDelegate.h */, + B4C8E6B32B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.h */, + B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.mm */, 1E4D655129C30A8700BC3478 /* MTRCommissionableBrowser.mm */, 1E4D654C29C208DD00BC3478 /* MTRCommissionableBrowser.h */, 1E4D654D29C208DD00BC3478 /* MTRCommissionableBrowserDelegate.h */, @@ -1421,6 +1430,7 @@ 2C1B027B2641DB4E00780EF1 /* MTROperationalCredentialsDelegate.h in Headers */, 5173A47529C0E2ED00F67F48 /* MTRFabricInfo_Internal.h in Headers */, 3D843717294979230070D20A /* MTRClusters_Internal.h in Headers */, + B4C8E6B52B3453AD00FCD54D /* MTRDiagnosticLogsDelegate.h in Headers */, 7596A85728788557004DAE0E /* MTRClusters.h in Headers */, 99D466E12798936D0089A18F /* MTRCommissioningParameters.h in Headers */, 5136661528067D550025EDAE /* MTRDeviceControllerFactory_Internal.h in Headers */, @@ -1465,6 +1475,7 @@ 2C8C8FC1253E0C2100797F05 /* MTRStorage.h in Headers */, AF1CB8702874B04C00865A96 /* MTROTAProviderDelegateBridge.h in Headers */, B2E0D7B5245B0B5C003C5B48 /* MTRQRCodeSetupPayloadParser.h in Headers */, + B4C8E6B62B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.h in Headers */, 1EC4CE6425CC276600D7304F /* MTRBaseClusters.h in Headers */, 3D843712294977000070D20A /* MTRCallbackBridgeBase.h in Headers */, 3DECCB742934C21B00585AEC /* MTRDefines.h in Headers */, @@ -1735,6 +1746,7 @@ 75B765C32A1D82D30014719B /* MTRAttributeSpecifiedCheck.mm in Sources */, AF5F90FF2878D351005503FA /* MTROTAProviderDelegateBridge.mm in Sources */, 51E95DFC2A78443C00A434F0 /* MTRSessionResumptionStorageBridge.mm in Sources */, + B4C8E6B72B3453AD00FCD54D /* MTRDiagnosticLogsDelegateBridge.mm in Sources */, 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */, 2C5EEEF7268A85C400CAE3D3 /* MTRDeviceConnectionBridge.mm in Sources */, 51B22C262740CB32008D5055 /* MTRStructsObjc.mm in Sources */,