Skip to content

Commit

Permalink
[Darwin] Add XPC mechanism for MTRDevice and MTRDeviceController with…
Browse files Browse the repository at this point in the history
… parameters
  • Loading branch information
jtung-apple committed Jan 24, 2024
1 parent a8df984 commit 858b8e6
Show file tree
Hide file tree
Showing 20 changed files with 2,007 additions and 22 deletions.
8 changes: 4 additions & 4 deletions src/darwin/Framework/CHIP/MTRBaseDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0))
* wildcards).
*/
MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
@interface MTRClusterPath : NSObject <NSCopying>
@interface MTRClusterPath : NSObject <NSCopying, NSSecureCoding>
@property (nonatomic, readonly, copy) NSNumber * endpoint;
@property (nonatomic, readonly, copy) NSNumber * cluster;

Expand All @@ -564,7 +564,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
* A path indicating a specific attribute on a device (i.e. without any
* wildcards).
*/
@interface MTRAttributePath : MTRClusterPath
@interface MTRAttributePath : MTRClusterPath <NSSecureCoding>
@property (nonatomic, readonly, copy) NSNumber * attribute;

+ (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID
Expand All @@ -578,7 +578,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
* (i.e. without any wildcards). There can be multiple instances of actual
* events for a given event path.
*/
@interface MTREventPath : MTRClusterPath
@interface MTREventPath : MTRClusterPath <NSSecureCoding>
@property (nonatomic, readonly, copy) NSNumber * event;

+ (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID
Expand All @@ -590,7 +590,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4))
* A path indicating a specific command on a device (i.e. without any
* wildcards).
*/
@interface MTRCommandPath : MTRClusterPath
@interface MTRCommandPath : MTRClusterPath <NSSecureCoding>
@property (nonatomic, readonly, copy) NSNumber * command;

+ (MTRCommandPath *)commandPathWithEndpointID:(NSNumber *)endpointID
Expand Down
123 changes: 123 additions & 0 deletions src/darwin/Framework/CHIP/MTRBaseDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,42 @@ - (id)copyWithZone:(NSZone *)zone
return [MTRClusterPath clusterPathWithEndpointID:_endpoint clusterID:_cluster];
}

static NSString * const sEndpointKey = @"endpointKey";
static NSString * const sClusterKey = @"endpointKey";

+ (BOOL)supportsSecureCoding
{
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self == nil) {
return nil;
}

_endpoint = [decoder decodeObjectOfClass:[NSNumber class] forKey:sEndpointKey];
if (_endpoint && ![_endpoint isKindOfClass:[NSNumber class]]) {
MTR_LOG_ERROR("MTRClusterPath got %@ for endpoint, not NSNumber.", _endpoint);
return nil;
}

_cluster = [decoder decodeObjectOfClass:[NSNumber class] forKey:sClusterKey];
if (_cluster && ![_cluster isKindOfClass:[NSNumber class]]) {
MTR_LOG_ERROR("MTRClusterPath got %@ for cluster, not NSNumber.", _cluster);
return nil;
}

return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_endpoint forKey:sEndpointKey];
[coder encodeObject:_cluster forKey:sClusterKey];
}

@end

@implementation MTRAttributePath
Expand Down Expand Up @@ -2462,6 +2498,35 @@ - (ConcreteAttributePath)_asConcretePath
return ConcreteAttributePath([self.endpoint unsignedShortValue], static_cast<ClusterId>([self.cluster unsignedLongValue]),
static_cast<AttributeId>([self.attribute unsignedLongValue]));
}

static NSString * const sAttributeKey = @"attributeKey";

+ (BOOL)supportsSecureCoding
{
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self == nil) {
return nil;
}

_attribute = [decoder decodeObjectOfClass:[NSNumber class] forKey:sAttributeKey];
if (_attribute && ![_attribute isKindOfClass:[NSNumber class]]) {
MTR_LOG_ERROR("MTRAttributePath got %@ for attribute, not NSNumber.", _attribute);
return nil;
}

return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_attribute forKey:sAttributeKey];
}

@end

@implementation MTRAttributePath (Deprecated)
Expand Down Expand Up @@ -2525,6 +2590,35 @@ - (ConcreteEventPath)_asConcretePath
return ConcreteEventPath([self.endpoint unsignedShortValue], static_cast<ClusterId>([self.cluster unsignedLongValue]),
static_cast<EventId>([self.event unsignedLongValue]));
}

static NSString * const sEventKey = @"eventKey";

+ (BOOL)supportsSecureCoding
{
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self == nil) {
return nil;
}

_event = [decoder decodeObjectOfClass:[NSNumber class] forKey:sEventKey];
if (_event && ![_event isKindOfClass:[NSNumber class]]) {
MTR_LOG_ERROR("MTRAttributePath got %@ for event, not NSNumber.", _event);
return nil;
}

