diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index ea98603f196f81..de7c0fcb4e3693 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -292,9 +292,25 @@ extern NSString * const MTRArrayValueType; @end -@interface MTRAttributePath : NSObject +/** + * A path indicating a specific cluster on a device (i.e. without any + * wildcards). + */ +@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 @@ -305,9 +321,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 clusterID:(NSNumber *)clusterID eventID:(NSNumber *)eventID; @@ -316,9 +335,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 clusterID:(NSNumber *)clusterID commandID:(NSNumber *)commandID; diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 3447e7351260e2..b3e8c1f463f8f5 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1453,12 +1453,63 @@ + (id)CHIPEncodeAndDecodeNSObject:(id)object @end -@implementation MTRAttributePath -- (instancetype)initWithPath:(const ConcreteDataAttributePath &)path +@interface MTRClusterPath () +- (instancetype)initWithPath:(const ConcreteClusterPath &)path; +@end + +@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; @@ -1467,7 +1518,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]; } @@ -1484,8 +1535,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 @@ -1498,21 +1548,19 @@ - (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 @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; @@ -1528,16 +1576,14 @@ 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 @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; @@ -1553,7 +1599,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