Skip to content

Commit

Permalink
Darwin: Tidy up some device type meta-data classes
Browse files Browse the repository at this point in the history
- Move MTRDeviceTypeRevision out of ServerEndpoint directory
- Move MTRProductIdentity into its own file
- Implement NSCopying and equality on MTRDeviceType and MTRProductIdentity
- Implement description on all 3 types
- Add tests
  • Loading branch information
ksperling-apple committed Dec 19, 2024
1 parent ef5f838 commit 0abedfb
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 36 deletions.
20 changes: 5 additions & 15 deletions src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@

NS_ASSUME_NONNULL_BEGIN

@class MTRDeviceController;
@class MTRDeviceTypeRevision;
@class MTRMetrics;
@class MTRProductIdentity;

typedef NS_ENUM(NSInteger, MTRCommissioningStatus) {
MTRCommissioningStatusUnknown = 0,
MTRCommissioningStatusSuccess = 1,
Expand All @@ -29,21 +34,6 @@ typedef NS_ENUM(NSInteger, MTRCommissioningStatus) {
= 3,
} MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4));

/**
* A representation of a (vendor, product) pair that identifies a specific product.
*/
MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0))
@interface MTRProductIdentity : NSObject

@property (nonatomic, copy, readonly) NSNumber * vendorID;

@property (nonatomic, copy, readonly) NSNumber * productID;

- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID;
@end

@class MTRDeviceController;
@class MTRMetrics;

/**
* The protocol definition for the MTRDeviceControllerDelegate.
Expand Down
9 changes: 8 additions & 1 deletion src/darwin/Framework/CHIP/MTRDeviceType.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@

NS_ASSUME_NONNULL_BEGIN

/**
* Meta-data about a device type defined in the Matter specification.
*/
MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2))
@interface MTRDeviceType : NSObject
@interface MTRDeviceType : NSObject /* <NSCopying> (see below) */

/**
* Returns an MTRDeviceType for the given ID, if the ID is known. Returns nil
Expand Down Expand Up @@ -52,4 +55,8 @@ MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2))

@end

MTR_NEWLY_AVAILABLE
@interface MTRDeviceType () <NSCopying>
@end

NS_ASSUME_NONNULL_END
44 changes: 35 additions & 9 deletions src/darwin/Framework/CHIP/MTRDeviceType.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@

#import <Matter/MTRDeviceType.h>

#import "MTRDefines_Internal.h"
#import "MTRDeviceTypeMetadata.h"
#import "MTRLogging_Internal.h"

#include <lib/support/SafeInt.h>
#include <lib/support/CodeUtils.h>

using namespace chip;

MTR_DIRECT_MEMBERS
@implementation MTRDeviceType

- (nullable instancetype)initWithDeviceTypeID:(NSNumber *)id name:(NSString *)name isUtility:(BOOL)isUtility
- (instancetype)initWithDeviceTypeID:(NSNumber *)id name:(NSString *)name isUtility:(BOOL)isUtility
{
if (!(self = [super init])) {
return nil;
}

self = [super init];
_id = id;
_name = name;
_isUtility = isUtility;
Expand All @@ -50,10 +50,36 @@ + (nullable MTRDeviceType *)deviceTypeForID:(NSNumber *)deviceTypeID
return nil;
}

return [[MTRDeviceType alloc]
initWithDeviceTypeID:deviceTypeID
name:[NSString stringWithUTF8String:deviceTypeData->name]
isUtility:(deviceTypeData->deviceClass != MTRDeviceTypeClass::Simple)];
auto * name = [[NSString alloc] initWithBytesNoCopy:(void *)deviceTypeData->name
length:strlen(deviceTypeData->name)
encoding:NSUTF8StringEncoding freeWhenDone:NO];

return [[MTRDeviceType alloc] initWithDeviceTypeID:deviceTypeID
name:name
isUtility:(deviceTypeData->deviceClass != MTRDeviceTypeClass::Simple)];
}

- (id)copyWithZone:(NSZone *)zone
{
return self; // immutable
}

- (NSUInteger)hash
{
return _id.hash;
}

- (BOOL)isEqual:(id)object
{
VerifyOrReturnValue([object class] == [self class], NO);
MTRDeviceType * other = object;
return [_id isEqual:other->_id];
}

- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ 0x%" PRIx32 " (%@)>",
self.class, _id.unsignedIntValue, _name];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#import <Foundation/Foundation.h>
#import <Matter/MTRDefines.h>

@class MTRDescriptorClusterDeviceTypeStruct;
@class MTRDeviceType;

NS_ASSUME_NONNULL_BEGIN

/**
Expand All @@ -38,9 +41,20 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6))
*/
- (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision;

/**
* Initializes the receiver based on the values in the specified struct.
*/
- (nullable instancetype)initWithDeviceTypeStruct:(MTRDescriptorClusterDeviceTypeStruct *)deviceTypeStruct MTR_NEWLY_AVAILABLE;

@property (nonatomic, copy, readonly) NSNumber * deviceTypeID;
@property (nonatomic, copy, readonly) NSNumber * deviceTypeRevision;

/**
* Returns the MTRDeviceType corresponding to deviceTypeID,
* or nil if deviceTypeID does not represent a known device type.
*/
@property (nonatomic, copy, readonly, nullable) MTRDeviceType * typeInformation MTR_NEWLY_AVAILABLE;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
* limitations under the License.
*/

#import "MTRDeviceTypeRevision.h"
#import "MTRDefines_Internal.h"
#import "MTRDeviceType.h"
#import "MTRLogging_Internal.h"
#import <Matter/MTRDeviceTypeRevision.h>
#import "MTRStructsObjc.h"

#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>

using namespace chip;
Expand All @@ -29,6 +32,9 @@ @implementation MTRDeviceTypeRevision

- (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision
{
VerifyOrReturnValue(deviceTypeID != nil, nil);
VerifyOrReturnValue(revision != nil, nil);

auto deviceTypeIDValue = deviceTypeID.unsignedLongLongValue;
if (!CanCastTo<DeviceTypeId>(deviceTypeIDValue)) {
MTR_LOG_ERROR("MTRDeviceTypeRevision provided too-large device type ID: 0x%llx", deviceTypeIDValue);
Expand All @@ -50,19 +56,26 @@ - (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision:
return [self initInternalWithDeviceTypeID:[deviceTypeID copy] revision:[revision copy]];
}

- (instancetype)initWithDeviceTypeStruct:(MTRDescriptorClusterDeviceTypeStruct *)deviceTypeStruct
{
return [self initWithDeviceTypeID:deviceTypeStruct.deviceType revision:deviceTypeStruct.revision];
}

// initInternalWithDeviceTypeID:revision assumes that the device type ID and device
// revision have already been validated and, if needed, copied from the input.
- (instancetype)initInternalWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision
{
if (!(self = [super init])) {
return nil;
}

self = [super init];
_deviceTypeID = deviceTypeID;
_deviceTypeRevision = revision;
return self;
}

- (MTRDeviceType *)typeInformation
{
return [MTRDeviceType deviceTypeForID:_deviceTypeID];
}

- (id)copyWithZone:(NSZone *)zone
{
// We have no mutable state.
Expand All @@ -85,4 +98,11 @@ - (NSUInteger)hash
return _deviceTypeID.unsignedLongValue ^ _deviceTypeRevision.unsignedShortValue;
}

- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ 0x%" PRIx32 " (%@) rev %d>",
self.class, _deviceTypeID.unsignedIntValue,
self.typeInformation.name ?: @"???", _deviceTypeRevision.unsignedIntValue];
}

@end
41 changes: 41 additions & 0 deletions src/darwin/Framework/CHIP/MTRProductIdentity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2024 Project CHIP Authors
*
* 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/MTRDefines.h>

NS_ASSUME_NONNULL_BEGIN

/**
* A representation of a (vendor, product) pair that identifies a specific product.
*/
MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0))
@interface MTRProductIdentity : NSObject /* <NSCopying> (see below) */

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID;

