From 3ecb0839745fd36ab6b7d5ec4a8531b694cecb87 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 4 Nov 2022 12:35:05 -0400 Subject: [PATCH] Add a common base for Darwin MTR*Path interfaces. (#23490) This is a re-landing of PR #22591. This change should be backwards-compatible with the existing API. --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 36 ++++++++-- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 72 +++++++++++++++---- .../Framework/CHIP/MTRBaseDevice_Internal.h | 4 ++ 3 files changed, 90 insertions(+), 22 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index e92b774bc988ed..1ed9b586e2e7bd 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -298,9 +298,26 @@ extern NSString * const MTRArrayValueType; @end -@interface MTRAttributePath : NSObject +/** + * A path indicating a specific cluster on a device (i.e. without any + * wildcards). + */ +MTR_NEWLY_AVAILABLE +@interface MTRClusterPath : NSObject @property (nonatomic, readonly, copy) NSNumber * endpoint; @property (nonatomic, readonly, copy) NSNumber * cluster; + ++ (instancetype)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +@end + +/** + * A path indicating a specific attribute on a device (i.e. without any + * wildcards). + */ +@interface MTRAttributePath : MTRClusterPath @property (nonatomic, readonly, copy) NSNumber * attribute; + (instancetype)attributePathWithEndpointID:(NSNumber *)endpointID @@ -311,9 +328,12 @@ extern NSString * const MTRArrayValueType; + (instancetype)new NS_UNAVAILABLE; @end -@interface MTREventPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * endpoint; -@property (nonatomic, readonly, copy) NSNumber * cluster; +/** + * A path indicating a specific event that can be emitted on a device + * (i.e. without any wildcards). There can be multiple instances of actual + * events for a given event path. + */ +@interface MTREventPath : MTRClusterPath @property (nonatomic, readonly, copy) NSNumber * event; + (instancetype)eventPathWithEndpointID:(NSNumber *)endpointID @@ -324,9 +344,11 @@ extern NSString * const MTRArrayValueType; + (instancetype)new NS_UNAVAILABLE; @end -@interface MTRCommandPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * endpoint; -@property (nonatomic, readonly, copy) NSNumber * cluster; +/** + * A path indicating a specific command on a device (i.e. without any + * wildcards). + */ +@interface MTRCommandPath : MTRClusterPath @property (nonatomic, readonly, copy) NSNumber * command; + (instancetype)commandPathWithEndpointID:(NSNumber *)endpointID diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0b41d2c3435a30..fbc709e4294990 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1558,12 +1558,59 @@ - (void)deregisterReportHandlersWithClientQueue:(dispatch_queue_t)queue completi @end -@implementation MTRAttributePath -- (instancetype)initWithPath:(const ConcreteDataAttributePath &)path +@implementation MTRClusterPath +- (instancetype)initWithPath:(const ConcreteClusterPath &)path { if (self = [super init]) { _endpoint = @(path.mEndpointId); _cluster = @(path.mClusterId); + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@" endpoint %u cluster %u", (uint16_t) _endpoint.unsignedShortValue, + (uint32_t) _cluster.unsignedLongValue]; +} + ++ (instancetype)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID +{ + ConcreteClusterPath path(static_cast([endpointID unsignedShortValue]), + static_cast([clusterID unsignedLongValue])); + + return [[MTRClusterPath alloc] initWithPath:path]; +} + +- (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath +{ + return [_endpoint isEqualToNumber:clusterPath.endpoint] && [_cluster isEqualToNumber:clusterPath.cluster]; +} + +- (BOOL)isEqual:(id)object +{ + if (![object isKindOfClass:[self class]]) { + return NO; + } + return [self isEqualToClusterPath:object]; +} + +- (NSUInteger)hash +{ + return _endpoint.unsignedShortValue ^ _cluster.unsignedLongValue; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [MTRClusterPath clusterPathWithEndpointID:_endpoint clusterID:_cluster]; +} + +@end + +@implementation MTRAttributePath +- (instancetype)initWithPath:(const ConcreteDataAttributePath &)path +{ + if (self = [super initWithPath:path]) { _attribute = @(path.mAttributeId); } return self; @@ -1572,7 +1619,7 @@ - (instancetype)initWithPath:(const ConcreteDataAttributePath &)path - (NSString *)description { return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", - (uint16_t) _endpoint.unsignedShortValue, (uint32_t) _cluster.unsignedLongValue, + (uint16_t) self.endpoint.unsignedShortValue, (uint32_t) self.cluster.unsignedLongValue, (uint32_t) _attribute.unsignedLongValue]; } @@ -1589,8 +1636,7 @@ ConcreteDataAttributePath path(static_cast([endpointID unsigne - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath { - return [_endpoint isEqualToNumber:attributePath.endpoint] && [_cluster isEqualToNumber:attributePath.cluster] && - [_attribute isEqualToNumber:attributePath.attribute]; + return [self isEqualToClusterPath:attributePath] && [_attribute isEqualToNumber:attributePath.attribute]; } - (BOOL)isEqual:(id)object @@ -1603,12 +1649,12 @@ - (BOOL)isEqual:(id)object - (NSUInteger)hash { - return _endpoint.unsignedShortValue ^ _cluster.unsignedLongValue ^ _attribute.unsignedLongValue; + return self.endpoint.unsignedShortValue ^ self.cluster.unsignedLongValue ^ _attribute.unsignedLongValue; } - (id)copyWithZone:(NSZone *)zone { - return [MTRAttributePath attributePathWithEndpointID:_endpoint clusterID:_cluster attributeID:_attribute]; + return [MTRAttributePath attributePathWithEndpointID:self.endpoint clusterID:self.cluster attributeID:_attribute]; } @end @@ -1624,9 +1670,7 @@ + (instancetype)attributePathWithEndpointId:(NSNumber *)endpointId @implementation MTREventPath - (instancetype)initWithPath:(const ConcreteEventPath &)path { - if (self = [super init]) { - _endpoint = @(path.mEndpointId); - _cluster = @(path.mClusterId); + if (self = [super initWithPath:path]) { _event = @(path.mEventId); } return self; @@ -1642,7 +1686,7 @@ ConcreteEventPath path(static_cast([endpointID unsignedShortVa - (id)copyWithZone:(NSZone *)zone { - return [MTREventPath eventPathWithEndpointID:_endpoint clusterID:_cluster eventID:_event]; + return [MTREventPath eventPathWithEndpointID:self.endpoint clusterID:self.cluster eventID:_event]; } @end @@ -1656,9 +1700,7 @@ + (instancetype)eventPathWithEndpointId:(NSNumber *)endpointId clusterId:(NSNumb @implementation MTRCommandPath - (instancetype)initWithPath:(const ConcreteCommandPath &)path { - if (self = [super init]) { - _endpoint = @(path.mEndpointId); - _cluster = @(path.mClusterId); + if (self = [super initWithPath:path]) { _command = @(path.mCommandId); } return self; @@ -1674,7 +1716,7 @@ ConcreteCommandPath path(static_cast([endpointID unsignedShort - (id)copyWithZone:(NSZone *)zone { - return [MTRCommandPath commandPathWithEndpointID:_endpoint clusterID:_cluster commandID:_command]; + return [MTRCommandPath commandPathWithEndpointID:self.endpoint clusterID:self.cluster commandID:_command]; } @end diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 7c3219fca1531b..2f874547e6948b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -71,6 +71,10 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRClusterPath () +- (instancetype)initWithPath:(const chip::app::ConcreteClusterPath &)path; +@end + @interface MTRAttributePath () - (instancetype)initWithPath:(const chip::app::ConcreteDataAttributePath &)path; @end