Skip to content

Commit cac7ccd

Browse files
Darwin: Address various MTRSetupPayload issues
API: - Conform to NSCopying and implement isEqual / hash - Simplify a number of methods to not return NSError - Add initWithPayload: as a replacement for setupPayloadWithOnboardingPayload:error: - Add initWithQRCode: and initWithManualPairingCode: for cases where payload type is known. - Add vendorElements as a replacement for getAllOptionalVendorData: - Add vendorElementWithTag: - Add removeVendorElementWithTag: - Add addOrReplaceVendorElement: Behaviour fixes: - Allow QRCodes with unknown discovery methods to be parsed - Include vendor elements in qrCodeString - Preserve vendor elements encodeWithCoder / initWithCoder Also simplify the implementation by acting as a direct wrapper of chip::SetupPayload. Implement parsing in MTRSetupPayload directly and implement the deprecated MTR*PayloadParser classes in terms of it, instead of the other way around.
1 parent 4594d4e commit cac7ccd

14 files changed

+873
-490
lines changed

src/darwin/Framework/CHIP/MTRDefines_Internal.h

+4
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,9 @@
5858
typedef struct {} variable_hidden_by_mtr_hide;
5959
// clang-format on
6060

61+
// mtr_[un]likely(expr): Evaluates a boolean expression and hints to the compiler that it is [un]likely to be true.
62+
#define mtr_likely(expr) __builtin_expect(!!(expr), 1)
63+
#define mtr_unlikely(expr) __builtin_expect(!!(expr), 0)
64+
6165
// Default timed interaction timeout, in ms, if another one is not provided.
6266
#define MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS 10000

src/darwin/Framework/CHIP/MTRError.mm

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#import "MTRError.h"
2121
#import "MTRError_Internal.h"
22+
#import "MTRLogging_Internal.h"
2223

2324
#import <app/MessageDef/StatusIB.h>
2425
#import <inet/InetError.h>
@@ -43,6 +44,11 @@ - (instancetype)initWithError:(CHIP_ERROR)error;
4344

4445
@implementation MTRError
4546

