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 */,