Dft xpc2 (#36719)

* [darwin-framework-tool][XPC] Add a XPC server registry.

* [darwin-framework-tool][XPC] Add a XPC server for MTRDeviceControllerServerProtocol.

* [darwin-framework-tool][XPC] Add a XPC server for MTRXPCServerProtocol
diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn
index e0224cc..7532ed8 100644
--- a/examples/darwin-framework-tool/BUILD.gn
+++ b/examples/darwin-framework-tool/BUILD.gn
@@ -218,6 +218,9 @@
     "commands/common/PreferencesStorage.mm",
     "commands/common/RemoteDataModelLogger.h",
     "commands/common/RemoteDataModelLogger.mm",
+    "commands/common/xpc/DeviceControllerServer.mm",
+    "commands/common/xpc/XPCServer.mm",
+    "commands/common/xpc/XPCServerRegistry.mm",
     "commands/configuration/Commands.h",
     "commands/configuration/ResetMRPParametersCommand.h",
     "commands/configuration/ResetMRPParametersCommand.mm",
diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
index 7f9f3f9..e1cc97e 100644
--- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
+++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
@@ -52,6 +52,7 @@
         AddArgument("commissioner-vendor-id", 0, UINT16_MAX, &mCommissionerVendorId,
             "The vendor id to use for darwin-framework-tool. If not provided, chip::VendorId::TestVendor1 (65521, 0xFFF1) will be "
             "used.");
+        AddArgument("use-xpc", &mUseXPC, "Use a controller that will connect to an XPC endpoint instead of talking to devices directly. If a string argument is provided, it must identify a Mach service name that can be used to connect to a remote endpoint. If no argument is provided, a local endpoint will be used.");
     }
 
     /////////// Command Interface /////////
@@ -168,4 +169,5 @@
     chip::Optional<char *> mPaaTrustStorePath;
     chip::Optional<chip::VendorId> mCommissionerVendorId;
     std::string mCurrentIdentity;
+    chip::Optional<chip::app::DataModel::Nullable<char *>> mUseXPC;
 };
diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
index 0eb7d60..d4154de 100644
--- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
+++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
@@ -31,6 +31,8 @@
 #import "DeviceDelegate.h"
 #include "MTRError_Utils.h"
 
+#include "xpc/XPCServerRegistry.h"
+
 #include <map>
 #include <string>
 
@@ -45,6 +47,17 @@
 bool CHIPCommandBridge::sUseSharedStorage = true;
 constexpr char kTrustStorePathVariable[] = "PAA_TRUST_STORE_PATH";
 
+namespace {
+NSString * ToNSString(const chip::Optional<chip::app::DataModel::Nullable<char *>> & string)
+{
+    if (!string.HasValue() && string.Value().IsNull()) {
+        return nil;
+    }
+
+    return @(string.Value().Value());
+}
+}
+
 CHIP_ERROR CHIPCommandBridge::Run()
 {
     // In interactive mode, we want to avoid memory accumulating in the main autorelease pool,
@@ -143,6 +156,8 @@
         productAttestationAuthorityCertificates = nil;
     }
 
+    [[XPCServerRegistry sharedInstance] start];
+
     sUseSharedStorage = mCommissionerSharedStorage.ValueOr(false);
     if (sUseSharedStorage) {
         return SetUpStackWithSharedStorage(productAttestationAuthorityCertificates);
@@ -202,7 +217,13 @@
 
         params.productAttestationAuthorityCertificates = productAttestationAuthorityCertificates;
 
-        __auto_type * controller = [[MTRDeviceController alloc] initWithParameters:params error:&error];
+        MTRDeviceController * controller = nil;
+        if (mUseXPC.HasValue()) {
+            __auto_type * identifier = uuidString;
+            controller = [[XPCServerRegistry sharedInstance] createController:identifier serviceName:ToNSString(mUseXPC) params:params error:&error];
+        } else {
+            controller = [[MTRDeviceController alloc] initWithParameters:params error:&error];
+        }
         VerifyOrReturnError(nil != controller, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Controller startup failure: %@", error));
         mControllers[identities[i]] = controller;
     }
@@ -237,12 +258,18 @@
             params.nodeId = @(mCommissionerNodeId.Value());
         }
 
-        // We're not sure whether we're creating a new fabric or using an existing one, so just try both.
-        auto controller = [factory createControllerOnExistingFabric:params error:&error];
-        if (controller == nil) {
-            // Maybe we didn't have this fabric yet.
-            params.vendorID = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1));
-            controller = [factory createControllerOnNewFabric:params error:&error];
+        MTRDeviceController * controller = nil;
+        if (mUseXPC.HasValue()) {
+            __auto_type * identifier = @(identities[i]);
+            controller = [[XPCServerRegistry sharedInstance] createController:identifier serviceName:ToNSString(mUseXPC) params:params error:&error];
+        } else {
+            // We're not sure whether we're creating a new fabric or using an existing one, so just try both.
+            controller = [factory createControllerOnExistingFabric:params error:&error];
+            if (controller == nil) {
+                // Maybe we didn't have this fabric yet.
+                params.vendorID = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1));
+                controller = [factory createControllerOnNewFabric:params error:&error];
+            }
         }
         VerifyOrReturnError(nil != controller, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Controller startup failure: %@", error));
         mControllers[identities[i]] = controller;
@@ -256,6 +283,8 @@
     if (IsInteractive()) {
         return;
     }
+
+    [[XPCServerRegistry sharedInstance] stop];
     ShutdownCommissioner();
 }
 
