Skip to content

Commit

Permalink
Piggyback darwin attribute cache subscription (#16534)
Browse files Browse the repository at this point in the history
* Piggyback CHIPAttributeCacheContainer on CHIPDevice subscription
  instead of using a dedicated subscription.
  • Loading branch information
kpark-apple authored and pull[bot] committed Jul 14, 2023
1 parent a61efd0 commit 4097116
Show file tree
Hide file tree
Showing 14 changed files with 358 additions and 422 deletions.
12 changes: 4 additions & 8 deletions src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
51E0310027EA20D20083DC9C /* CHIPControllerAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E030FE27EA20D20083DC9C /* CHIPControllerAccessControl.h */; };
51E0310127EA20D20083DC9C /* CHIPControllerAccessControl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51E030FF27EA20D20083DC9C /* CHIPControllerAccessControl.mm */; };
51E24E73274E0DAC007CCF6E /* CHIPErrorTestUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51E24E72274E0DAC007CCF6E /* CHIPErrorTestUtils.mm */; };
5A60370827EA1FF60020DB79 /* CHIPAttributeCacheContainer+XPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A60370727EA1FF60020DB79 /* CHIPAttributeCacheContainer+XPC.h */; };
5A6FEC9027B563D900F25F42 /* CHIPDeviceControllerOverXPC.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A6FEC8F27B563D900F25F42 /* CHIPDeviceControllerOverXPC.m */; };
5A6FEC9227B5669C00F25F42 /* CHIPDeviceControllerOverXPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6FEC8D27B5624E00F25F42 /* CHIPDeviceControllerOverXPC.h */; };
5A6FEC9627B5983000F25F42 /* CHIPDeviceControllerXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A6FEC9527B5983000F25F42 /* CHIPDeviceControllerXPCConnection.m */; };
Expand All @@ -54,9 +55,7 @@
5A7947DE27BEC3F500434CF2 /* CHIPXPCListenerSampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A7947DD27BEC3F500434CF2 /* CHIPXPCListenerSampleTests.m */; };
5A7947E427C0129600434CF2 /* CHIPDeviceController+XPC.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A7947E327C0129500434CF2 /* CHIPDeviceController+XPC.m */; };
5A7947E527C0129F00434CF2 /* CHIPDeviceController+XPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A7947E227C0101200434CF2 /* CHIPDeviceController+XPC.h */; settings = {ATTRIBUTES = (Public, ); }; };
5A830D6A27CFCB640053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A830D6927CFCB570053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.h */; };
5A830D6C27CFCF590053B85D /* CHIPDeviceControllerOverXPC_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A830D6B27CFCF590053B85D /* CHIPDeviceControllerOverXPC_Internal.h */; };
5A830D6E27CFCFF90053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A830D6D27CFCFF90053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.m */; };
5ACDDD7A27CD129700EFD68A /* CHIPAttributeCacheContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5ACDDD7927CD129700EFD68A /* CHIPAttributeCacheContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
5ACDDD7D27CD16D200EFD68A /* CHIPAttributeCacheContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5ACDDD7C27CD16D200EFD68A /* CHIPAttributeCacheContainer.mm */; };
5ACDDD7E27CD3F3A00EFD68A /* CHIPAttributeCacheContainer_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5ACDDD7B27CD14AF00EFD68A /* CHIPAttributeCacheContainer_Internal.h */; };
Expand Down Expand Up @@ -138,6 +137,7 @@
51E030FE27EA20D20083DC9C /* CHIPControllerAccessControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPControllerAccessControl.h; sourceTree = "<group>"; };
51E030FF27EA20D20083DC9C /* CHIPControllerAccessControl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPControllerAccessControl.mm; sourceTree = "<group>"; };
51E24E72274E0DAC007CCF6E /* CHIPErrorTestUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPErrorTestUtils.mm; sourceTree = "<group>"; };
5A60370727EA1FF60020DB79 /* CHIPAttributeCacheContainer+XPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CHIPAttributeCacheContainer+XPC.h"; sourceTree = "<group>"; };
5A6FEC8B27B5609C00F25F42 /* CHIPDeviceOverXPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPDeviceOverXPC.h; sourceTree = "<group>"; };
5A6FEC8D27B5624E00F25F42 /* CHIPDeviceControllerOverXPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPDeviceControllerOverXPC.h; sourceTree = "<group>"; };
5A6FEC8F27B563D900F25F42 /* CHIPDeviceControllerOverXPC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CHIPDeviceControllerOverXPC.m; sourceTree = "<group>"; };
Expand All @@ -148,9 +148,7 @@
5A7947DD27BEC3F500434CF2 /* CHIPXPCListenerSampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CHIPXPCListenerSampleTests.m; sourceTree = "<group>"; };
5A7947E227C0101200434CF2 /* CHIPDeviceController+XPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CHIPDeviceController+XPC.h"; sourceTree = "<group>"; };
5A7947E327C0129500434CF2 /* CHIPDeviceController+XPC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CHIPDeviceController+XPC.m"; sourceTree = "<group>"; };
5A830D6927CFCB570053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CHIPDeviceControllerOverXPC+AttributeCache.h"; sourceTree = "<group>"; };
5A830D6B27CFCF590053B85D /* CHIPDeviceControllerOverXPC_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPDeviceControllerOverXPC_Internal.h; sourceTree = "<group>"; };
5A830D6D27CFCFF90053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CHIPDeviceControllerOverXPC+AttributeCache.m"; sourceTree = "<group>"; };
5ACDDD7927CD129700EFD68A /* CHIPAttributeCacheContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPAttributeCacheContainer.h; sourceTree = "<group>"; };
5ACDDD7B27CD14AF00EFD68A /* CHIPAttributeCacheContainer_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPAttributeCacheContainer_Internal.h; sourceTree = "<group>"; };
5ACDDD7C27CD16D200EFD68A /* CHIPAttributeCacheContainer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPAttributeCacheContainer.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -278,6 +276,7 @@
2C222ACF255C620600E446B9 /* CHIPDevice.mm */,
2C8C8FBE253E0C2100797F05 /* CHIPPersistentStorageDelegate.h */,
5ACDDD7927CD129700EFD68A /* CHIPAttributeCacheContainer.h */,
5A60370727EA1FF60020DB79 /* CHIPAttributeCacheContainer+XPC.h */,
5ACDDD7B27CD14AF00EFD68A /* CHIPAttributeCacheContainer_Internal.h */,
5ACDDD7C27CD16D200EFD68A /* CHIPAttributeCacheContainer.mm */,
997DED152695343400975E97 /* CHIPThreadOperationalDataset.mm */,
Expand Down Expand Up @@ -315,8 +314,6 @@
5A6FEC8D27B5624E00F25F42 /* CHIPDeviceControllerOverXPC.h */,
5A830D6B27CFCF590053B85D /* CHIPDeviceControllerOverXPC_Internal.h */,
5A6FEC8F27B563D900F25F42 /* CHIPDeviceControllerOverXPC.m */,
5A830D6927CFCB570053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.h */,
5A830D6D27CFCFF90053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.m */,
5A6FEC9427B5976200F25F42 /* CHIPDeviceControllerXPCConnection.h */,
5A6FEC9527B5983000F25F42 /* CHIPDeviceControllerXPCConnection.m */,
);
Expand Down Expand Up @@ -375,6 +372,7 @@
997DED182695344800975E97 /* CHIPThreadOperationalDataset.h in Headers */,
9956064426420367000C28DE /* CHIPSetupPayload_Internal.h in Headers */,
5A830D6C27CFCF590053B85D /* CHIPDeviceControllerOverXPC_Internal.h in Headers */,
5A60370827EA1FF60020DB79 /* CHIPAttributeCacheContainer+XPC.h in Headers */,
5ACDDD7E27CD3F3A00EFD68A /* CHIPAttributeCacheContainer_Internal.h in Headers */,
998F286D26D55E10001846C6 /* CHIPKeypair.h in Headers */,
1ED276E426C5832500547A89 /* CHIPCluster.h in Headers */,
Expand All @@ -385,7 +383,6 @@
1EC4CE6425CC276600D7304F /* CHIPClustersObjc.h in Headers */,
2C5EEEF6268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h in Headers */,
2C8C8FC0253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h in Headers */,
5A830D6A27CFCB640053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.h in Headers */,
998F286F26D55EC5001846C6 /* CHIPP256KeypairBridge.h in Headers */,
2C222ADF255C811800E446B9 /* CHIPDevice_Internal.h in Headers */,
51E0310027EA20D20083DC9C /* CHIPControllerAccessControl.h in Headers */,
Expand Down Expand Up @@ -546,7 +543,6 @@
B2E0D7B6245B0B5C003C5B48 /* CHIPManualSetupPayloadParser.mm in Sources */,
5A6FEC9827B5C6AF00F25F42 /* CHIPDeviceOverXPC.m in Sources */,
51431AF927D2973E008A7943 /* CHIPIMDispatch.mm in Sources */,
5A830D6E27CFCFF90053B85D /* CHIPDeviceControllerOverXPC+AttributeCache.m in Sources */,
51431AFB27D29CA4008A7943 /* ota-provider.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,14 @@

#import <Foundation/Foundation.h>

#import "CHIPDeviceControllerOverXPC.h"
#import "CHIPAttributeCacheContainer.h"

NS_ASSUME_NONNULL_BEGIN

@class CHIPSubscribeParams;

@interface CHIPDeviceControllerOverXPC (AttributeCache)

- (void)subscribeAttributeCacheWithNodeId:(uint64_t)nodeId
params:(CHIPSubscribeParams * _Nullable)params
completion:(void (^)(NSError * _Nullable error))completion;

- (void)readAttributeCacheWithNodeId:(uint64_t)nodeId
endpointId:(NSNumber * _Nullable)endpointId
clusterId:(NSNumber * _Nullable)clusterId
attributeId:(NSNumber * _Nullable)attributeId
completion:(void (^)(id _Nullable values, NSError * _Nullable error))completion;

@interface CHIPAttributeCacheContainer (XPC)
- (void)setXPCConnection:(CHIPDeviceControllerXPCConnection *)xpcConnection
controllerId:(id<NSCopying>)controllerId
deviceId:(uint64_t)deviceId;
@end

NS_ASSUME_NONNULL_END
15 changes: 0 additions & 15 deletions src/darwin/Framework/CHIP/CHIPAttributeCacheContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface CHIPAttributeCacheContainer : NSObject

/**
* Subscribes to all attributes to update attribute cache.
*
* @param deviceController device controller to retrieve connected device from
* @param deviceId device identifier of the device to cache attributes of
* @param params subscription parameters
* @param clientQueue client queue to dispatch the completion handler through
* @param completion completion handler
*/
- (void)subscribeWithDeviceController:(CHIPDeviceController *)deviceController
deviceId:(uint64_t)deviceId
params:(CHIPSubscribeParams * _Nullable)params
clientQueue:(dispatch_queue_t)clientQueue
completion:(void (^)(NSError * _Nullable error))completion;