return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_event forKey:sEventKey];
}

@end

@implementation MTREventPath (Deprecated)
Expand Down Expand Up @@ -2580,6 +2674,35 @@ - (id)copyWithZone:(NSZone *)zone
{
return [MTRCommandPath commandPathWithEndpointID:self.endpoint clusterID:self.cluster commandID:_command];
}

static NSString * const sCommandKey = @"commandKey";

+ (BOOL)supportsSecureCoding
{
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self == nil) {
return nil;
}

_command = [decoder decodeObjectOfClass:[NSNumber class] forKey:sCommandKey];
if (_command && ![_command isKindOfClass:[NSNumber class]]) {
MTR_LOG_ERROR("MTRAttributePath got %@ for command, not NSNumber.", _command);
return nil;
}

return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_command forKey:sCommandKey];
}

@end

@implementation MTRCommandPath (Deprecated)
Expand Down
39 changes: 26 additions & 13 deletions src/darwin/Framework/CHIP/MTRDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#import "MTRError_Internal.h"
#import "MTREventTLVValueDecoder_Internal.h"
#import "MTRLogging_Internal.h"
#import "MTRRemoteDevice.h"
#import "MTRRemoteDeviceController.h"
#import "zap-generated/MTRCommandPayloads_Internal.h"

#include "lib/core/CHIPError.h"
Expand All @@ -48,13 +50,6 @@
// Consider moving utility classes to their own file
#pragma mark - Utility Classes
// This class is for storing weak references in a container
MTR_HIDDEN
@interface MTRWeakReference<ObjectType> : NSObject
+ (instancetype)weakReferenceWithObject:(ObjectType)object;
- (instancetype)initWithObject:(ObjectType)object;
- (ObjectType)strongObject; // returns strong object or NULL
@end

@interface MTRWeakReference () {
@private
__weak id _object;
Expand Down Expand Up @@ -142,8 +137,6 @@ typedef NS_ENUM(NSUInteger, MTRDeviceWorkItemDuplicateTypeID) {
@interface MTRDevice ()
@property (nonatomic, readonly) os_unfair_lock lock; // protects the caches and device state
@property (nonatomic) chip::FabricIndex fabricIndex;
@property (nonatomic) MTRWeakReference<id<MTRDeviceDelegate>> * weakDelegate;
@property (nonatomic) dispatch_queue_t delegateQueue;
@property (nonatomic) NSMutableArray<NSDictionary<NSString *, id> *> * unreportedEvents;
@property (nonatomic) BOOL receivingReport;
@property (nonatomic) BOOL receivingPrimingReport;
Expand Down Expand Up @@ -251,8 +244,6 @@ + (MTRDevice *)deviceWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControll

- (void)setDelegate:(id<MTRDeviceDelegate>)delegate queue:(dispatch_queue_t)queue
{
MTR_LOG_INFO("%@ setDelegate %@", self, delegate);

BOOL setUpSubscription = YES;

// For unit testing only
Expand All @@ -263,6 +254,13 @@ - (void)setDelegate:(id<MTRDeviceDelegate>)delegate queue:(dispatch_queue_t)queu
}
#endif

[self setDelegate:delegate queue:queue setUpSubscription:setUpSubscription];
}

- (void)setDelegate:(id<MTRDeviceDelegate>)delegate queue:(dispatch_queue_t)queue setUpSubscription:(BOOL)setUpSubscription
{
MTR_LOG_INFO("%@ setDelegate %@", self, delegate);

os_unfair_lock_lock(&self->_lock);

_weakDelegate = [MTRWeakReference weakReferenceWithObject:delegate];
Expand Down Expand Up @@ -423,7 +421,7 @@ - (void)_handleSubscriptionReset
}

MTR_LOG_DEFAULT("%@ scheduling to reattempt subscription in %u seconds", self, _lastSubscriptionAttemptWait);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (_lastSubscriptionAttemptWait * NSEC_PER_SEC)), self.queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_lastSubscriptionAttemptWait * NSEC_PER_SEC)), self.queue, ^{
os_unfair_lock_lock(&self->_lock);
[self _reattemptSubscriptionNowIfNeeded];
os_unfair_lock_unlock(&self->_lock);
Expand Down Expand Up @@ -1422,7 +1420,7 @@ - (void)_checkExpiredExpectedValues
waitTime = MTR_DEVICE_EXPIRATION_CHECK_TIMER_MINIMUM_WAIT_TIME;
}
MTRWeakReference<MTRDevice *> * weakSelf = [MTRWeakReference weakReferenceWithObject:self];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (waitTime * NSEC_PER_SEC)), self.queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), self.queue, ^{
MTRDevice * strongSelf = weakSelf.strongObject;
[strongSelf _performScheduledExpirationCheck];
});
Expand Down Expand Up @@ -1728,6 +1726,21 @@ - (void)_removeExpectedValueForAttributePath:(MTRAttributePath *)attributePath e
}
}