diff --git a/examples/darwin-framework-tool/commands/common/xpc/DeviceControllerServer.mm b/examples/darwin-framework-tool/commands/common/xpc/DeviceControllerServer.mm
new file mode 100644
index 0000000..7b0f9ac
--- /dev/null
+++ b/examples/darwin-framework-tool/commands/common/xpc/DeviceControllerServer.mm
@@ -0,0 +1,349 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#import "XPCServerProtocols.h"
+
+#import <lib/support/logging/CHIPLogging.h>
+
+@interface DeviceControllerXPCServerImpl : NSObject <MTRDeviceControllerServerProtocol>
+@property (nonatomic, strong) id<MTRDeviceControllerClientProtocol> clientProxy;
+@property (nonatomic, strong) NSArray<MTRDeviceController *> * controllers;
+@property (nonatomic, strong) dispatch_queue_t callbackQueue;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)initWithClientProxy:(id<MTRXPCClientProtocol>)proxy controllers:(NSArray<MTRDeviceController *> *)controllers;
+@end
+
+@implementation DeviceControllerXPCServerImpl
+- (instancetype)initWithClientProxy:(id<MTRDeviceControllerClientProtocol>)proxy controllers:(NSArray<MTRDeviceController *> *)controllers
+{
+    if ([super init]) {
+        _clientProxy = proxy;
+        _controllers = controllers;
+        _callbackQueue = dispatch_queue_create("com.chip.xpc.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+    }
+    return self;
+}
+
+- (MTRBaseDevice *)createDevice:(id)uniqueIdentifierString nodeID:(uint64_t)nodeID
+{
+    if (![uniqueIdentifierString isKindOfClass:[NSString class]]) {
+        ChipLogError(chipTool, "The controller identifier should be a NSString.");
+        return nil;
+    }
+
+    __auto_type * uniqueIdentifier = [[NSUUID alloc] initWithUUIDString:uniqueIdentifierString];
+    for (MTRDeviceController * controller in _controllers) {
+        if ([controller.uniqueIdentifier isEqual:uniqueIdentifier]) {
+            return [MTRBaseDevice deviceWithNodeID:@(nodeID) controller:controller];
+        }
+    }
+
+    ChipLogError(chipTool, "The controller '%s' could not be found.", [uniqueIdentifierString UTF8String]);
+    return nil;
+}
+
+- (void)getAnyDeviceControllerWithCompletion:(MTRDeviceControllerGetterHandler)completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+- (void)readAttributeWithController:(id _Nullable)controller
+                             nodeId:(uint64_t)nodeId
+                         endpointId:(NSNumber * _Nullable)endpointId
+                          clusterId:(NSNumber * _Nullable)clusterId
+                        attributeId:(NSNumber * _Nullable)attributeId
+                             params:(NSDictionary<NSString *, id> * _Nullable)params
+                         completion:(MTRValuesHandler)completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controller nodeID:nodeId];
+    [device readAttributesWithEndpointID:endpointId
+                               clusterID:clusterId
+                             attributeID:attributeId
+                                  params:[MTRDeviceController decodeXPCReadParams:params]
+                                   queue:_callbackQueue
+                              completion:^(NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error) {
+                                  completion([MTRDeviceController encodeXPCResponseValues:values], error);
+                              }];
+}
+
+- (void)writeAttributeWithController:(id _Nullable)controller
+                              nodeId:(uint64_t)nodeId
+                          endpointId:(NSNumber *)endpointId
+                           clusterId:(NSNumber *)clusterId
+                         attributeId:(NSNumber *)attributeId
+                               value:(id)value
+                   timedWriteTimeout:(NSNumber * _Nullable)timeoutMs
+                          completion:(MTRValuesHandler)completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controller nodeID:nodeId];
+    [device
+        writeAttributeWithEndpointID:endpointId
+                           clusterID:clusterId
+                         attributeID:attributeId
+                               value:value
+                   timedWriteTimeout:timeoutMs
+                               queue:_callbackQueue
+                          completion:^(NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error) {
+                              completion([MTRDeviceController encodeXPCResponseValues:values], error);
+                          }];
+}
+
+- (void)invokeCommandWithController:(id _Nullable)controller
+                             nodeId:(uint64_t)nodeId
+                         endpointId:(NSNumber *)endpointId
+                          clusterId:(NSNumber *)clusterId
+                          commandId:(NSNumber *)commandId
+                             fields:(id)fields
+                 timedInvokeTimeout:(NSNumber * _Nullable)timeoutMs
+                         completion:(MTRValuesHandler)completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controller nodeID:nodeId];
+    [device
+        invokeCommandWithEndpointID:endpointId
+                          clusterID:clusterId
+                          commandID:commandId
+                      commandFields:fields
+                 timedInvokeTimeout:timeoutMs
+                              queue:_callbackQueue
+                         completion:^(NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error) {
+                             completion([MTRDeviceController encodeXPCResponseValues:values], error);
+                         }];
+}
+
+- (void)subscribeAttributeWithController:(id _Nullable)controller
+                                  nodeId:(uint64_t)nodeId
+                              endpointId:(NSNumber * _Nullable)endpointId
+                               clusterId:(NSNumber * _Nullable)clusterId
+                             attributeId:(NSNumber * _Nullable)attributeId
+                             minInterval:(NSNumber *)minInterval
+                             maxInterval:(NSNumber *)maxInterval
+                                  params:(NSDictionary<NSString *, id> * _Nullable)params
+                      establishedHandler:(dispatch_block_t)establishedHandler
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controller nodeID:nodeId];
+    if (nil == device) {
+        establishedHandler();
+        // Send an error report so that the client knows of the failure
+        [self.clientProxy handleReportWithController:controller
+                                              nodeId:nodeId
+                                              values:nil
+                                               error:[NSError errorWithDomain:MTRErrorDomain
+                                                                         code:MTRErrorCodeGeneralError
+                                                                     userInfo:nil]];
+        return;
+    }
+
+    auto subscriptionParams = [MTRDeviceController decodeXPCSubscribeParams:params];
+    if (subscriptionParams == nil) {
+        subscriptionParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
+    } else {
+        subscriptionParams.minInterval = minInterval;
+        subscriptionParams.maxInterval = maxInterval;
+    }
+
+    [device subscribeToAttributesWithEndpointID:endpointId
+                                      clusterID:clusterId
+                                    attributeID:attributeId
+                                         params:subscriptionParams
+                                          queue:_callbackQueue
+                                  reportHandler:^(
+                                      NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error) {
+                                      [self.clientProxy
+                                          handleReportWithController:controller
+                                                              nodeId:nodeId
+                                                              values:[MTRDeviceController encodeXPCResponseValues:values]
+                                                               error:error];
+                                  }
+                        subscriptionEstablished:establishedHandler];
+}
+
+- (void)stopReportsWithController:(id _Nullable)controller nodeId:(uint64_t)nodeId completion:(dispatch_block_t)completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controller nodeID:nodeId];
+    VerifyOrReturn(nil != device, completion());
+
+    [device deregisterReportHandlersWithQueue:_callbackQueue completion:completion];
+}
+
+- (void)subscribeWithController:(id _Nullable)controller
+                         nodeId:(uint64_t)nodeId
+                    minInterval:(NSNumber *)minInterval
+                    maxInterval:(NSNumber *)maxInterval
+                         params:(NSDictionary<NSString *, id> * _Nullable)params
+                    shouldCache:(BOOL)shouldCache
+                     completion:(MTRStatusCompletion)completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(error);
+}
+
+- (void)readAttributeCacheWithController:(id _Nullable)controller
+                                  nodeId:(uint64_t)nodeId
+                              endpointId:(NSNumber * _Nullable)endpointId
+                               clusterId:(NSNumber * _Nullable)clusterId
+                             attributeId:(NSNumber * _Nullable)attributeId
+                              completion:(MTRValuesHandler)completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+- (void)getDeviceControllerWithFabricId:(uint64_t)fabricId
+                             completion:(MTRDeviceControllerGetterHandler)completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+- (void)downloadLogWithController:(id _Nullable)controller
+                           nodeId:(NSNumber *)nodeId
+                             type:(MTRDiagnosticLogType)type
+                          timeout:(NSTimeInterval)timeout
+                       completion:(void (^)(NSString * _Nullable url, NSError * _Nullable error))completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+@end
+
+@interface DeviceControllerXPCServer : NSObject <XPCServerStartupParametersProtocol>
+@property (nonatomic, strong) NSXPCListener * listener;
+@property (nonatomic, strong) NSMutableArray<MTRDeviceController *> * controllers;
+@end
+
+@implementation DeviceControllerXPCServer
+- (instancetype)init
+{
+    if ((self = [super init])) {
+        _controllers = [NSMutableArray new];
+    }
+
+    return self;
+}
+
+- (void)start
+{
+    _listener = [NSXPCListener anonymousListener];
+    [_listener setDelegate:self];
+    [_listener resume];
+}
+
+- (void)stop
+{
+    [_listener suspend];
+    _listener = nil;
+    _controllers = nil;
+}
+
+- (MTRDeviceController *)createController:(MTRDeviceControllerStartupParams *)params error:(NSError * __autoreleasing *)error
+{
+    __auto_type * factory = [MTRDeviceControllerFactory sharedInstance];
+    __auto_type * local = [factory createControllerOnExistingFabric:params error:error];
+    if (nil == local) {
+        return nil;
+    }
+    [_controllers addObject:local];
+
+    __auto_type connectBlock = ^NSXPCConnection *
+    {
+        return [[NSXPCConnection alloc] initWithListenerEndpoint:self.listener.endpoint];
+    };
+    return [MTRDeviceController sharedControllerWithID:[local.uniqueIdentifier UUIDString] xpcConnectBlock:connectBlock];
+}
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
+{
+    newConnection.exportedInterface = [MTRDeviceController xpcInterfaceForServerProtocol];
+    newConnection.remoteObjectInterface = [MTRDeviceController xpcInterfaceForClientProtocol];
+
+    auto server = [[DeviceControllerXPCServerImpl alloc] initWithClientProxy:[newConnection remoteObjectProxy] controllers:_controllers];
+    newConnection.exportedObject = server;
+
+    newConnection.interruptionHandler = ^{
+        ChipLogProgress(chipTool, "XPC connection interrupted");
+    };
+
+    newConnection.invalidationHandler = ^{
+        ChipLogProgress(chipTool, "XPC connection invalidated");
+    };
+
+    [newConnection resume];
+    return YES;
+}
+@end
+
+@interface DeviceControllerXPCServerWithServiceName : NSObject <XPCServerStartupParametersWithServiceNameProtocol>
+@end
+
+@implementation DeviceControllerXPCServerWithServiceName
+- (void)start
+{
+}
+
+- (void)stop
+{
+}
+
+- (MTRDeviceController *)createController:(NSString *)controllerID serviceName:(NSString *)serviceName error:(NSError * __autoreleasing *)error
+{
+    __auto_type connectBlock = ^NSXPCConnection *
+    {
+#if TARGET_OS_OSX
+        return [[NSXPCConnection alloc] initWithMachServiceName:serviceName options:0];
+#else
+        ChipLogError(chipTool, "NSXPCConnection::initWithMachServiceName is not supported on this platform.");
+        return nil;
+#endif // TARGET_OS_OSX
+    };
+    return [MTRDeviceController sharedControllerWithID:controllerID xpcConnectBlock:connectBlock];
+}
+@end
diff --git a/examples/darwin-framework-tool/commands/common/xpc/XPCServer.mm b/examples/darwin-framework-tool/commands/common/xpc/XPCServer.mm
new file mode 100644
index 0000000..9aa7e77
--- /dev/null
+++ b/examples/darwin-framework-tool/commands/common/xpc/XPCServer.mm
@@ -0,0 +1,259 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#import "XPCServerProtocols.h"
+
+#import <lib/support/logging/CHIPLogging.h>
+
+@interface XPCServerImpl : NSObject <MTRXPCServerProtocol_MTRDevice>
+@property (nonatomic, strong) id<MTRXPCClientProtocol> clientProxy;
+@property (nonatomic, strong) NSArray<MTRDeviceController *> * controllers;
+@property (nonatomic, strong) dispatch_queue_t callbackQueue;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)initWithClientProxy:(id<MTRXPCClientProtocol>)proxy controllers:(NSArray<MTRDeviceController *> *)controllers;
+@end
+
+@implementation XPCServerImpl
+- (instancetype)initWithClientProxy:(id<MTRXPCClientProtocol>)proxy controllers:(NSArray<MTRDeviceController *> *)controllers
+{
+    if ([super init]) {
+        _clientProxy = proxy;
+        _controllers = controllers;
+        _callbackQueue = dispatch_queue_create("com.chip.xpc.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+    }
+    return self;
+}
+
+- (MTRDevice *)createDevice:(NSUUID *)uniqueIdentifier nodeID:(NSNumber *)nodeID
+{
+    for (MTRDeviceController * controller in _controllers) {
+        if ([controller.uniqueIdentifier isEqual:uniqueIdentifier]) {
+            return [MTRDevice deviceWithNodeID:nodeID controller:controller];
+        }
+    }
+
+    ChipLogError(chipTool, "The controller '%s' could not be found.", [[uniqueIdentifier UUIDString] UTF8String]);
+    return nil;
+}
+
+// TODO this is declared optional but the framework does not do any check on it, so it just crashes.
+- (oneway void)deviceController:(NSUUID *)controllerUUID updateControllerConfiguration:(NSDictionary *)controllerState
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID getStateWithReply:(void (^)(MTRDeviceState state))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply(device.state);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID getDeviceCachePrimedWithReply:(void (^)(BOOL primed))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply(device.deviceCachePrimed);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID getEstimatedStartTimeWithReply:(void (^)(NSDate * _Nullable estimatedStartTime))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply(device.estimatedStartTime);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID getEstimatedSubscriptionLatencyWithReply:(void (^)(NSNumber * _Nullable estimatedSubscriptionLatency))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply(device.estimatedSubscriptionLatency);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID readAttributeWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID params:(MTRReadParams * _Nullable)params withReply:(void (^)(NSDictionary<NSString *, id> * _Nullable))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply([device readAttributeWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID params:params]);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID readAttributePaths:(NSArray<MTRAttributeRequestPath *> *)attributePaths withReply:(void (^)(NSArray<NSDictionary<NSString *, id> *> *))reply
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    reply([device readAttributePaths:attributePaths]);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID writeAttributeWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID value:(id)value expectedValueInterval:(NSNumber * _Nullable)expectedValueInterval timedWriteTimeout:(NSNumber * _Nullable)timeout
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    [device writeAttributeWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID value:value expectedValueInterval:expectedValueInterval timedWriteTimeout:timeout];
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID invokeCommandWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID commandID:(NSNumber *)commandID commandFields:(id)commandFields expectedValues:(NSArray<NSDictionary<NSString *, id> *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueInterval timedInvokeTimeout:(NSNumber * _Nullable)timeout serverSideProcessingTimeout:(NSNumber * _Nullable)serverSideProcessingTimeout completion:(MTRDeviceResponseHandler)completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    [device invokeCommandWithEndpointID:endpointID
+                              clusterID:clusterID
+                              commandID:commandID
+                          commandFields:commandFields
+                         expectedValues:expectedValues
+                  expectedValueInterval:expectedValueInterval
+                     timedInvokeTimeout:timeout
+                                  queue:_callbackQueue
+                             completion:^(NSArray * values, NSError * _Nullable error) {
+                                 completion(values, error);
+                             }];
+}
+
+- (oneway void)deviceController:(NSUUID *)controller nodeID:(NSNumber *)nodeID openCommissioningWindowWithSetupPasscode:(NSNumber *)setupPasscode discriminator:(NSNumber *)discriminator duration:(NSNumber *)duration completion:(MTRDeviceOpenCommissioningWindowHandler)completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+- (oneway void)deviceController:(NSUUID *)controllerUUID nodeID:(NSNumber *)nodeID downloadLogOfType:(MTRDiagnosticLogType)type timeout:(NSTimeInterval)timeout completion:(void (^)(NSURL * _Nullable url, NSError * _Nullable error))completion
+{
+    ChipLogProgress(chipTool, "XPC: %s", __func__);
+
+    __auto_type * device = [self createDevice:controllerUUID nodeID:nodeID];
+    [device downloadLogOfType:type timeout:timeout queue:_callbackQueue completion:completion];
+}
+
+- (oneway void)downloadLogOfType:(MTRDiagnosticLogType)type nodeID:(NSNumber *)nodeID timeout:(NSTimeInterval)timeout completion:(void (^)(NSURL * _Nullable url, NSError * _Nullable error))completion
+{
+    ChipLogError(chipTool, "XPC (NotImplemented): %s", __func__);
+
+    __auto_type * error = [NSError errorWithDomain:MTRErrorDomain
+                                              code:MTRErrorCodeGeneralError
+                                          userInfo:nil];
+    completion(nil, error);
+}
+
+@end
+
+@interface XPCServer : NSObject <XPCServerExternalCertificateParametersProtocol>
+@property (nonatomic, strong) NSXPCListener * listener;
+@property (nonatomic, strong) NSMutableArray<MTRDeviceController *> * controllers;
+@end
+
+@implementation XPCServer
+- (instancetype)init
+{
+    if ((self = [super init])) {
+        _controllers = [NSMutableArray new];
+    }
+
+    return self;
+}
+
+- (void)start
+{
+    _listener = [NSXPCListener anonymousListener];
+    [_listener setDelegate:self];
+    [_listener resume];
+}
+
+- (void)stop
+{
+    [_listener suspend];
+    _listener = nil;
+    _controllers = nil;
+}
+
+- (MTRDeviceController *)createController:(MTRDeviceControllerExternalCertificateParameters *)params error:(NSError * __autoreleasing *)error
+{
+    __auto_type * local = [[MTRDeviceController alloc] initWithParameters:params error:error];
+    if (nil == local) {
+        return nil;
+    }
+    [_controllers addObject:local];
+
+    __auto_type connectBlock = ^NSXPCConnection *
+    {
+        return [[NSXPCConnection alloc] initWithListenerEndpoint:self.listener.endpoint];
+    };
+    __auto_type * xpcParams = [[MTRXPCDeviceControllerParameters alloc] initWithXPConnectionBlock:connectBlock uniqueIdentifier:local.uniqueIdentifier];
+    return [[MTRDeviceController alloc] initWithParameters:xpcParams error:error];
+}
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
+{
+    newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MTRXPCServerProtocol)];
+    newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MTRXPCClientProtocol)];
+
+    auto server = [[XPCServerImpl alloc] initWithClientProxy:[newConnection remoteObjectProxy] controllers:_controllers];
+    newConnection.exportedObject = server;
+
+    newConnection.interruptionHandler = ^{
+        ChipLogProgress(chipTool, "XPC connection interrupted");
+    };
+
+    newConnection.invalidationHandler = ^{
+        ChipLogProgress(chipTool, "XPC connection invalidated");
+    };
+
+    [newConnection resume];
+    return YES;
+}
+@end
+
+@interface XPCServerWithServiceName : NSObject <XPCServerExternalCertificateParametersWithServiceNameProtocol>
+@end
+
+@implementation XPCServerWithServiceName
+- (void)start
+{
+}
+
+- (void)stop
+{
+}
+
+- (MTRDeviceController *)createController:(NSString *)controllerID serviceName:(NSString *)serviceName error:(NSError * __autoreleasing *)error
+{
+    __auto_type connectBlock = ^NSXPCConnection *
+    {
+#if TARGET_OS_OSX
+        return [[NSXPCConnection alloc] initWithMachServiceName:serviceName options:0];
+#else
+        ChipLogError(chipTool, "NSXPCConnection::initWithMachServiceName is not supported on this platform.");
+        return nil;
+#endif // TARGET_OS_OSX
+    };
+    __auto_type * uniqueIdentifier = [[NSUUID alloc] initWithUUIDString:controllerID];
+    __auto_type * xpcParams = [[MTRXPCDeviceControllerParameters alloc] initWithXPConnectionBlock:connectBlock uniqueIdentifier:uniqueIdentifier];
+    return [[MTRDeviceController alloc] initWithParameters:xpcParams error:error];
+}
+@end
diff --git a/examples/darwin-framework-tool/commands/common/xpc/XPCServerProtocols.h b/examples/darwin-framework-tool/commands/common/xpc/XPCServerProtocols.h
new file mode 100644
index 0000000..e713bdb
--- /dev/null
+++ b/examples/darwin-framework-tool/commands/common/xpc/XPCServerProtocols.h
@@ -0,0 +1,44 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#import <Matter/Matter.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol XPCServerBaseProtocol <NSObject>
+- (void)start;
+- (void)stop;
+@end
+
+@protocol XPCServerExternalCertificateParametersProtocol <XPCServerBaseProtocol, NSXPCListenerDelegate>
+- (MTRDeviceController *)createController:(MTRDeviceControllerExternalCertificateParameters *)params error:(NSError * __autoreleasing *)error;
+@end
+
+@protocol XPCServerStartupParametersProtocol <XPCServerBaseProtocol, NSXPCListenerDelegate>
+- (MTRDeviceController *)createController:(MTRDeviceControllerStartupParams *)params error:(NSError * __autoreleasing *)error;
+@end
+
+@protocol XPCServerExternalCertificateParametersWithServiceNameProtocol <XPCServerBaseProtocol>
+- (MTRDeviceController *)createController:(NSString *)controllerID serviceName:(NSString *)serviceName error:(NSError * __autoreleasing *)error;
+@end
+
+@protocol XPCServerStartupParametersWithServiceNameProtocol <XPCServerBaseProtocol>
+- (MTRDeviceController *)createController:(NSString *)controllerID serviceName:(NSString *)serviceName error:(NSError * __autoreleasing *)error;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.h b/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.h
new file mode 100644
index 0000000..1b77728
--- /dev/null
+++ b/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.h
@@ -0,0 +1,33 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#import <Matter/Matter.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface XPCServerRegistry : NSObject
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
++ (XPCServerRegistry *)sharedInstance;
+
+- (void)start;
+- (void)stop;
+- (MTRDeviceController *)createController:(NSString * _Nullable)controllerId serviceName:(NSString * _Nullable)serviceName params:(id)params error:(NSError * __autoreleasing *)error;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.mm b/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.mm
new file mode 100644
index 0000000..3e873f3
--- /dev/null
+++ b/examples/darwin-framework-tool/commands/common/xpc/XPCServerRegistry.mm
@@ -0,0 +1,113 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#import "XPCServerRegistry.h"
+
+#import "XPCServerProtocols.h"
+#import <objc/runtime.h>
+
+@interface XPCServerRegistry ()
+@property (strong, nonatomic) NSMutableArray<id<XPCServerBaseProtocol>> * servers;
+@end
+
+@implementation XPCServerRegistry
+- (instancetype)init
+{
+    if ((self = [super init])) {
+        _servers = [NSMutableArray new];
+    }
+
+    return self;
+}
+
++ (XPCServerRegistry *)sharedInstance
+{
+    static XPCServerRegistry * registry = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        registry = [[XPCServerRegistry alloc] init];
+    });
+    return registry;
+}
+
+- (void)start
+{
+    if (@available(macOS 13.0, *)) {
+        objc_enumerateClasses(nil, nil, @protocol(XPCServerBaseProtocol), nil, ^(Class cls, BOOL * stop) {
+            id server = [[cls alloc] init];
+            [_servers addObject:server];
+        });
+    } else {
+        int numClasses = objc_getClassList(NULL, 0);
+        if (numClasses > 0) {
+            __auto_type * classes = (__unsafe_unretained Class *) malloc(sizeof(Class) * static_cast<size_t>(numClasses));
+            numClasses = objc_getClassList(classes, numClasses);
+
+            for (int i = 0; i < numClasses; i++) {
+                id cls = classes[i];
+                if (class_conformsToProtocol(cls, @protocol(XPCServerBaseProtocol))) {
+                    id server = [[cls alloc] init];
+                    [_servers addObject:server];
+                }
+            }
+            free(classes); // Free the allocated memory
+        }
+    }
+
+    for (id<XPCServerBaseProtocol> server in _servers) {
+        [server start];
+    }
+}
+
+- (void)stop
+{
+    for (id<XPCServerBaseProtocol> server in _servers) {
+        [server stop];
+    }
+}
+
+- (MTRDeviceController *)createController:(NSString * _Nullable)controllerId serviceName:(NSString * _Nullable)serviceName params:(id)params error:(NSError * __autoreleasing *)error
+{
+    BOOL isExternalCertificateParameters = [params isKindOfClass:[MTRDeviceControllerExternalCertificateParameters class]];
+    BOOL isStartupParameters = [params isKindOfClass:[MTRDeviceControllerStartupParams class]];
+    for (id server in _servers) {
+        if (controllerId && serviceName) {
+            if ([server conformsToProtocol:@protocol(XPCServerExternalCertificateParametersWithServiceNameProtocol)] && isExternalCertificateParameters) {
+                return [server createController:controllerId serviceName:serviceName error:error];
+            }
+
+            if ([server conformsToProtocol:@protocol(XPCServerStartupParametersWithServiceNameProtocol)] && isStartupParameters) {
+                return [server createController:controllerId serviceName:serviceName error:error];
+            }
+        } else {
+            if ([server conformsToProtocol:@protocol(XPCServerExternalCertificateParametersProtocol)] && isExternalCertificateParameters) {
+                return [server createController:params error:error];
+            }
+
+            if ([server conformsToProtocol:@protocol(XPCServerStartupParametersProtocol)] && isStartupParameters) {
+                return [server createController:params error:error];
+            }
+        }
+    }
+
+    __auto_type * userInfo = @{ NSLocalizedDescriptionKey : @"No XPC servers support this configuration." };
+    *error = [NSError errorWithDomain:@"Error" code:0 userInfo:userInfo];
+    return nil;
+}
+
+@end
diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
index 16ed12a..702f853 100644
--- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
+++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
@@ -436,12 +436,17 @@
 		B45374002A9FEC4F00807602 /* unix-init.c in Sources */ = {isa = PBXBuildFile; fileRef = B45373F92A9FEC4F00807602 /* unix-init.c */; settings = {COMPILER_FLAGS = "-Wno-error -Wno-unreachable-code -Wno-conversion -Wno-format-nonliteral"; }; };
 		B45374012A9FEC4F00807602 /* unix-sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = B45373FA2A9FEC4F00807602 /* unix-sockets.c */; settings = {COMPILER_FLAGS = "-Wno-error -Wno-unreachable-code -Wno-conversion -Wno-format-nonliteral"; }; };
 		B4C8E6B72B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm */; };
