From 7a45cd5582ee6d6e84538bf58e9568f4aeb274a1 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 13 Sep 2022 22:59:47 -0400 Subject: [PATCH] Apply API review fixes for MTROTAHeaderParser. * Move the parsing method to MTROTAHeader. * Rename the file to MTROTAHeader.h * Add documentation. * Make the properties that can be missing nullable. * Make properties copy instead of strong. Fixes https://github.com/project-chip/connectedhomeip/issues/22540 Addresses part of https://github.com/project-chip/connectedhomeip/issues/22420 --- .../provider/OTASoftwareUpdateInteractive.mm | 2 +- src/darwin/Framework/CHIP/MTROTAHeader.h | 111 ++++++++++++++++++ ...{MTROTAHeaderParser.mm => MTROTAHeader.mm} | 13 +- .../Framework/CHIP/MTROTAHeaderParser.h | 56 --------- src/darwin/Framework/CHIP/Matter.h | 2 +- .../Matter.xcodeproj/project.pbxproj | 16 +-- 6 files changed, 128 insertions(+), 72 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTROTAHeader.h rename src/darwin/Framework/CHIP/{MTROTAHeaderParser.mm => MTROTAHeader.mm} (89%) delete mode 100644 src/darwin/Framework/CHIP/MTROTAHeaderParser.h diff --git a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm index 1c8caa56089ca4..d73357e9323eef 100644 --- a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm +++ b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm @@ -39,7 +39,7 @@ } NSError * error; - return [MTROTAHeaderParser headerFromData:[NSData dataWithBytes:buffer.data() length:buffer.size()] error:&error]; + return [MTROTAHeader headerFromData:[NSData dataWithBytes:buffer.data() length:buffer.size()] error:&error]; } // Parses the JSON filepath and extracts DeviceSoftwareVersionModel parameters diff --git a/src/darwin/Framework/CHIP/MTROTAHeader.h b/src/darwin/Framework/CHIP/MTROTAHeader.h new file mode 100644 index 00000000000000..0684cdb66697aa --- /dev/null +++ b/src/darwin/Framework/CHIP/MTROTAHeader.h @@ -0,0 +1,111 @@ +/** + * + * Copyright (c) 2022 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 + +/** + * A representation of an OTA image header as defined in the Matter + * specification's "Over-the-Air (OTA) Software Update File Format" section. + */ + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, MTROTAImageDigestType) { + MTROTAImageDigestTypeSha256 = 1, + MTROTAImageDigestTypeSha256_128, + MTROTAImageDigestTypeSha256_120, + MTROTAImageDigestTypeSha256_96, + MTROTAImageDigestTypeSha256_64, + MTROTAImageDigestTypeSha256_32, + MTROTAImageDigestTypeSha384, + MTROTAImageDigestTypeSha512, + MTROTAImageDigestTypeSha3_224, + MTROTAImageDigestTypeSha3_256, + MTROTAImageDigestTypeSha3_384, + MTROTAImageDigestTypeSha3_512, +}; + +@interface MTROTAHeader : NSObject + +/** + * The identifier of the vendor whose product this image is meant for. + * + * This field can be compared to the vendor id received in the Query Image + * command to determine whether an image matches. + * + * This field may be 0, in which case the image might apply to products from + * more than one vendor. If it's nonzero, it must match the vendor id in Query + * Image for this image to be considered. + */ +@property (nonatomic, copy) NSNumber * vendorID; +/** + * The identifier of the specific product the image is meant for. May be 0, if + * the image might apply to more than one product. This is allowed, but not + * required, to be matched against the product id received in Query Image. + */ +@property (nonatomic, copy) NSNumber * productID; +/** + * The size of the actual image payload, which follows the header in the OTA + * file. + */ +@property (nonatomic, copy) NSNumber * payloadSize; +/** + * The version of the software contained in this image. This is the version the + * OTA requestor will be updated to if this image is installed. This can be + * used to determine whether this image is newer than what the requestor is + * currently running, by comparing it to the SoftwareVersion in the Query Image + * command. + */ +@property (nonatomic, copy) NSNumber * softwareVersion; +/** + * Human-readable version of softwareVersion. This must not be used for + * deciding which versions are newer or older; use softwareVersion for that. + */ +@property (nonatomic, copy) NSString * softwareVersionString; +/** + * If not nil a URL pointing to release notes for the software update + * represented by the image. + */ +@property (nonatomic, copy, nullable) NSString * releaseNotesURL; +/** + * A digest of the payload that follows the header. Can be used to verify that + * the payload is not truncated or corrupted. + */ +@property (nonatomic, copy) NSData * imageDigest; +/** + * The specific algorithm that was used to compute imageDigest. + */ +@property (nonatomic, assign) MTROTAImageDigestType imageDigestType; +/** + * If not nil, specifies the smallest software version that this update can be + * applied on top of. In that case, this value must be compared to the + * SoftwareVersion in the QueryImage command to check whether this image is + * valid for the OTA requestor. + */ +@property (nonatomic, copy, nullable) NSNumber * minApplicableVersion; +/** + * If not nil, specifies the largest software version that this update can be + * applied on top of. In that case, this value must be compared to the + * SoftwareVersion in the QueryImage command to check whether this image is + * valid for the OTA requestor. + */ +@property (nonatomic, copy, nullable) NSNumber * maxApplicableVersion; + ++ (nullable MTROTAHeader *)headerFromData:(NSData *)data error:(NSError * __autoreleasing *)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTROTAHeaderParser.mm b/src/darwin/Framework/CHIP/MTROTAHeader.mm similarity index 89% rename from src/darwin/Framework/CHIP/MTROTAHeaderParser.mm rename to src/darwin/Framework/CHIP/MTROTAHeader.mm index b796d8797f3023..2cb6882af34125 100644 --- a/src/darwin/Framework/CHIP/MTROTAHeaderParser.mm +++ b/src/darwin/Framework/CHIP/MTROTAHeader.mm @@ -15,7 +15,7 @@ * limitations under the License. */ -#import "MTROTAHeaderParser.h" +#import "MTROTAHeader.h" #import "MTRError.h" #import "MTRError_Internal.h" @@ -25,9 +25,6 @@ #include @implementation MTROTAHeader -@end - -@implementation MTROTAHeaderParser + (MTROTAHeader * _Nullable)headerFromData:(NSData *)data error:(NSError * __autoreleasing *)error { chip::OTAImageHeaderParser parser; @@ -35,7 +32,9 @@ + (MTROTAHeader * _Nullable)headerFromData:(NSData *)data error:(NSError * __aut parser.Init(); if (!parser.IsInitialized()) { - *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]; + if (error != nil) { + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]; + } return nil; } @@ -43,7 +42,9 @@ + (MTROTAHeader * _Nullable)headerFromData:(NSData *)data error:(NSError * __aut chip::OTAImageHeader header; CHIP_ERROR err = parser.AccumulateAndDecode(buffer, header); if (err != CHIP_NO_ERROR) { - *error = [MTRError errorForCHIPErrorCode:err]; + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:err]; + } parser.Clear(); return nil; } diff --git a/src/darwin/Framework/CHIP/MTROTAHeaderParser.h b/src/darwin/Framework/CHIP/MTROTAHeaderParser.h deleted file mode 100644 index d578af8cae05b8..00000000000000 --- a/src/darwin/Framework/CHIP/MTROTAHeaderParser.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * - * Copyright (c) 2022 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 - -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSUInteger, MTROTAImageDigestType) { - MTROTAImageDigestTypeSha256 = 1, - MTROTAImageDigestTypeSha256_128, - MTROTAImageDigestTypeSha256_120, - MTROTAImageDigestTypeSha256_96, - MTROTAImageDigestTypeSha256_64, - MTROTAImageDigestTypeSha256_32, - MTROTAImageDigestTypeSha384, - MTROTAImageDigestTypeSha512, - MTROTAImageDigestTypeSha3_224, - MTROTAImageDigestTypeSha3_256, - MTROTAImageDigestTypeSha3_384, - MTROTAImageDigestTypeSha3_512, -}; - -@interface MTROTAHeader : NSObject - -@property (nonatomic, strong) NSNumber * vendorID; -@property (nonatomic, strong) NSNumber * productID; -@property (nonatomic, strong) NSNumber * payloadSize; -@property (nonatomic, strong) NSNumber * softwareVersion; -@property (nonatomic, strong) NSString * softwareVersionString; -@property (nonatomic, strong) NSString * releaseNotesURL; -@property (nonatomic, strong) NSData * imageDigest; -@property (nonatomic, assign) MTROTAImageDigestType imageDigestType; -@property (nonatomic, strong) NSNumber * minApplicableVersion; -@property (nonatomic, strong) NSNumber * maxApplicableVersion; - -@end - -@interface MTROTAHeaderParser : NSObject -+ (nullable MTROTAHeader *)headerFromData:(NSData *)data error:(NSError * __autoreleasing *)error; -@end - -NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index c2040c08a882c4..b6ba88c6d5dc0c 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -39,7 +39,7 @@ #import #import #import -#import +#import #import #import #import diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index d643e28707c3f0..718b8e04691f03 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -15,8 +15,8 @@ 1ED276E026C57CF000547A89 /* MTRCallbackBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1ED276DF26C57CF000547A89 /* MTRCallbackBridge.mm */; }; 1ED276E226C5812A00547A89 /* MTRCluster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1ED276E126C5812A00547A89 /* MTRCluster.mm */; }; 1ED276E426C5832500547A89 /* MTRCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ED276E326C5832500547A89 /* MTRCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1EDCE545289049A100E41EC9 /* MTROTAHeaderParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EDCE543289049A100E41EC9 /* MTROTAHeaderParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1EDCE546289049A100E41EC9 /* MTROTAHeaderParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EDCE544289049A100E41EC9 /* MTROTAHeaderParser.mm */; }; + 1EDCE545289049A100E41EC9 /* MTROTAHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EDCE543289049A100E41EC9 /* MTROTAHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1EDCE546289049A100E41EC9 /* MTROTAHeader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EDCE544289049A100E41EC9 /* MTROTAHeader.mm */; }; 27A53C1727FBC6920053F131 /* MTRAttestationTrustStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 27A53C1527FBC6920053F131 /* MTRAttestationTrustStoreBridge.h */; }; 27A53C1827FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27A53C1627FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm */; }; 2C1B027A2641DB4E00780EF1 /* MTROperationalCredentialsDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C1B02782641DB4E00780EF1 /* MTROperationalCredentialsDelegate.mm */; }; @@ -154,8 +154,8 @@ 1ED276DF26C57CF000547A89 /* MTRCallbackBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MTRCallbackBridge.mm; path = "zap-generated/MTRCallbackBridge.mm"; sourceTree = ""; }; 1ED276E126C5812A00547A89 /* MTRCluster.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCluster.mm; sourceTree = ""; }; 1ED276E326C5832500547A89 /* MTRCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRCluster.h; sourceTree = ""; }; - 1EDCE543289049A100E41EC9 /* MTROTAHeaderParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTROTAHeaderParser.h; sourceTree = ""; }; - 1EDCE544289049A100E41EC9 /* MTROTAHeaderParser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROTAHeaderParser.mm; sourceTree = ""; }; + 1EDCE543289049A100E41EC9 /* MTROTAHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTROTAHeader.h; sourceTree = ""; }; + 1EDCE544289049A100E41EC9 /* MTROTAHeader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROTAHeader.mm; sourceTree = ""; }; 27A53C1527FBC6920053F131 /* MTRAttestationTrustStoreBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRAttestationTrustStoreBridge.h; sourceTree = ""; }; 27A53C1627FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRAttestationTrustStoreBridge.mm; sourceTree = ""; }; 2C1B02782641DB4E00780EF1 /* MTROperationalCredentialsDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalCredentialsDelegate.mm; sourceTree = ""; }; @@ -355,8 +355,8 @@ B202528F2459E34F00F97062 /* CHIP */ = { isa = PBXGroup; children = ( - 1EDCE543289049A100E41EC9 /* MTROTAHeaderParser.h */, - 1EDCE544289049A100E41EC9 /* MTROTAHeaderParser.mm */, + 1EDCE543289049A100E41EC9 /* MTROTAHeader.h */, + 1EDCE544289049A100E41EC9 /* MTROTAHeader.mm */, 27A53C1527FBC6920053F131 /* MTRAttestationTrustStoreBridge.h */, 27A53C1627FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm */, 88EBF8CB27FABDD500686BC1 /* MTRDeviceAttestationDelegate.h */, @@ -556,7 +556,7 @@ 7596A84828762783004DAE0E /* MTRAsyncCallbackWorkQueue.h in Headers */, 5A7947E527C0129F00434CF2 /* MTRDeviceController+XPC.h in Headers */, B2E0D7B4245B0B5C003C5B48 /* MTRError_Internal.h in Headers */, - 1EDCE545289049A100E41EC9 /* MTROTAHeaderParser.h in Headers */, + 1EDCE545289049A100E41EC9 /* MTROTAHeader.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -698,7 +698,7 @@ 3CF134A9289D8D800017A19E /* MTRCSRInfo.m in Sources */, 991DC0892475F47D00C13860 /* MTRDeviceController.mm in Sources */, B2E0D7B7245B0B5C003C5B48 /* MTRQRCodeSetupPayloadParser.mm in Sources */, - 1EDCE546289049A100E41EC9 /* MTROTAHeaderParser.mm in Sources */, + 1EDCE546289049A100E41EC9 /* MTROTAHeader.mm in Sources */, 1EC4CE5D25CC26E900D7304F /* MTRBaseClusters.mm in Sources */, 51E0310127EA20D20083DC9C /* MTRControllerAccessControl.mm in Sources */, 1ED276E226C5812A00547A89 /* MTRCluster.mm in Sources */,