@property (nonatomic, copy, readonly) NSNumber * vendorID;
@property (nonatomic, copy, readonly) NSNumber * productID;

@end

MTR_NEWLY_AVAILABLE
@interface MTRProductIdentity () <NSCopying>
@end

NS_ASSUME_NONNULL_END
58 changes: 58 additions & 0 deletions src/darwin/Framework/CHIP/MTRProductIdentity.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2024 Project CHIP Authors
*
* 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 "MTRProductIdentity.h"

#import "MTRDefines_Internal.h"
#import "MTRUtilities.h"

#include <lib/support/CodeUtils.h>

MTR_DIRECT_MEMBERS
@implementation MTRProductIdentity

- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID
{
self = [super init];
VerifyOrReturnValue(vendorID != nil && productID != nil, nil);
_vendorID = vendorID;
_productID = productID;
return self;
}

- (id)copyWithZone:(NSZone *)zone
{
return self; // immutable
}

- (NSUInteger)hash
{
return _vendorID.hash ^ _productID.hash;
}

- (BOOL)isEqual:(id)object
{
VerifyOrReturnValue([object class] == [self class], NO);
MTRProductIdentity * other = object;
return MTREqualObjects(_vendorID, other.vendorID) && MTREqualObjects(_productID, other.productID);
}

- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: vid 0x%u pid 0x%u>", self.class, _vendorID.unsignedIntValue, _productID.unsignedIntValue];
}

@end
1 change: 1 addition & 0 deletions src/darwin/Framework/CHIP/Matter.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#import <Matter/MTROTAProviderDelegate.h>
#import <Matter/MTROnboardingPayloadParser.h>
#import <Matter/MTROperationalCertificateIssuer.h>
#import <Matter/MTRProductIdentity.h>
#import <Matter/MTRQRCodeSetupPayloadParser.h>
#import <Matter/MTRServerAttribute.h>
#import <Matter/MTRServerCluster.h>
Expand Down
Loading

0 comments on commit 0abedfb

Please sign in to comment.