+		B4D67A3B2D00DAB700C49965 /* XPCServerRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D67A382D00DAB700C49965 /* XPCServerRegistry.h */; };
+		B4D67A3C2D00DAB700C49965 /* XPCServerRegistry.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A392D00DAB700C49965 /* XPCServerRegistry.mm */; };
+		B4D67A3D2D00DAB700C49965 /* DeviceControllerServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A362D00DAB700C49965 /* DeviceControllerServer.mm */; };
+		B4D67A3E2D00DAB700C49965 /* XPCServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A372D00DAB700C49965 /* XPCServer.mm */; };
 		B4D67A412D00DD3D00C49965 /* DFTKeypair.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D67A3F2D00DD3D00C49965 /* DFTKeypair.h */; };
 		B4D67A422D00DD3D00C49965 /* DFTKeypair.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A402D00DD3D00C49965 /* DFTKeypair.mm */; };
 		B4D67A922D527F4A00C49965 /* DCLClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */; };
 		B4D67A932D527F4A00C49965 /* DisplayTermsAndConditions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */; };
 		B4D67A952D527F4A00C49965 /* JsonSchemaMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */; };
 		B4D67A9B2D538E9700C49965 /* HTTPSRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A992D538E9700C49965 /* HTTPSRequest.mm */; };