47+
+ (NSError *)errorWithCode:(MTRErrorCode)code
48+
{
49+
return [NSError errorWithDomain:MTRErrorDomain code:code userInfo:nil];
50+
}
51+
4652
+ (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode
4753
{
4854
return [MTRError errorForCHIPErrorCode:errorCode logContext:nil];
@@ -337,3 +343,9 @@ - (instancetype)initWithError:(CHIP_ERROR)error
337343
}
338344

339345
@end
346+
347+
void MTRThrowInvalidArgument(NSString * reason)
348+
{
349+
MTR_LOG_ERROR("Invalid argument: %@", reason);
350+
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
351+
}

src/darwin/Framework/CHIP/MTRError_Internal.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,34 @@
1616
*/
1717

1818
#import <Foundation/Foundation.h>
19-
#import <Matter/MTRDefines.h>
2019
#import <Matter/MTRError.h>
2120

21+
#import "MTRDefines_Internal.h"
22+
2223
#include <app/MessageDef/StatusIB.h>
2324
#include <lib/core/CHIPError.h>
2425
#include <protocols/interaction_model/StatusCode.h>
2526

2627
NS_ASSUME_NONNULL_BEGIN
2728

29+
MTR_DIRECT_MEMBERS
2830
@interface MTRError : NSObject
31+
+ (NSError *)errorWithCode:(MTRErrorCode)code;
2932
+ (NSError * _Nullable)errorForCHIPErrorCode:(CHIP_ERROR)errorCode;
3033
+ (NSError * _Nullable)errorForCHIPErrorCode:(CHIP_ERROR)errorCode logContext:(id _Nullable)contextToLog;
3134
+ (NSError * _Nullable)errorForIMStatus:(const chip::app::StatusIB &)status;
3235
+ (NSError * _Nullable)errorForIMStatusCode:(chip::Protocols::InteractionModel::Status)status;
3336
+ (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error;
3437
@end
3538

39+
// Similar to VerifyOrDie, but throws an NSInvalidArgumentException
40+
#define MTRVerifyArgumentOrDie(cond, reason) \
41+
do { \
42+
if (mtr_unlikely(!(cond))) { \
43+
MTRThrowInvalidArgument(reason); \
44+
} \
45+
} while (0)
46+
47+
MTR_EXTERN _Noreturn void MTRThrowInvalidArgument(NSString * reason);
48+
3649
NS_ASSUME_NONNULL_END

src/darwin/Framework/CHIP/MTRManualSetupPayloadParser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
NS_ASSUME_NONNULL_BEGIN
2323

24-
MTR_DEPRECATED("Please use [MTRSetupPayload setupPayloadWithOnboardingPayload:error:]", ios(16.1, 16.4), macos(13.0, 13.3),
24+
MTR_DEPRECATED("Please use -[MTRSetupPayload initWithManualPairingCode:]", ios(16.1, 16.4), macos(13.0, 13.3),
2525
watchos(9.1, 9.4), tvos(16.1, 16.4))
2626
@interface MTRManualSetupPayloadParser : NSObject
2727
- (instancetype)initWithDecimalStringRepresentation:(NSString *)decimalStringRepresentation;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
*
3-
* Copyright (c) 2020 Project CHIP Authors
3+
* Copyright (c) 2020-2024 Project CHIP Authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -14,56 +14,30 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
1718
#import "MTRManualSetupPayloadParser.h"
1819

1920
#import "MTRError_Internal.h"
20-
#import "MTRFramework.h"
21-
#import "MTRLogging_Internal.h"
22-
#import "MTRSetupPayload_Internal.h"
23-
24-
#import <setup_payload/ManualSetupPayloadParser.h>
25-
#import <setup_payload/SetupPayload.h>
26-
27-
#include <string>
21+
#import "MTRSetupPayload.h"
2822

2923
@implementation MTRManualSetupPayloadParser {
3024
NSString * _decimalStringRepresentation;
31-
chip::ManualSetupPayloadParser * _chipManualSetupPayloadParser;
32-
}
33-
34-
+ (void)initialize
35-
{
36-
MTRFrameworkInit();
3725
}
3826

3927
- (id)initWithDecimalStringRepresentation:(NSString *)decimalStringRepresentation
4028
{
41-
if (self = [super init]) {
42-
_decimalStringRepresentation = decimalStringRepresentation;
43-
_chipManualSetupPayloadParser = new chip::ManualSetupPayloadParser(std::string([decimalStringRepresentation UTF8String]));
44-
}
29+
self = [super init];
30+
_decimalStringRepresentation = decimalStringRepresentation;
4531
return self;
4632
}
4733

4834
- (MTRSetupPayload *)populatePayload:(NSError * __autoreleasing *)error
4935
{
50-
chip::SetupPayload cPlusPluspayload;
51-
MTRSetupPayload * payload;
52-
53-
CHIP_ERROR chipError = _chipManualSetupPayloadParser->populatePayload(cPlusPluspayload);
54-
if (chipError == CHIP_NO_ERROR) {
55-
payload = [[MTRSetupPayload alloc] initWithSetupPayload:cPlusPluspayload];
56-
} else if (error) {
57-
*error = [MTRError errorForCHIPErrorCode:chipError];
36+
MTRSetupPayload * payload = [[MTRSetupPayload alloc] initWithManualPairingCode:_decimalStringRepresentation];
37+
if (!payload && error) {
38+
*error = [MTRError errorWithCode:MTRErrorCodeInvalidArgument];
5839
}
59-
6040
return payload;
6141
}
6242

63-
- (void)dealloc
64-
{
65-
delete _chipManualSetupPayloadParser;
66-
_chipManualSetupPayloadParser = nullptr;
67-
}
68-
6943
@end

src/darwin/Framework/CHIP/MTROnboardingPayloadParser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef NS_ENUM(NSUInteger, MTROnboardingPayloadType) {
2828
MTROnboardingPayloadTypeNFC
2929
} MTR_DEPRECATED("MTROnboardingPayloadType is unused", ios(16.1, 17.0), macos(13.0, 14.0), watchos(9.1, 10.0), tvos(16.1, 17.0));
3030

31-
MTR_DEPRECATED("Please use [MTRSetupPayload setupPayloadWithOnboardingPayload:error:]", ios(16.1, 17.0), macos(13.0, 14.0),
31+
MTR_DEPRECATED("Please use [MTRSetupPayload initWithPayload:]", ios(16.1, 17.0), macos(13.0, 14.0),
3232
watchos(9.1, 10.0), tvos(16.1, 17.0))
3333
@interface MTROnboardingPayloadParser : NSObject
3434

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
*
3-
* Copyright (c) 2020 Project CHIP Authors
3+
* Copyright (c) 2020-2024 Project CHIP Authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,50 +16,15 @@
1616
*/
1717

1818
#import "MTROnboardingPayloadParser.h"
19-
#import "MTRManualSetupPayloadParser.h"
20-
#import "MTRQRCodeSetupPayloadParser.h"
19+
2120
#import "MTRSetupPayload.h"
2221

2322
@implementation MTROnboardingPayloadParser
2423

25-
+ (bool)isQRCode:(NSString *)codeString
26-
{
27-
return [codeString hasPrefix:@"MT:"];
28-
}
29-
3024
+ (MTRSetupPayload * _Nullable)setupPayloadForOnboardingPayload:(NSString *)onboardingPayload
3125
error:(NSError * __autoreleasing *)error
3226
{
33-
MTRSetupPayload * payload;
34-
// MTROnboardingPayloadTypeNFC is of type QR code and handled same as QR code
35-
MTROnboardingPayloadType type =
36-
[self isQRCode:onboardingPayload] ? MTROnboardingPayloadTypeQRCode : MTROnboardingPayloadTypeManualCode;
37-
switch (type) {
38-
case MTROnboardingPayloadTypeManualCode:
39-
payload = [self setupPayloadForManualCodeOnboardingPayload:onboardingPayload error:error];
40-
break;
41-
case MTROnboardingPayloadTypeQRCode:
42-
payload = [self setupPayloadForQRCodeOnboardingPayload:onboardingPayload error:error];
43-
break;
44-
default:
45-
break;
46-
}
47-
return payload;
27+
return [MTRSetupPayload setupPayloadWithOnboardingPayload:onboardingPayload error:error];
4828
}
4929

50-
+ (MTRSetupPayload * _Nullable)setupPayloadForQRCodeOnboardingPayload:(NSString *)onboardingPayload
51-
error:(NSError * __autoreleasing *)error
52-
{
53-
MTRQRCodeSetupPayloadParser * qrCodeParser =
54-
[[MTRQRCodeSetupPayloadParser alloc] initWithBase38Representation:onboardingPayload];
55-
return [qrCodeParser populatePayload:error];
56-
}
57-
58-
+ (MTRSetupPayload * _Nullable)setupPayloadForManualCodeOnboardingPayload:(NSString *)onboardingPayload
59-
error:(NSError * __autoreleasing *)error
60-
{
61-
MTRManualSetupPayloadParser * manualParser =
62-
[[MTRManualSetupPayloadParser alloc] initWithDecimalStringRepresentation:onboardingPayload];
63-
return [manualParser populatePayload:error];
64-
}
6530
@end

src/darwin/Framework/CHIP/MTRQRCodeSetupPayloadParser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
NS_ASSUME_NONNULL_BEGIN
2323

24-
MTR_DEPRECATED("Please use [MTRSetupPayload setupPayloadWithOnboardingPayload:error:]", ios(16.1, 16.4), macos(13.0, 13.3),
24+
MTR_DEPRECATED("Please use [MTRSetupPayload -initWithQRCode:]", ios(16.1, 16.4), macos(13.0, 13.3),
2525
watchos(9.1, 9.4), tvos(16.1, 16.4))
2626
@interface MTRQRCodeSetupPayloadParser : NSObject
2727
- (instancetype)initWithBase38Representation:(NSString *)base38Representation;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
*
3-
* Copyright (c) 2020 Project CHIP Authors
3+
* Copyright (c) 2020-2024 Project CHIP Authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,54 +16,28 @@
1616
*/
1717

1818
#import "MTRQRCodeSetupPayloadParser.h"
19-
#import "MTRError_Internal.h"
20-
#import "MTRFramework.h"
21-
#import "MTRLogging_Internal.h"
22-
#import "MTRSetupPayload_Internal.h"
23-
24-
#import <setup_payload/QRCodeSetupPayloadParser.h>
25-
#import <setup_payload/SetupPayload.h>
2619

27-
#include <string>
20+
#import "MTRError_Internal.h"
21+
#import "MTRSetupPayload.h"
2822

2923
@implementation MTRQRCodeSetupPayloadParser {
3024
NSString * _base38Representation;
31-
chip::QRCodeSetupPayloadParser * _chipQRCodeSetupPayloadParser;
32-
}
33-
34-
+ (void)initialize
35-
{
36-
MTRFrameworkInit();
3725
}
3826

3927
- (id)initWithBase38Representation:(NSString *)base38Representation
4028
{
41-
if (self = [super init]) {
42-
_base38Representation = base38Representation;
43-
_chipQRCodeSetupPayloadParser = new chip::QRCodeSetupPayloadParser(std::string([base38Representation UTF8String]));
44-
}
29+
self = [super init];
30+
_base38Representation = base38Representation;
4531
return self;
4632
}
4733

4834
- (MTRSetupPayload *)populatePayload:(NSError * __autoreleasing *)error
4935
{
50-
chip::SetupPayload cPlusPluspayload;
51-
MTRSetupPayload * payload;
52-
53-
CHIP_ERROR chipError = _chipQRCodeSetupPayloadParser->populatePayload(cPlusPluspayload);
54-
if (chipError == CHIP_NO_ERROR) {
55-
payload = [[MTRSetupPayload alloc] initWithSetupPayload:cPlusPluspayload];
56-
} else if (error) {
57-
*error = [MTRError errorForCHIPErrorCode:chipError];
36+
MTRSetupPayload * payload = [[MTRSetupPayload alloc] initWithQRCode:_base38Representation];
37+
if (!payload && error) {
38+
*error = [MTRError errorWithCode:MTRErrorCodeInvalidArgument];
5839
}
59-
6040
return payload;
6141
}
6242

63-
- (void)dealloc
64-
{
65-
delete _chipQRCodeSetupPayloadParser;
66-
_chipQRCodeSetupPayloadParser = nullptr;
67-
}
68-
6943
@end

0 commit comments

Comments
 (0)