- (NSArray<NSDictionary *> *)getAllCurrentAttributes
{
os_unfair_lock_lock(&self->_lock);

NSMutableArray * attributesToReport = [NSMutableArray array];
for (MTRAttributePath * attributePath in _readCache) {
NSDictionary * dataValue = _readCache[attributePath];
[attributesToReport addObject:@{ MTRAttributePathKey : attributePath, MTRDataKey : dataValue }];
}
MTR_LOG_INFO("%@ getAllCurrentAttributes reporting %lu values", self, attributesToReport.count);

os_unfair_lock_unlock(&self->_lock);
return attributesToReport;
}

- (MTRBaseDevice *)newBaseDevice
{
return [MTRBaseDevice deviceWithNodeID:self.nodeID controller:self.deviceController];
Expand Down
17 changes: 17 additions & 0 deletions src/darwin/Framework/CHIP/MTRDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#import <Matter/MTRDefines.h>

#if MTR_PER_CONTROLLER_STORAGE_ENABLED
#import "MTRRemoteDeviceController_Internal.h"
#import <Matter/MTRDeviceControllerParameters.h>
#import <Matter/MTRRemoteDeviceControllerParameters.h>
#else
#import "MTRDeviceControllerParameters_Wrapper.h"
#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED
Expand Down Expand Up @@ -123,8 +125,23 @@ @implementation MTRDeviceController {
MTRAttestationTrustStoreBridge * _attestationTrustStoreBridge;
}

- (nullable instancetype)initWithUniqueIdentifier:(NSUUID *)uniqueIdentifier
{
if (self = [super init]) {
_uniqueIdentifier = uniqueIdentifier;
}
return self;
}

- (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error
{
if ([parameters isKindOfClass:[MTRRemoteDeviceControllerParameters class]]) {
MTRRemoteDeviceControllerParameters * xpcParameters = (MTRRemoteDeviceControllerParameters *) parameters;

MTRRemoteDeviceController * remoteController = [[MTRRemoteDeviceController alloc] initWithParameters:xpcParameters error:error];
return remoteController;
}

if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) {
MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters);

Expand Down
12 changes: 12 additions & 0 deletions src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "MTRDeviceController_Internal.h"
#import "MTRLogging_Internal.h"
#import "MTRP256KeypairBridge.h"
#import "MTRRemoteDeviceControllerParameters.h"
#import "NSDataSpanConversion.h"

#if MTR_PER_CONTROLLER_STORAGE_ENABLED
Expand Down Expand Up @@ -308,6 +309,17 @@ - (void)setOTAProviderDelegate:(id<MTROTAProviderDelegate>)otaProviderDelegate q

@end

@implementation MTRRemoteDeviceControllerParameters
- (instancetype)initWithXPCServiceName:(NSString *)xpcServiceName uniqueIdentifier:(NSUUID *)uniqueIdentifier
{
if (self = [super _initInternal]) {
_xpcServiceName = xpcServiceName;
_uniqueIdentifier = uniqueIdentifier;
}
return self;
}
@end

@implementation MTRDeviceControllerExternalCertificateParameters
- (instancetype)initWithStorageDelegate:(id<MTRDeviceControllerStorageDelegate>)storageDelegate
storageDelegateQueue:(dispatch_queue_t)storageDelegateQueue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#import <Matter/MTRDeviceController.h>
#if MTR_PER_CONTROLLER_STORAGE_ENABLED
#import <Matter/MTRDeviceControllerParameters.h>
#import <Matter/MTRRemoteDeviceControllerParameters.h>
#else
#import "MTRDeviceControllerParameters_Wrapper.h"
#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED
Expand Down Expand Up @@ -91,6 +92,10 @@ NS_ASSUME_NONNULL_BEGIN

@end

@interface MTRRemoteDeviceControllerParameters ()
@property (nonatomic, strong, readonly) NSString * xpcServiceName;
@end

MTR_HIDDEN
@interface MTRDeviceControllerStartupParamsInternal : MTRDeviceControllerStartupParams

Expand Down
2 changes: 2 additions & 0 deletions src/darwin/Framework/CHIP/MTRDeviceController_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ NS_ASSUME_NONNULL_BEGIN
otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue
uniqueIdentifier:(NSUUID *)uniqueIdentifier;

- (nullable instancetype)initWithUniqueIdentifier:(NSUUID *)uniqueIdentifier;

/**
* Check whether this controller is running on the given fabric, as represented
* by the provided FabricTable and fabric index. The provided fabric table may
Expand Down
Loading

0 comments on commit 858b8e6

Please sign in to comment.