+		B4D67A462D07021700C49965 /* XPCServerProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D67A452D07021700C49965 /* XPCServerProtocols.h */; };
 		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 */; };
@@ -998,12 +1003,17 @@
 		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 = "<group>"; };
 		B4C8E6B32B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDiagnosticLogsDownloader.h; sourceTree = "<group>"; };
 		B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDiagnosticLogsDownloader.mm; sourceTree = "<group>"; };
+		B4D67A362D00DAB700C49965 /* DeviceControllerServer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceControllerServer.mm; sourceTree = "<group>"; };
+		B4D67A372D00DAB700C49965 /* XPCServer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = XPCServer.mm; sourceTree = "<group>"; };
+		B4D67A382D00DAB700C49965 /* XPCServerRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPCServerRegistry.h; sourceTree = "<group>"; };
+		B4D67A392D00DAB700C49965 /* XPCServerRegistry.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = XPCServerRegistry.mm; sourceTree = "<group>"; };
 		B4D67A3F2D00DD3D00C49965 /* DFTKeypair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DFTKeypair.h; sourceTree = "<group>"; };
 		B4D67A402D00DD3D00C49965 /* DFTKeypair.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DFTKeypair.mm; sourceTree = "<group>"; };
 		B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DCLClient.cpp; path = commands/dcl/DCLClient.cpp; sourceTree = "<group>"; };
 		B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayTermsAndConditions.cpp; path = commands/dcl/DisplayTermsAndConditions.cpp; sourceTree = "<group>"; };
 		B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JsonSchemaMacros.cpp; path = commands/dcl/JsonSchemaMacros.cpp; sourceTree = "<group>"; };
 		B4D67A992D538E9700C49965 /* HTTPSRequest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HTTPSRequest.mm; sourceTree = "<group>"; };
+		B4D67A452D07021700C49965 /* XPCServerProtocols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPCServerProtocols.h; sourceTree = "<group>"; };
 		B4E262122AA0C7A300DBA5BC /* RemoteDataModelLogger.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteDataModelLogger.mm; sourceTree = "<group>"; };
 		B4E262132AA0C7A300DBA5BC /* RemoteDataModelLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteDataModelLogger.h; sourceTree = "<group>"; };
 		B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SleepCommand.mm; sourceTree = "<group>"; };
@@ -1171,6 +1181,7 @@
 			children = (
 				B4D67A3F2D00DD3D00C49965 /* DFTKeypair.h */,
 				B4D67A402D00DD3D00C49965 /* DFTKeypair.mm */,