/**
* Reads an attribute with specific attribute path
*
Expand Down
155 changes: 36 additions & 119 deletions src/darwin/Framework/CHIP/CHIPAttributeCacheContainer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#import "CHIPAttributeCacheContainer_Internal.h"
#import "CHIPCluster.h"
#import "CHIPDeviceControllerOverXPC+AttributeCache.h"
#import "CHIPDeviceControllerXPCConnection.h"
#import "CHIPDevice_Internal.h"
#import "CHIPError.h"
#import "CHIPError_Internal.h"
Expand All @@ -31,123 +31,25 @@

using namespace chip;

void ContainerAttributeCacheCallback::OnDone()
{
dispatch_async(DeviceLayer::PlatformMgrImpl().GetWorkQueue(), ^{
CHIPAttributeCacheContainer * container = attributeCacheContainer;
if (container) {
CHIP_LOG_ERROR("Attribute cache read client done for device %llu", container.deviceId);
if (container.cppReadClient) {
delete container.cppReadClient;
container.cppReadClient = nullptr;
}
if (container.cppAttributeCache) {
delete container.cppAttributeCache;
container.cppAttributeCache = nullptr;
}
} else {
CHIP_LOG_ERROR("Attribute cache read client done for a released cache container");
}
});
}

@implementation CHIPAttributeCacheContainer

- (instancetype)init
{
if ([super init]) {
_cppAttributeCache = nullptr;
_cppReadClient = nullptr;
_attributeCacheCallback = new ContainerAttributeCacheCallback;
if (_attributeCacheCallback) {
_attributeCacheCallback->SetContainer(self);
}
_shouldUseXPC = NO;
}
return self;
}

- (void)dealloc
{
if (_cppReadClient) {
delete _cppReadClient;
}
if (_cppAttributeCache) {
delete _cppAttributeCache;
}
if (_attributeCacheCallback) {
delete _attributeCacheCallback;
}
}

- (void)subscribeWithDeviceController:(CHIPDeviceController *)deviceController
deviceId:(uint64_t)deviceId
params:(CHIPSubscribeParams * _Nullable)params
clientQueue:clientQueue
completion:(void (^)(NSError * _Nullable error))completion
- (void)setXPCConnection:(CHIPDeviceControllerXPCConnection *)xpcConnection
controllerId:(id<NSCopying>)controllerId
deviceId:(uint64_t)deviceId
{
__auto_type workQueue = DeviceLayer::PlatformMgrImpl().GetWorkQueue();
__auto_type completionHandler = ^(NSError * _Nullable error) {
dispatch_async(clientQueue, ^{
completion(error);
});
};
if ([deviceController isKindOfClass:[CHIPDeviceControllerOverXPC class]]) {
self.deviceId = deviceId;
CHIPDeviceControllerOverXPC * xpcDeviceController = (CHIPDeviceControllerOverXPC *) deviceController;
self.xpcDeviceController = xpcDeviceController;
[xpcDeviceController subscribeAttributeCacheWithNodeId:deviceId params:params completion:completionHandler];
return;
}
[deviceController
getConnectedDevice:deviceId
queue:workQueue
completionHandler:^(CHIPDevice * _Nullable device, NSError * _Nullable error) {
if (error) {
CHIP_LOG_ERROR("Error: Failed to get connected device (%llu) for attribute cache: %@", deviceId, error);
completionHandler(error);
return;
}
if (self.cppReadClient) {
delete self.cppReadClient;
self.cppReadClient = nullptr;
}
if (self.cppAttributeCache) {
delete self.cppAttributeCache;
}
self.cppAttributeCache = new app::AttributeCache(*self.attributeCacheCallback);
if (!self.cppAttributeCache) {
CHIP_LOG_ERROR("Error: Failed to allocate attribute cache for device %llu", deviceId);
completionHandler([NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeGeneralError userInfo:nil]);
return;
}

__auto_type engine = app::InteractionModelEngine::GetInstance();
__auto_type readClient = new app::ReadClient(engine, [device internalDevice]->GetExchangeManager(),
self.cppAttributeCache->GetBufferedCallback(), app::ReadClient::InteractionType::Subscribe);
if (!readClient) {
CHIP_LOG_ERROR("Error: Failed to allocate attribute cache read client for device %llu", deviceId);
completionHandler([NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeGeneralError userInfo:nil]);
return;
}
self.deviceId = deviceId;
app::ReadPrepareParams readParams([device internalDevice]->GetSecureSession().Value());
static app::AttributePathParams attributePath;
readParams.mpAttributePathParamsList = &attributePath;
readParams.mAttributePathParamsListSize = 1;
readParams.mMaxIntervalCeilingSeconds = 43200;
readParams.mIsFabricFiltered = (params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
readParams.mKeepSubscriptions
= (params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
__auto_type err = readClient->SendAutoResubscribeRequest(std::move(readParams));
if (err != CHIP_NO_ERROR) {
CHIP_LOG_ERROR("Error: attribute cache subscription failed for device %llu: %s", deviceId, ErrorStr(err));
completionHandler([NSError errorWithDomain:CHIPErrorDomain code:err.AsInteger() userInfo:nil]);
return;
}
self.cppReadClient = readClient;
CHIP_LOG_DEBUG("Attribute cache subscription succeeded for device %llu", deviceId);
completionHandler(nil);
}];
self.xpcConnection = xpcConnection;
self.xpcControllerId = controllerId;
self.deviceId = deviceId;
self.shouldUseXPC = YES;
}

static CHIP_ERROR AppendAttibuteValueToArray(
Expand Down Expand Up @@ -189,21 +91,36 @@ - (void)readAttributeWithEndpointId:(NSNumber * _Nullable)endpointId
});
};

if (self.xpcDeviceController) {
CHIPDeviceControllerOverXPC * strongController = self.xpcDeviceController;
if (strongController) {
[strongController
readAttributeCacheWithNodeId:self.deviceId
endpointId:endpointId
clusterId:clusterId
attributeId:attributeId
completion:(void (^)(id _Nullable values, NSError * _Nullable error)) completionHandler];
} else {
CHIP_LOG_ERROR("Reading attribute cache failed when associated device controller is deleted");
completionHandler(nil, [NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeGeneralError userInfo:nil]);
if (self.shouldUseXPC) {
CHIPDeviceControllerXPCConnection * xpcConnection = self.xpcConnection;
if (!xpcConnection) {
CHIP_LOG_ERROR("Attribute cache read failed: CHIPDeviceController was already disposed");
completion(nil, [NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeGeneralError userInfo:nil]);
return;
}
__auto_type controllerId = self.xpcControllerId;
uint64_t nodeId = self.deviceId;
[xpcConnection getProxyHandleWithCompletion:^(
dispatch_queue_t _Nonnull queue, CHIPDeviceControllerXPCProxyHandle * _Nullable handle) {
if (handle) {
[handle.proxy readAttributeCacheWithController:controllerId
nodeId:nodeId
endpointId:endpointId
clusterId:clusterId
attributeId:attributeId
completion:^(id _Nullable values, NSError * _Nullable error) {
completion([CHIPDeviceController decodeXPCResponseValues:values], error);
__auto_type handleRetainer = handle;
(void) handleRetainer;
}];
} else {
CHIP_LOG_ERROR("Attribute cache read failed due to XPC connection failure");
completion(nil, [NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeGeneralError userInfo:nil]);
}
}];
return;
}

dispatch_async(DeviceLayer::PlatformMgrImpl().GetWorkQueue(), ^{
if (endpointId == nil && clusterId == nil) {
CHIP_LOG_ERROR("Error: currently read from attribute cache does not support wildcards for both endpoint and cluster");
Expand Down
Loading

0 comments on commit 4097116

Please sign in to comment.