+				B4D67A3A2D00DAB700C49965 /* xpc */,
 				B409D0AC2CCFB89600A7ED5A /* DeviceDelegate.h */,
 				B409D0AD2CCFB89600A7ED5A /* DeviceDelegate.mm */,
 				B43B39EF2CB99090006AA284 /* CertificateIssuer.h */,
@@ -1889,6 +1900,18 @@
 			path = dcl;
 			sourceTree = "<group>";
 		};
+		B4D67A3A2D00DAB700C49965 /* xpc */ = {
+			isa = PBXGroup;
+			children = (
+				B4D67A452D07021700C49965 /* XPCServerProtocols.h */,
+				B4D67A362D00DAB700C49965 /* DeviceControllerServer.mm */,
+				B4D67A372D00DAB700C49965 /* XPCServer.mm */,
+				B4D67A382D00DAB700C49965 /* XPCServerRegistry.h */,
+				B4D67A392D00DAB700C49965 /* XPCServerRegistry.mm */,
+			);
+			path = xpc;
+			sourceTree = "<group>";
+		};
 		B4E262182AA0CFFE00DBA5BC /* delay */ = {
 			isa = PBXGroup;
 			children = (
@@ -1976,6 +1999,7 @@
 				B43B39EC2CB859A5006AA284 /* DumpMemoryGraphCommand.h in Headers */,
 				B43B39ED2CB859A5006AA284 /* Commands.h in Headers */,
 				B43B39EE2CB859A5006AA284 /* LeaksTool.h in Headers */,
+				B4D67A462D07021700C49965 /* XPCServerProtocols.h in Headers */,
 				7534D17E2CF8CE2000F64654 /* DefaultAttributePersistenceProvider.h in Headers */,
 				037C3DBD2991BD5000B7EEE2 /* OTAProviderDelegate.h in Headers */,
 				B4FCD5702B603A6300832859 /* Commands.h in Headers */,
@@ -1985,6 +2009,7 @@
 				037C3DCB2991BD5100B7EEE2 /* CHIPCommandStorageDelegate.h in Headers */,
 				037C3DD32991BD5200B7EEE2 /* logging.h in Headers */,
 				037C3DB72991BD5000B7EEE2 /* ModelCommandBridge.h in Headers */,
+				B4D67A3B2D00DAB700C49965 /* XPCServerRegistry.h in Headers */,
 				037C3DC52991BD5100B7EEE2 /* StorageManagementCommand.h in Headers */,
 				037C3DCC2991BD5100B7EEE2 /* MTRError_Utils.h in Headers */,
 				7592BD002CBEE98C00EB74A0 /* Instance.h in Headers */,
@@ -2379,6 +2404,9 @@
 				75A202E62BA8DBAC00A771DD /* reporting.cpp in Sources */,
 				039145E82993179300257B3E /* GetCommissionerNodeIdCommand.mm in Sources */,
 				0395469F2991DFC5006D42A8 /* json_reader.cpp in Sources */,
+				B4D67A3C2D00DAB700C49965 /* XPCServerRegistry.mm in Sources */,
+				B4D67A3D2D00DAB700C49965 /* DeviceControllerServer.mm in Sources */,
+				B4D67A3E2D00DAB700C49965 /* XPCServer.mm in Sources */,
 				514C79F42B62ED5500DD6D7B /* attribute-storage.cpp in Sources */,
 				0395469E2991DFC5006D42A8 /* json_writer.cpp in Sources */,
 				B4D67A422D00DD3D00C49965 /* DFTKeypair.mm in Sources */,