From 009f601c3ee30f49fe3fe94c5288ca080eb6b490 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 18 Jul 2023 14:35:08 -0400 Subject: [PATCH 1/5] Add a Swift XCTest for commissioning. (#27998) * Add a Swift XCTest for commissioning. * Address review comments. Also fixes some bits that did not set the error outparam when returning nil. --- .../CHIP/MTRDeviceControllerFactory.mm | 12 ++ .../CHIPTests/MTRSwiftPairingTests.swift | 109 ++++++++++++++++++ .../CHIPTests/MatterTests-Bridging-Header.h | 7 ++ .../Matter.xcodeproj/project.pbxproj | 14 +++ 4 files changed, 142 insertions(+) create mode 100644 src/darwin/Framework/CHIPTests/MTRSwiftPairingTests.swift create mode 100644 src/darwin/Framework/CHIPTests/MatterTests-Bridging-Header.h diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 5bd050b0df028e..053a3a5c6a5094 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -560,6 +560,9 @@ - (MTRDeviceController * _Nullable)createControllerOnExistingFabric:(MTRDeviceCo if (![self checkIsRunning:error]) { MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running"); + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } return nil; } @@ -653,16 +656,25 @@ - (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControl if (![self isRunning]) { MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running"); + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } return nil; } if (startupParams.vendorID == nil) { MTR_LOG_ERROR("Must provide vendor id when starting controller on new fabric"); + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]; + } return nil; } if (startupParams.intermediateCertificate != nil && startupParams.rootCertificate == nil) { MTR_LOG_ERROR("Must provide a root certificate when using an intermediate certificate"); + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]; + } return nil; } diff --git a/src/darwin/Framework/CHIPTests/MTRSwiftPairingTests.swift b/src/darwin/Framework/CHIPTests/MTRSwiftPairingTests.swift new file mode 100644 index 00000000000000..70c95d5c42efb4 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MTRSwiftPairingTests.swift @@ -0,0 +1,109 @@ +import Matter +import XCTest + +// This more or less parallels the "no delegate" case in MTRPairingTests + +struct Constants { + static let localPort = 5541 + static let vendorID = 0xFFF1 + static let onboardingPayload = "MT:Y.K90SO527JA0648G00" + static let deviceID = 0x12344321 + static let timeoutInSeconds : UInt16 = 3 +} + +class MTRSwiftPairingTestControllerDelegate : NSObject, MTRDeviceControllerDelegate { + let expectation: XCTestExpectation + + init(withExpectation providedExpectation: XCTestExpectation) { + expectation = providedExpectation + } + + @available(macOS, introduced: 13.3) + func controller(_ controller: MTRDeviceController, statusUpdate status: MTRCommissioningStatus) { + XCTAssertNotEqual(status, MTRCommissioningStatus.failed) + } + + @available(macOS, introduced: 13.3) + func controller(_ controller: MTRDeviceController, commissioningSessionEstablishmentDone error: Error?) { + XCTAssertNil(error) + + do { + try controller.commissionNode(withID: Constants.deviceID as NSNumber, commissioningParams: MTRCommissioningParameters()) + } catch { + XCTFail("Could not start commissioning of node: \(error)") + } + + // Keep waiting for commissioningComplete + } + + func controller(_ controller: MTRDeviceController, commissioningComplete error: Error?, nodeID: NSNumber?) { + XCTAssertNil(error) + XCTAssertEqual(nodeID, Constants.deviceID as NSNumber) + expectation.fulfill() + } +} + +class MTRSwiftPairingTests : XCTestCase { + @available(macOS, introduced: 13.3) + func test001_BasicPairing() { + let factory = MTRDeviceControllerFactory.sharedInstance() + + let storage = MTRTestStorage() + let factoryParams = MTRDeviceControllerFactoryParams(storage: storage) + factoryParams.port = Constants.localPort as NSNumber + + do { + try factory.start(factoryParams) + } catch { + XCTFail("Could not start controller factory: \(error)") + return + } + XCTAssertTrue(factory.isRunning) + + let testKeys = MTRTestKeys() + + let params = MTRDeviceControllerStartupParams(ipk: testKeys.ipk, fabricID: 1, nocSigner: testKeys) + params.vendorID = Constants.vendorID as NSNumber + + let controller: MTRDeviceController + do { + controller = try factory.createController(onNewFabric: params) + } catch { + XCTFail("Could not create controller: \(error)") + return + } + XCTAssertTrue(controller.isRunning) + + let expectation = expectation(description: "Commissioning Complete") + + let controllerDelegate = MTRSwiftPairingTestControllerDelegate(withExpectation: expectation) + let serialQueue = DispatchQueue(label: "com.chip.pairing") + + controller.setDeviceControllerDelegate(controllerDelegate, queue: serialQueue) + + let payload : MTRSetupPayload + do { + payload = try MTRSetupPayload(onboardingPayload: Constants.onboardingPayload) + } catch { + XCTFail("Could not parse setup payload: \(error)") + return + } + + do { + try controller.setupCommissioningSession(with: payload, newNodeID: Constants.deviceID as NSNumber) + } catch { + XCTFail("Could not start setting up PASE session: \(error)") + return + } + + wait(for: [expectation], timeout: TimeInterval(Constants.timeoutInSeconds)) + + ResetCommissionee(MTRBaseDevice(nodeID: Constants.deviceID as NSNumber, controller: controller), DispatchQueue.main, self, Constants.timeoutInSeconds) + + controller.shutdown() + XCTAssertFalse(controller.isRunning) + + factory.stop() + XCTAssertFalse(factory.isRunning) + } +} diff --git a/src/darwin/Framework/CHIPTests/MatterTests-Bridging-Header.h b/src/darwin/Framework/CHIPTests/MatterTests-Bridging-Header.h new file mode 100644 index 00000000000000..52983e729d27b1 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MatterTests-Bridging-Header.h @@ -0,0 +1,7 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "MTRTestKeys.h" +#import "MTRTestResetCommissioneeHelper.h" +#import "MTRTestStorage.h" diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 7b97bb8c4861e2..7693dd68e95935 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -152,6 +152,7 @@ 514304202914CED9004DC7FE /* generic-callback-stubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5143041F2914CED9004DC7FE /* generic-callback-stubs.cpp */; }; 51431AF927D2973E008A7943 /* MTRIMDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51431AF827D2973E008A7943 /* MTRIMDispatch.mm */; }; 51431AFB27D29CA4008A7943 /* ota-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51431AFA27D29CA4008A7943 /* ota-provider.cpp */; }; + 5143851E2A65885500EDC8E6 /* MTRSwiftPairingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5143851D2A65885500EDC8E6 /* MTRSwiftPairingTests.swift */; }; 515C1C6F284F9FFB00A48F0C /* MTRFramework.mm in Sources */ = {isa = PBXBuildFile; fileRef = 515C1C6D284F9FFB00A48F0C /* MTRFramework.mm */; }; 515C1C70284F9FFB00A48F0C /* MTRFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 515C1C6E284F9FFB00A48F0C /* MTRFramework.h */; }; 51669AF02913204400F4AA36 /* MTRBackwardsCompatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */; }; @@ -452,6 +453,8 @@ 5143041F2914CED9004DC7FE /* generic-callback-stubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "generic-callback-stubs.cpp"; path = "util/generic-callback-stubs.cpp"; sourceTree = ""; }; 51431AF827D2973E008A7943 /* MTRIMDispatch.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRIMDispatch.mm; sourceTree = ""; }; 51431AFA27D29CA4008A7943 /* ota-provider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ota-provider.cpp"; path = "clusters/ota-provider/ota-provider.cpp"; sourceTree = ""; }; + 5143851C2A65885400EDC8E6 /* MatterTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MatterTests-Bridging-Header.h"; sourceTree = ""; }; + 5143851D2A65885500EDC8E6 /* MTRSwiftPairingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTRSwiftPairingTests.swift; sourceTree = ""; }; 515C1C6D284F9FFB00A48F0C /* MTRFramework.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRFramework.mm; sourceTree = ""; }; 515C1C6E284F9FFB00A48F0C /* MTRFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRFramework.h; sourceTree = ""; }; 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRBackwardsCompatTests.m; sourceTree = ""; }; @@ -1120,7 +1123,9 @@ 51A2F1312A00402A00F03298 /* MTRDataValueParserTests.m */, 51339B1E2A0DA64D00C798C1 /* MTRCertificateValidityTests.m */, 519498312A25581C00B3BABE /* MTRSetupPayloadSerializerTests.m */, + 5143851D2A65885500EDC8E6 /* MTRSwiftPairingTests.swift */, B202529D2459E34F00F97062 /* Info.plist */, + 5143851C2A65885400EDC8E6 /* MatterTests-Bridging-Header.h */, ); path = CHIPTests; sourceTree = ""; @@ -1346,6 +1351,7 @@ }; B20252952459E34F00F97062 = { CreatedOnToolsVersion = 11.4.1; + LastSwiftMigration = 1430; }; }; }; @@ -1532,6 +1538,7 @@ 1EE0805E2A44875E008A03C2 /* MTRCommissionableBrowserTests.m in Sources */, 51339B1F2A0DA64D00C798C1 /* MTRCertificateValidityTests.m in Sources */, 5173A47929C0E82300F67F48 /* MTRFabricInfoTests.m in Sources */, + 5143851E2A65885500EDC8E6 /* MTRSwiftPairingTests.swift in Sources */, 3D0C484B29DA4FA0006D811F /* MTRErrorTests.m in Sources */, 51742B4A29CB5FC1009974FE /* MTRTestResetCommissioneeHelper.m in Sources */, 5AE6D4E427A99041001F2493 /* MTRDeviceTests.m in Sources */, @@ -1824,6 +1831,7 @@ BA09EB752474881D00605257 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; "HEADER_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../../../src"; INFOPLIST_FILE = CHIPTests/Info.plist; @@ -1834,6 +1842,9 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chip.CHIPTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "CHIPTests/MatterTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Debug; @@ -1987,6 +1998,7 @@ BA09EB792474882200605257 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; "HEADER_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../../../src"; @@ -1998,6 +2010,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chip.CHIPTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "CHIPTests/MatterTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Release; From d972f17d21001bb0704912dfe1b7c8b5e1eadaaa Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 18 Jul 2023 14:50:38 -0400 Subject: [PATCH 2/5] Time sync: add check for fabric removal (#28011) * Time sync: add check for fabric removal * Update src/app/clusters/time-synchronization-server/time-synchronization-server.cpp --- .../time-synchronization-server.cpp | 17 +++++++++++++++++ .../time-synchronization-server.h | 6 +++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp b/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp index 4ec952a97537c9..f7a0c39919d168 100644 --- a/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp +++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp @@ -258,6 +258,13 @@ void TimeSynchronizationServer::Init() { mGranularity = GranularityEnum::kNoTimeGranularity; } + // This can error, but it's not clear what should happen in this case. For now, just ignore it because we still + // want time sync even if we can't register the deletgate here. + CHIP_ERROR err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(this); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Unable to register Fabric table delegate for time sync"); + } } CHIP_ERROR TimeSynchronizationServer::SetTrustedTimeSource(const DataModel::Nullable & tts) @@ -663,6 +670,16 @@ void TimeSynchronizationServer::ClearEventFlag(TimeSyncEventFlag flag) mEventFlag = static_cast(eventFlag); } +void TimeSynchronizationServer::OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) +{ + if (!mTrustedTimeSource.IsNull() && mTrustedTimeSource.Value().fabricIndex == fabricIndex) + { + DataModel::Nullable tts; + TimeSynchronizationServer::Instance().SetTrustedTimeSource(tts); + emitMissingTrustedTimeSourceEvent(0); + } +} + namespace { class TimeSynchronizationAttrAccess : public AttributeAccessInterface diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.h b/src/app/clusters/time-synchronization-server/time-synchronization-server.h index e98ad10b067b19..5b64f613e7a1eb 100644 --- a/src/app/clusters/time-synchronization-server/time-synchronization-server.h +++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -60,7 +61,7 @@ enum class TimeSyncEventFlag : uint8_t kMissingTTSource = 16, }; -class TimeSynchronizationServer +class TimeSynchronizationServer : public FabricTable::Delegate { public: void Init(); @@ -94,6 +95,9 @@ class TimeSynchronizationServer TimeSyncEventFlag GetEventFlag(void); void ClearEventFlag(TimeSyncEventFlag flag); + // Fabric Table delegate functions + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex); + private: DataModel::Nullable mTrustedTimeSource; TimeSyncDataProvider::TimeZoneObj mTimeZoneObj{ Span(mTz), 0 }; From b312dfe72ca915b7a7b173486ed5767418552d76 Mon Sep 17 00:00:00 2001 From: marktrayer Date: Tue, 18 Jul 2023 13:55:35 -0500 Subject: [PATCH 3/5] Change OnOff revision to 5 (XML). Update all impacted .zap files. (#26524) Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- .../all-clusters-app.matter | 6 +- .../all-clusters-common/all-clusters-app.zap | 12 +-- .../all-clusters-minimal-app.matter | 5 +- .../all-clusters-minimal-app.zap | 12 +-- .../bridge-common/bridge-app.matter | 3 +- .../bridge-app/bridge-common/bridge-app.zap | 4 +- ...p_rootnode_dimmablelight_bCwGYSDpoe.matter | 3 +- ...noip_rootnode_dimmablelight_bCwGYSDpoe.zap | 8 +- ...de_colortemperaturelight_hbUnzYVeyn.matter | 3 +- ...tnode_colortemperaturelight_hbUnzYVeyn.zap | 8 +- .../rootnode_contactsensor_lFAGG1bfRO.zap | 4 +- .../rootnode_dimmablelight_bCwGYSDpoe.matter | 3 +- .../rootnode_dimmablelight_bCwGYSDpoe.zap | 8 +- .../devices/rootnode_doorlock_aNKYAreMXE.zap | 8 +- ...tnode_extendedcolorlight_8lcaaYJVAa.matter | 3 +- ...rootnode_extendedcolorlight_8lcaaYJVAa.zap | 8 +- .../chef/devices/rootnode_fan_7N2TobIlOX.zap | 4 +- .../rootnode_flowsensor_1zVxHedlaV.zap | 4 +- ...tnode_heatingcoolingunit_ncdGai1E5a.matter | 3 +- ...rootnode_heatingcoolingunit_ncdGai1E5a.zap | 8 +- .../rootnode_humiditysensor_Xyj4gda6Hb.zap | 4 +- .../rootnode_lightsensor_lZQycTFcJK.zap | 4 +- .../rootnode_occupancysensor_iHyVgifZuo.zap | 4 +- .../rootnode_onofflight_bbs1b7IaOV.matter | 3 +- .../rootnode_onofflight_bbs1b7IaOV.zap | 8 +- ...ootnode_onofflightswitch_FsPlMr090Q.matter | 4 +- .../rootnode_onofflightswitch_FsPlMr090Q.zap | 8 +- ...rootnode_onoffpluginunit_Wtf8ss5EBY.matter | 3 +- .../rootnode_onoffpluginunit_Wtf8ss5EBY.zap | 8 +- .../rootnode_pressuresensor_s0qC9wLH4k.zap | 4 +- .../devices/rootnode_pump_a811bb33a0.matter | 1 + .../chef/devices/rootnode_pump_a811bb33a0.zap | 2 +- .../rootnode_speaker_RpzeXdimqA.matter | 3 +- .../devices/rootnode_speaker_RpzeXdimqA.zap | 8 +- .../rootnode_temperaturesensor_Qy1zkNW7c3.zap | 4 +- .../rootnode_thermostat_bm3fb8dhYi.zap | 4 +- .../rootnode_windowcovering_RLCxaGi9Yx.zap | 4 +- .../test_files/sample_zap_file.zap | 8 +- .../contact-sensor-app.zap | 8 +- .../light-switch-app.matter | 1 + .../light-switch-common/light-switch-app.zap | 8 +- .../data_model/lighting-app-thread.matter | 3 +- .../data_model/lighting-app-thread.zap | 8 +- .../data_model/lighting-app-wifi.matter | 3 +- .../data_model/lighting-app-wifi.zap | 8 +- .../lighting-common/lighting-app.matter | 3 +- .../lighting-common/lighting-app.zap | 4 +- .../nxp/zap/lighting-on-off.matter | 3 +- .../lighting-app/nxp/zap/lighting-on-off.zap | 8 +- examples/lighting-app/qpg/zap/light.matter | 3 +- examples/lighting-app/qpg/zap/light.zap | 8 +- .../data_model/lighting-thread-app.matter | 3 +- .../silabs/data_model/lighting-thread-app.zap | 8 +- .../data_model/lighting-wifi-app.matter | 3 +- .../silabs/data_model/lighting-wifi-app.zap | 8 +- examples/lock-app/lock-common/lock-app.matter | 3 +- examples/lock-app/lock-common/lock-app.zap | 8 +- examples/lock-app/nxp/zap/lock-app.zap | 4 +- examples/lock-app/qpg/zap/lock.zap | 8 +- .../log-source-common/log-source-app.zap | 4 +- .../ota-provider-common/ota-provider-app.zap | 4 +- .../ota-requestor-app.matter | 3 +- .../ota-requestor-app.zap | 8 +- .../placeholder/linux/apps/app1/config.matter | 4 +- .../placeholder/linux/apps/app1/config.zap | 4 +- .../placeholder/linux/apps/app2/config.matter | 4 +- .../placeholder/linux/apps/app2/config.zap | 4 +- examples/pump-app/pump-common/pump-app.matter | 3 +- examples/pump-app/pump-common/pump-app.zap | 4 +- .../pump-controller-app.matter | 1 + .../pump-controller-app.zap | 4 +- .../smoke-co-alarm-app.zap | 4 +- .../thermostat-common/thermostat.zap | 8 +- examples/tv-app/tv-common/tv-app.matter | 5 +- examples/tv-app/tv-common/tv-app.zap | 12 +-- .../tv-casting-common/tv-casting-app.matter | 1 + .../tv-casting-common/tv-casting-app.zap | 8 +- .../zap/tests/inputs/all-clusters-app.zap | 12 +-- .../tools/zap/tests/inputs/lighting-app.zap | 8 +- .../app-templates/endpoint_config.h | 4 +- .../app-templates/endpoint_config.h | 2 +- src/app/tests/suites/certification/PICS.yaml | 3 + .../suites/certification/Test_TC_OO_1_1.yaml | 14 ++- .../tests/suites/certification/ci-pics-values | 1 + .../zcl/data-model/chip/onoff-cluster.xml | 3 +- .../data_model/controller-clusters.matter | 1 + .../data_model/controller-clusters.zap | 4 +- .../python/chip/clusters/Objects.py | 1 + .../CHIP/zap-generated/MTRBaseClusters.h | 1 + .../app-common/zap-generated/cluster-enums.h | 3 +- .../chip-tool/zap-generated/test/Commands.h | 54 ++++++++---- .../zap-generated/test/Commands.h | 86 ++++++++++++------- 92 files changed, 346 insertions(+), 250 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 7430b037d79e12..d743a03b7dd723 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -293,6 +293,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -361,6 +362,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -6529,7 +6531,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 0x0001; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster OnOffSwitchConfiguration { @@ -7558,7 +7560,7 @@ endpoint 2 { ram attribute offWaitTime default = 0; ram attribute startUpOnOff; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index e78ffef66e0cc4..d4998f476c3a9d 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -608,7 +608,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -650,7 +650,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -10127,7 +10127,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -10297,7 +10297,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -29897,7 +29897,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -30019,7 +30019,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 1e5a0b4931593b..9e5f6786a55f9a 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -287,6 +287,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -4209,7 +4210,7 @@ endpoint 1 { server cluster OnOff { persist attribute onOff default = 0x00; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { @@ -4594,7 +4595,7 @@ endpoint 2 { server cluster OnOff { ram attribute onOff default = 0x00; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap index b1dc9e0bfe9faa..1ad1394f4a2adc 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap @@ -608,7 +608,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -650,7 +650,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9153,7 +9153,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9323,7 +9323,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -21564,7 +21564,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -21686,7 +21686,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index b9159bfe7c78f7..199117c8edd14a 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -104,6 +104,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1970,7 +1971,7 @@ endpoint 2 { server cluster OnOff { ram attribute onOff default = 0x00; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/bridge-app/bridge-common/bridge-app.zap b/examples/bridge-app/bridge-common/bridge-app.zap index ab047dcf8cd7a8..4fd1ae893aaada 100644 --- a/examples/bridge-app/bridge-common/bridge-app.zap +++ b/examples/bridge-app/bridge-common/bridge-app.zap @@ -6270,7 +6270,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6328,7 +6328,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 2936d0b4dfd411..59852041f62afa 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1843,7 +1844,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0x1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.zap b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.zap index 737718bf5d98fd..05a923ced5d212 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.zap +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6224,7 +6224,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6394,7 +6394,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter index 1c66700a58d779..df9263ae1c4412 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1707,7 +1708,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.zap b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.zap index 87ea9747f7b6ce..e6acf1565b0276 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.zap +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6313,7 +6313,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6499,7 +6499,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap index d535157c7ae66e..e89aecd12781ae 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter index 77a88a5555a0f1..927061e0e3d6f3 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1619,7 +1620,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0x1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap index 3816db4a60f3a3..7fba5c4134daf5 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6249,7 +6249,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6419,7 +6419,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.zap b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.zap index e950e4f0d356bb..5a46308f437617 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.zap +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6201,7 +6201,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6371,7 +6371,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter index 13b7ab5dd36a61..151ea11cec76f3 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1845,7 +1846,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0x1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.zap b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.zap index 215741490ee549..79e9cc632850e1 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.zap +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6201,7 +6201,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6371,7 +6371,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.zap b/examples/chef/devices/rootnode_fan_7N2TobIlOX.zap index cab0ff28e19c12..321bbb3b20bf07 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.zap +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap index 6cac6f5ef673ac..886a475473db1f 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index 683ec5e863619c..6180211966281c 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1791,7 +1792,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap index 63a60b24272408..945ddd6d1e5ce8 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6167,7 +6167,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6337,7 +6337,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap index f143625afbb536..b978f4ec63924f 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap index 1778ef509b39f8..f9afc87acb29fe 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap index cfcd999a726b20..3afbcce18145ec 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index 826b8733180a87..0d004319048e9b 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1577,7 +1578,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap index 3d677ebd130a75..936482b5b5f361 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6201,7 +6201,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6371,7 +6371,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter index 7dec9ff856d9e2..26de0114737044 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -167,6 +167,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -235,6 +236,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1537,7 +1539,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap index 4d114d92a0c17c..0f1824d8ea2bea 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6201,7 +6201,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6371,7 +6371,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter index b2c9f3b1df05f9..5c10b0e1c762d8 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1476,7 +1477,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap index 0bac9060a6c2c4..fbecf55ef040e4 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6201,7 +6201,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6371,7 +6371,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap index abc07c0f87df82..bc3b79d37dc51b 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.matter b/examples/chef/devices/rootnode_pump_a811bb33a0.matter index 2cbc3939eb206c..fd3f0022ec1ab0 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -104,6 +104,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.zap b/examples/chef/devices/rootnode_pump_a811bb33a0.zap index 759cdfdba44c45..f83aac1598fd68 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.zap +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.zap @@ -6594,7 +6594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter index c5e2ecff2cdbca..d5a586c417a99a 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -167,6 +167,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1558,7 +1559,7 @@ endpoint 1 { callback attribute acceptedCommandList default = 0; callback attribute attributeList default = 0; ram attribute featureMap default = 0x0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap index 209a2b9ed60b38..2a6dbf5b9ce81d 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5633,7 +5633,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5803,7 +5803,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap index bc0e7c737038e4..f1dbfdd711a930 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap index 44bde117b830f6..4ab16c9f1ee7b1 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap index 5b4360a8a32c0a..df025f16b7344f 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/chef/sample_app_util/test_files/sample_zap_file.zap b/examples/chef/sample_app_util/test_files/sample_zap_file.zap index c954ce70224b27..c72c564300460a 100644 --- a/examples/chef/sample_app_util/test_files/sample_zap_file.zap +++ b/examples/chef/sample_app_util/test_files/sample_zap_file.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5966,7 +5966,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6088,7 +6088,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap index d1d9cf4abe5e7d..fc310d97ca9bdd 100644 --- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6136,7 +6136,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6258,7 +6258,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 1b9ed214c9fc70..fd01398a33e433 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -396,6 +396,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index cbe503464f3c45..c93571c2996316 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6611,7 +6611,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6749,7 +6749,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter index 274640e7c29500..383979ff946c11 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2145,7 +2146,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.zap b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.zap index 5fd41b4d42890b..5b31d85e407fd3 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.zap +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6061,7 +6061,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6183,7 +6183,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter index 4c5a81f7e39b55..06da353cea23bd 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2007,7 +2008,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.zap b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.zap index 89acd7f87f9e78..8d717c43e916e2 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.zap +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6061,7 +6061,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6183,7 +6183,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 354100305bf66e..0c685ad61c80ad 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -317,6 +317,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2432,7 +2433,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 8161343d7f55e5..8ca915a66c1a70 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -5469,7 +5469,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5591,7 +5591,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index 47edc557d98339..bdd3f820f6b97d 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1566,7 +1567,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.zap b/examples/lighting-app/nxp/zap/lighting-on-off.zap index 3a8941297cbc42..c21d9c92bbd394 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.zap +++ b/examples/lighting-app/nxp/zap/lighting-on-off.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6349,7 +6349,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6519,7 +6519,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index f6a5e153d6c1fc..b456501a1e6e46 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2047,7 +2048,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/qpg/zap/light.zap b/examples/lighting-app/qpg/zap/light.zap index 36583b33122d79..1b658aeaf1cffc 100644 --- a/examples/lighting-app/qpg/zap/light.zap +++ b/examples/lighting-app/qpg/zap/light.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7301,7 +7301,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7487,7 +7487,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index 93321db022632a..a7040b2bee6001 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -338,6 +338,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2527,7 +2528,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.zap b/examples/lighting-app/silabs/data_model/lighting-thread-app.zap index bcd3e5b623d6fb..545671963b34a1 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.zap +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6539,7 +6539,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6661,7 +6661,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index b4ee34da3c1d00..0c1c4ef15309db 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -317,6 +317,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2304,7 +2305,7 @@ endpoint 1 { ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.zap b/examples/lighting-app/silabs/data_model/lighting-wifi-app.zap index 25e06913bb7a04..ae67282f0662aa 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.zap +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6261,7 +6261,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6383,7 +6383,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index d93129595912dc..e7a9741b157322 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -98,6 +98,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2562,7 +2563,7 @@ endpoint 1 { ram attribute offWaitTime default = 0; ram attribute startUpOnOff; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 5ccddc2b088daf..8d76ddfd54cdf7 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5976,7 +5976,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6098,7 +6098,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lock-app/nxp/zap/lock-app.zap b/examples/lock-app/nxp/zap/lock-app.zap index 54cbf6dc7829a8..3503d6e3b35e36 100644 --- a/examples/lock-app/nxp/zap/lock-app.zap +++ b/examples/lock-app/nxp/zap/lock-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lock-app/qpg/zap/lock.zap b/examples/lock-app/qpg/zap/lock.zap index 595668ff569dd6..3884fdd557478c 100644 --- a/examples/lock-app/qpg/zap/lock.zap +++ b/examples/lock-app/qpg/zap/lock.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7048,7 +7048,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7170,7 +7170,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/log-source-app/log-source-common/log-source-app.zap b/examples/log-source-app/log-source-common/log-source-app.zap index ba1151d632720e..81fc0a96b3a020 100644 --- a/examples/log-source-app/log-source-common/log-source-app.zap +++ b/examples/log-source-app/log-source-common/log-source-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap index 3c5cb228625f20..f8dd677884022c 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index 1df5987176bbbe..0ffa0d1a21dc31 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -173,6 +173,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1339,7 +1340,7 @@ endpoint 1 { ram attribute offWaitTime default = 0; persist attribute startUpOnOff default = 0xFF; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap index 867c71d558337e..5fbd879ead4619 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5945,7 +5945,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6115,7 +6115,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65534, diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index e673fc4d80d32c..78d957a4f92368 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -338,6 +338,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -406,6 +407,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -7147,7 +7149,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/placeholder/linux/apps/app1/config.zap b/examples/placeholder/linux/apps/app1/config.zap index 2565d5b7266e59..c1de43b678fbd7 100644 --- a/examples/placeholder/linux/apps/app1/config.zap +++ b/examples/placeholder/linux/apps/app1/config.zap @@ -11628,7 +11628,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65534, @@ -11814,7 +11814,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65534, diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index fb9da67813c8f8..6c65ecebe21f14 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -338,6 +338,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -406,6 +407,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -7123,7 +7125,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/placeholder/linux/apps/app2/config.zap b/examples/placeholder/linux/apps/app2/config.zap index 333648b408f972..beebe9f319fade 100644 --- a/examples/placeholder/linux/apps/app2/config.zap +++ b/examples/placeholder/linux/apps/app2/config.zap @@ -11912,7 +11912,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65534, @@ -12098,7 +12098,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65534, diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index 26fcc69e9ddeb1..b616e32193f87b 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -98,6 +98,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -1610,7 +1611,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/pump-app/pump-common/pump-app.zap b/examples/pump-app/pump-common/pump-app.zap index de01f2557f1551..2ba4c43e611618 100644 --- a/examples/pump-app/pump-common/pump-app.zap +++ b/examples/pump-app/pump-common/pump-app.zap @@ -5883,7 +5883,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6053,7 +6053,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index 8df97601c07802..751ddeea59cd4f 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -98,6 +98,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap index 4dd00338218210..83b5113b422d07 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap @@ -5823,7 +5823,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5865,7 +5865,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap index e2c4aaa0e63082..7aa73cd2a2c6d2 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap index 23fc81da772aa7..49567e9fc56f5a 100644 --- a/examples/thermostat/thermostat-common/thermostat.zap +++ b/examples/thermostat/thermostat-common/thermostat.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -8220,7 +8220,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -8342,7 +8342,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 4e54322294dcc4..0722e02b66f878 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -58,6 +58,7 @@ server cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { @@ -2736,7 +2737,7 @@ endpoint 1 { server cluster OnOff { ram attribute onOff default = 0x00; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster Descriptor { @@ -2831,7 +2832,7 @@ endpoint 2 { server cluster OnOff { ram attribute onOff default = 0x00; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster LevelControl { diff --git a/examples/tv-app/tv-common/tv-app.zap b/examples/tv-app/tv-common/tv-app.zap index 30cb37f8806469..4db12ffd11259e 100644 --- a/examples/tv-app/tv-common/tv-app.zap +++ b/examples/tv-app/tv-common/tv-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7460,7 +7460,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7518,7 +7518,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9790,7 +9790,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9848,7 +9848,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index bc7d05cd49e72c..154e5f96b4a483 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -167,6 +167,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap index 086fe507a646e2..eff8d93dd239ef 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap @@ -552,7 +552,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -594,7 +594,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7659,7 +7659,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7845,7 +7845,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/scripts/tools/zap/tests/inputs/all-clusters-app.zap b/scripts/tools/zap/tests/inputs/all-clusters-app.zap index eb0821aa30c234..f60def9897093c 100644 --- a/scripts/tools/zap/tests/inputs/all-clusters-app.zap +++ b/scripts/tools/zap/tests/inputs/all-clusters-app.zap @@ -608,7 +608,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -650,7 +650,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9338,7 +9338,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9508,7 +9508,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -21483,7 +21483,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -21605,7 +21605,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/scripts/tools/zap/tests/inputs/lighting-app.zap b/scripts/tools/zap/tests/inputs/lighting-app.zap index e175e3e4a20474..1793810e60e7aa 100644 --- a/scripts/tools/zap/tests/inputs/lighting-app.zap +++ b/scripts/tools/zap/tests/inputs/lighting-app.zap @@ -568,7 +568,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -610,7 +610,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6029,7 +6029,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6151,7 +6151,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h index bb9cc7672206fe..8f45ebd47ee361 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h @@ -775,7 +775,7 @@ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* StartUpOnOff */ \ { ZAP_SIMPLE_DEFAULT(0x0001), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ - { ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ + { ZAP_SIMPLE_DEFAULT(5), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: On/off Switch Configuration (server) */ \ { ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(ENUM8), 0 }, /* switch type */ \ @@ -1422,7 +1422,7 @@ { ZAP_MIN_MAX_DEFAULTS_INDEX(46), 0x00004003, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* StartUpOnOff */ \ { ZAP_SIMPLE_DEFAULT(0x0000), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ - { ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ + { ZAP_SIMPLE_DEFAULT(5), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ \ /* Endpoint: 2, Cluster: Descriptor (server) */ \ { ZAP_EMPTY_DEFAULT(), 0x00000000, 0, ZAP_TYPE(ARRAY), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* DeviceTypeList */ \ diff --git a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h index 43598a42835cd6..c3f587310f2fa5 100644 --- a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h @@ -453,7 +453,7 @@ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* StartUpOnOff */ \ { ZAP_SIMPLE_DEFAULT(1), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ - { ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ + { ZAP_SIMPLE_DEFAULT(5), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Level Control (server) */ \ { ZAP_SIMPLE_DEFAULT(0x01), 0x00000000, 1, ZAP_TYPE(INT8U), \ diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 82d7d55a1ff0ea..1b58859dcabdd8 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -5584,6 +5584,9 @@ PICS: - label: "Level Control for Lighting" id: OO.S.F00 + - label: "Device has Deadfront behaviour" + id: OO.S.F01 + # # server / manually # diff --git a/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml index c48a23dfc7d8c0..735e1c1d50471d 100644 --- a/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml @@ -35,14 +35,15 @@ tests: command: "readAttribute" attribute: "ClusterRevision" response: - value: 4 constraints: type: int16u + minValue: 4 + maxValue: 5 - label: "Read the global attribute: FeatureMap" command: "readAttribute" attribute: "FeatureMap" - PICS: " !OO.S.F00 " + PICS: ( !OO.S.F00 && !OO.S.F01 ) response: value: 0 constraints: @@ -57,6 +58,15 @@ tests: type: bitmap32 hasMasksSet: [0x1] + - label: "Given OO.S.F01(DF) ensure featuremap has the correct bit set" + command: "readAttribute" + attribute: "FeatureMap" + PICS: OO.S.F01 + response: + constraints: + type: bitmap32 + hasMasksSet: [0x2] + - label: "Read the global attribute: AttributeList" command: "readAttribute" attribute: "AttributeList" diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 0264ad8fe3be8d..bd5ed772903675 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -1168,6 +1168,7 @@ OO.S.C40.Rsp=1 OO.S.C41.Rsp=1 OO.S.C42.Rsp=1 OO.S.F00=1 +OO.S.F01=0 OO.S.A4003=1 OO.M.ManuallyControlled=1 diff --git a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml index 305e82aaca0c52..46689b38467deb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml @@ -53,7 +53,7 @@ limitations under the License. 0x0006 ON_OFF_CLUSTER Attributes and commands for switching devices between 'On' and 'Off' states. - + OnOff GlobalSceneControl @@ -98,5 +98,6 @@ limitations under the License. + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index db6f89b02be15c..4ce2bd85ece43d 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -356,6 +356,7 @@ client cluster OnOff = 6 { bitmap Feature : BITMAP32 { kLighting = 0x1; + kDeadFront = 0x2; } bitmap OnOffControl : BITMAP8 { diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 20d598ef63a499..229e8cdbe0e8af 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -872,7 +872,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -1058,7 +1058,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index aa2c6e474d06c9..a2d82c1d340f34 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -1344,6 +1344,7 @@ class OnOffStartUpOnOff(MatterIntEnum): class Bitmaps: class Feature(IntFlag): kLighting = 0x1 + kDeadFront = 0x2 class OnOffControl(IntFlag): kAcceptOnlyWhenOn = 0x1 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 10f9d304312ea2..ab12f8d355dfeb 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -18913,6 +18913,7 @@ typedef NS_ENUM(uint8_t, MTROnOffStartUpOnOff) { typedef NS_OPTIONS(uint32_t, MTROnOffFeature) { MTROnOffFeatureLighting API_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x1, + MTROnOffFeatureDeadFront MTR_NEWLY_AVAILABLE = 0x2, } API_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); typedef NS_OPTIONS(uint8_t, MTROnOffControl) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 67c365c6bec629..15ed70d2e5c3e0 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -157,7 +157,8 @@ enum class OnOffStartUpOnOff : uint8_t // Bitmap for Feature enum class Feature : uint32_t { - kLighting = 0x1, + kLighting = 0x1, + kDeadFront = 0x2, }; // Bitmap for OnOffControl diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 7ec8b02994c977..1f2894bfc40260 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -52618,7 +52618,7 @@ class Test_TC_OCC_2_3Suite : public TestCommand class Test_TC_OO_1_1Suite : public TestCommand { public: - Test_TC_OO_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_OO_1_1", 10, credsIssuerConfig) + Test_TC_OO_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_OO_1_1", 11, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -52660,8 +52660,9 @@ class Test_TC_OO_1_1Suite : public TestCommand { uint16_t value; VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); - VerifyOrReturn(CheckValue("clusterRevision", value, 4U)); VerifyOrReturn(CheckConstraintType("value", "int16u", "int16u")); + VerifyOrReturn(CheckConstraintMinValue("value", value, 4U)); + VerifyOrReturn(CheckConstraintMaxValue("value", value, 5U)); } break; case 2: @@ -52683,6 +52684,15 @@ class Test_TC_OO_1_1Suite : public TestCommand } break; case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint32_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32")); + VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 2UL)); + } + break; + case 5: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); { chip::app::DataModel::DecodableList value; @@ -52697,7 +52707,7 @@ class Test_TC_OO_1_1Suite : public TestCommand VerifyOrReturn(CheckConstraintContains("value", value, 65533UL)); } break; - case 5: + case 6: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); { chip::app::DataModel::DecodableList value; @@ -52709,7 +52719,7 @@ class Test_TC_OO_1_1Suite : public TestCommand VerifyOrReturn(CheckConstraintContains("value", value, 16387UL)); } break; - case 6: + case 7: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); { chip::app::DataModel::DecodableList value; @@ -52720,7 +52730,7 @@ class Test_TC_OO_1_1Suite : public TestCommand VerifyOrReturn(CheckConstraintContains("value", value, 2UL)); } break; - case 7: + case 8: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); { chip::app::DataModel::DecodableList value; @@ -52731,7 +52741,7 @@ class Test_TC_OO_1_1Suite : public TestCommand VerifyOrReturn(CheckConstraintContains("value", value, 66UL)); } break; - case 8: + case 9: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); { chip::app::DataModel::DecodableList value; @@ -52743,7 +52753,7 @@ class Test_TC_OO_1_1Suite : public TestCommand VerifyOrReturn(CheckConstraintType("value", "list", "list")); } break; - case 9: + case 10: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); shouldContinue = true; break; @@ -52776,7 +52786,7 @@ class Test_TC_OO_1_1Suite : public TestCommand } case 2: { LogStep(2, "Read the global attribute: FeatureMap"); - VerifyOrDo(!ShouldSkip(" !OO.S.F00 "), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + VerifyOrDo(!ShouldSkip("( !OO.S.F00 && !OO.S.F01 )"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::FeatureMap::Id, true, chip::NullOptional); } @@ -52787,34 +52797,40 @@ class Test_TC_OO_1_1Suite : public TestCommand chip::NullOptional); } case 4: { - LogStep(4, "Read the global attribute: AttributeList"); - return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AttributeList::Id, true, + LogStep(4, "Given OO.S.F01(DF) ensure featuremap has the correct bit set"); + VerifyOrDo(!ShouldSkip("OO.S.F01"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::FeatureMap::Id, true, chip::NullOptional); } case 5: { - LogStep(5, "Read the feature dependent(OO.S.F00) attribute in AttributeList"); - VerifyOrDo(!ShouldSkip("OO.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + LogStep(5, "Read the global attribute: AttributeList"); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AttributeList::Id, true, chip::NullOptional); } case 6: { - LogStep(6, "Read the global attribute: AcceptedCommandList"); - return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AcceptedCommandList::Id, true, + LogStep(6, "Read the feature dependent(OO.S.F00) attribute in AttributeList"); + VerifyOrDo(!ShouldSkip("OO.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AttributeList::Id, true, chip::NullOptional); } case 7: { - LogStep(7, "Read the feature dependent(OO.S.F00) commands in AcceptedCommandList"); - VerifyOrDo(!ShouldSkip("OO.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + LogStep(7, "Read the global attribute: AcceptedCommandList"); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AcceptedCommandList::Id, true, chip::NullOptional); } case 8: { - LogStep(8, "Read the global attribute: GeneratedCommandList"); - return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::GeneratedCommandList::Id, true, + LogStep(8, "Read the feature dependent(OO.S.F00) commands in AcceptedCommandList"); + VerifyOrDo(!ShouldSkip("OO.S.F00"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::AcceptedCommandList::Id, true, chip::NullOptional); } case 9: { - LogStep(9, + LogStep(9, "Read the global attribute: GeneratedCommandList"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), OnOff::Id, OnOff::Attributes::GeneratedCommandList::Id, true, + chip::NullOptional); + } + case 10: { + LogStep(10, "Read EventList attribute from the DUT.For this cluster the list is usually empty but it can contain " "manufacturer specific event IDs."); VerifyOrDo(!ShouldSkip("PICS_USER_PROMPT"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index 8cbd89fe9f47cf..ce2f23e21bf64d 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -60185,7 +60185,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { break; case 2: ChipLogProgress(chipTool, " ***** Test Step 2 : Read the global attribute: FeatureMap\n"); - if (ShouldSkip(" !OO.S.F00 ")) { + if (ShouldSkip("( !OO.S.F00 && !OO.S.F01 )")) { NextTest(); return; } @@ -60200,43 +60200,51 @@ class Test_TC_OO_1_1 : public TestCommandBridge { err = TestGivenOosf00ltEnsureFeaturemapHasTheCorrectBitSet_3(); break; case 4: - ChipLogProgress(chipTool, " ***** Test Step 4 : Read the global attribute: AttributeList\n"); - err = TestReadTheGlobalAttributeAttributeList_4(); + ChipLogProgress(chipTool, " ***** Test Step 4 : Given OO.S.F01(DF) ensure featuremap has the correct bit set\n"); + if (ShouldSkip("OO.S.F01")) { + NextTest(); + return; + } + err = TestGivenOosf01dfEnsureFeaturemapHasTheCorrectBitSet_4(); break; case 5: - ChipLogProgress(chipTool, " ***** Test Step 5 : Read the feature dependent(OO.S.F00) attribute in AttributeList\n"); + ChipLogProgress(chipTool, " ***** Test Step 5 : Read the global attribute: AttributeList\n"); + err = TestReadTheGlobalAttributeAttributeList_5(); + break; + case 6: + ChipLogProgress(chipTool, " ***** Test Step 6 : Read the feature dependent(OO.S.F00) attribute in AttributeList\n"); if (ShouldSkip("OO.S.F00")) { NextTest(); return; } - err = TestReadTheFeatureDependentOOSF00AttributeInAttributeList_5(); - break; - case 6: - ChipLogProgress(chipTool, " ***** Test Step 6 : Read the global attribute: AcceptedCommandList\n"); - err = TestReadTheGlobalAttributeAcceptedCommandList_6(); + err = TestReadTheFeatureDependentOOSF00AttributeInAttributeList_6(); break; case 7: + ChipLogProgress(chipTool, " ***** Test Step 7 : Read the global attribute: AcceptedCommandList\n"); + err = TestReadTheGlobalAttributeAcceptedCommandList_7(); + break; + case 8: ChipLogProgress( - chipTool, " ***** Test Step 7 : Read the feature dependent(OO.S.F00) commands in AcceptedCommandList\n"); + chipTool, " ***** Test Step 8 : Read the feature dependent(OO.S.F00) commands in AcceptedCommandList\n"); if (ShouldSkip("OO.S.F00")) { NextTest(); return; } - err = TestReadTheFeatureDependentOOSF00CommandsInAcceptedCommandList_7(); - break; - case 8: - ChipLogProgress(chipTool, " ***** Test Step 8 : Read the global attribute: GeneratedCommandList\n"); - err = TestReadTheGlobalAttributeGeneratedCommandList_8(); + err = TestReadTheFeatureDependentOOSF00CommandsInAcceptedCommandList_8(); break; case 9: + ChipLogProgress(chipTool, " ***** Test Step 9 : Read the global attribute: GeneratedCommandList\n"); + err = TestReadTheGlobalAttributeGeneratedCommandList_9(); + break; + case 10: ChipLogProgress(chipTool, - " ***** Test Step 9 : Read EventList attribute from the DUT.For this cluster the list is usually empty but it can " + " ***** Test Step 10 : Read EventList attribute from the DUT.For this cluster the list is usually empty but it can " "contain manufacturer specific event IDs.\n"); if (ShouldSkip("PICS_USER_PROMPT")) { NextTest(); return; } - err = TestReadEventListAttributeFromTheDUTForThisClusterTheListIsUsuallyEmptyButItCanContainManufacturerSpecificEventIDs_9(); + err = TestReadEventListAttributeFromTheDUTForThisClusterTheListIsUsuallyEmptyButItCanContainManufacturerSpecificEventIDs_10(); break; } @@ -60279,6 +60287,9 @@ class Test_TC_OO_1_1 : public TestCommandBridge { case 9: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; } // Go on to the next test. @@ -60292,7 +60303,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { private: std::atomic_uint16_t mTestIndex; - const uint16_t mTestCount = 10; + const uint16_t mTestCount = 11; chip::Optional mNodeId; chip::Optional mCluster; @@ -60319,12 +60330,10 @@ class Test_TC_OO_1_1 : public TestCommandBridge { VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - { - id actualValue = value; - VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 4U)); - } - VerifyOrReturn(CheckConstraintType("clusterRevision", "int16u", "int16u")); + VerifyOrReturn(CheckConstraintMinValue("clusterRevision", [value unsignedShortValue], 4U)); + VerifyOrReturn(CheckConstraintMaxValue("clusterRevision", [value unsignedShortValue], 5U)); + NextTest(); }]; @@ -60374,7 +60383,26 @@ class Test_TC_OO_1_1 : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestReadTheGlobalAttributeAttributeList_4() + CHIP_ERROR TestGivenOosf01dfEnsureFeaturemapHasTheCorrectBitSet_4() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"Given OO.S.F01(DF) ensure featuremap has the correct bit set Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32")); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadTheGlobalAttributeAttributeList_5() { MTRBaseDevice * device = GetDevice("alpha"); @@ -60401,7 +60429,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestReadTheFeatureDependentOOSF00AttributeInAttributeList_5() + CHIP_ERROR TestReadTheFeatureDependentOOSF00AttributeInAttributeList_6() { MTRBaseDevice * device = GetDevice("alpha"); @@ -60425,7 +60453,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestReadTheGlobalAttributeAcceptedCommandList_6() + CHIP_ERROR TestReadTheGlobalAttributeAcceptedCommandList_7() { MTRBaseDevice * device = GetDevice("alpha"); @@ -60448,7 +60476,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestReadTheFeatureDependentOOSF00CommandsInAcceptedCommandList_7() + CHIP_ERROR TestReadTheFeatureDependentOOSF00CommandsInAcceptedCommandList_8() { MTRBaseDevice * device = GetDevice("alpha"); @@ -60471,7 +60499,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestReadTheGlobalAttributeGeneratedCommandList_8() + CHIP_ERROR TestReadTheGlobalAttributeGeneratedCommandList_9() { MTRBaseDevice * device = GetDevice("alpha"); @@ -60496,7 +60524,7 @@ class Test_TC_OO_1_1 : public TestCommandBridge { } CHIP_ERROR - TestReadEventListAttributeFromTheDUTForThisClusterTheListIsUsuallyEmptyButItCanContainManufacturerSpecificEventIDs_9() + TestReadEventListAttributeFromTheDUTForThisClusterTheListIsUsuallyEmptyButItCanContainManufacturerSpecificEventIDs_10() { chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; From 9cfbdfe7fb8f569b9df14ebabf10479145c75bf9 Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:59:31 +0800 Subject: [PATCH 4/5] [ota] rework ota - use ameba matter porting layer (#27513) - erase flash will not block for 20seconds --- src/platform/Ameba/AmebaOTAImageProcessor.cpp | 256 +++--------------- src/platform/Ameba/AmebaOTAImageProcessor.h | 23 -- 2 files changed, 36 insertions(+), 243 deletions(-) diff --git a/src/platform/Ameba/AmebaOTAImageProcessor.cpp b/src/platform/Ameba/AmebaOTAImageProcessor.cpp index e605ba7741fb4a..57aeb2205a5473 100644 --- a/src/platform/Ameba/AmebaOTAImageProcessor.cpp +++ b/src/platform/Ameba/AmebaOTAImageProcessor.cpp @@ -19,12 +19,10 @@ #include #include #include - #include +#include -#if defined(CONFIG_PLATFORM_8710C) -static flash_t flash_ota; -#endif +using namespace chip::DeviceLayer::Internal; namespace chip { @@ -127,18 +125,8 @@ void AmebaOTAImageProcessor::HandlePrepareDownload(intptr_t context) imageProcessor->mHeaderParser.Init(); - // Get OTA update partition -#if defined(CONFIG_PLATFORM_8721D) - if (ota_get_cur_index() == OTA_INDEX_1) - imageProcessor->ota_target_index = OTA_INDEX_2; - else if (ota_get_cur_index() == OTA_INDEX_2) - imageProcessor->ota_target_index = OTA_INDEX_1; - ChipLogProgress(SoftwareUpdate, "OTA%d address space will be upgraded", imageProcessor->ota_target_index + 1); -#elif defined(CONFIG_PLATFORM_8710C) - imageProcessor->flash_addr = sys_update_ota_prepare_addr(); - ChipLogProgress(SoftwareUpdate, "New Flash Address: 0x%X", imageProcessor->flash_addr); -#endif - + // prepare OTA update partition + matter_ota_prepare_partition(); imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); } @@ -151,15 +139,11 @@ void AmebaOTAImageProcessor::HandleFinalize(intptr_t context) return; } - // Verify checksum -#if defined(CONFIG_PLATFORM_8721D) - if (verify_ota_checksum(imageProcessor->pOtaTgtHdr) != 1) + if (AmebaUtils::MapError(matter_ota_flush_last(), AmebaErrorType::kFlashError) != CHIP_NO_ERROR) { - ota_update_free(imageProcessor->pOtaTgtHdr); - ChipLogError(SoftwareUpdate, "OTA checksum verification failed"); + ChipLogError(SoftwareUpdate, "Failed to finalize OTA"); return; } -#endif imageProcessor->ReleaseBlock(); @@ -175,24 +159,8 @@ void AmebaOTAImageProcessor::HandleAbort(intptr_t context) return; } - // Abort OTA procedure -#if defined(CONFIG_PLATFORM_8721D) - ChipLogProgress(SoftwareUpdate, "Erasing target partition..."); - erase_ota_target_flash(imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr, imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgLen); - ChipLogProgress(SoftwareUpdate, "Erased partition OTA%d", imageProcessor->ota_target_index + 1); -#elif defined(CONFIG_PLATFORM_8710C) - ChipLogProgress(SoftwareUpdate, "Erasing partition"); - imageProcessor->NewFWBlkSize = ((0x1AC000 - 1) / 4096) + 1; // Use a fixed image length of 0x1AC000, change in the future - ChipLogProgress(SoftwareUpdate, "Erasing %d sectors", imageProcessor->NewFWBlkSize); - device_mutex_lock(RT_DEV_LOCK_FLASH); - for (int i = 0; i < imageProcessor->NewFWBlkSize; i++) - flash_erase_sector(&flash_ota, imageProcessor->flash_addr + i * 4096); - device_mutex_unlock(RT_DEV_LOCK_FLASH); -#endif - -#if defined(CONFIG_PLATFORM_8721D) - ota_update_free(imageProcessor->pOtaTgtHdr); -#endif + // to make flash erase non-blocking, create background task to cleanup flash, will self-delete upon completion + matter_ota_create_abort_task(); imageProcessor->ReleaseBlock(); } @@ -211,185 +179,47 @@ void AmebaOTAImageProcessor::HandleProcessBlock(intptr_t context) return; } - ByteSpan block = imageProcessor->mBlock; - CHIP_ERROR error = imageProcessor->ProcessHeader(block); - uint8_t HeaderOffset = 32 - imageProcessor->RemainHeader; + ByteSpan block = imageProcessor->mBlock; + CHIP_ERROR error = imageProcessor->ProcessHeader(block); // process matter ota header + uint8_t remainHeader = + matter_ota_get_total_header_size() - matter_ota_get_current_header_size(); // size of ameba header received + uint16_t writeLength = block.size(); // length of actual data to write to flash, excluding header + uint8_t * writePointer = (uint8_t *) block.data(); // pointer to the actual data to write to flash, excluding header -#if defined(CONFIG_PLATFORM_8721D) - if (imageProcessor->RemainHeader != 0) // Still not yet received full ameba header + // 1. Check if 32-bytes Ameba header has already been received + if (remainHeader > 0) { - if (block.size() >= imageProcessor->RemainHeader) + if (block.size() >= remainHeader) { - memcpy(imageProcessor->AmebaHeader + HeaderOffset, block.data(), imageProcessor->RemainHeader); - imageProcessor->pOtaTgtHdr = (update_ota_target_hdr *) ota_update_malloc(sizeof(update_ota_target_hdr)); - - memcpy(imageProcessor->pOtaTgtHdr, imageProcessor->AmebaHeader, 8); // Store FwVer, HdrNum - memcpy(&(imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgId), imageProcessor->AmebaHeader + 8, 4); // Store OTA id - memcpy(&(imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgHdrLen), imageProcessor->AmebaHeader + 12, - 16); // Store ImgHdrLen, Checksum, ImgLen, Offset - - if (imageProcessor->ota_target_index == OTA_INDEX_1) - imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr = LS_IMG2_OTA1_ADDR; - else if (imageProcessor->ota_target_index == OTA_INDEX_2) - imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr = LS_IMG2_OTA2_ADDR; - - imageProcessor->pOtaTgtHdr->ValidImgCnt = 1; - - if (strncmp("OTA", (const char *) &(imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgId), 3) != 0) + if (AmebaUtils::MapError(matter_ota_store_header((uint8_t *) block.data(), remainHeader), + AmebaErrorType::kFlashError) != CHIP_NO_ERROR) { - ota_update_free(imageProcessor->pOtaTgtHdr); - ChipLogError(SoftwareUpdate, "Wrong Image ID for OTA"); + ChipLogError(SoftwareUpdate, "Failed to store OTA header"); return; } - - ChipLogProgress(SoftwareUpdate, "Correct OTA Image ID, get firmware header success"); - ChipLogProgress(SoftwareUpdate, "FwVer: 0x%X", imageProcessor->pOtaTgtHdr->FileHdr.FwVer); - ChipLogProgress(SoftwareUpdate, "HdrNum: 0x%X", imageProcessor->pOtaTgtHdr->FileHdr.HdrNum); - ChipLogProgress(SoftwareUpdate, "ImgHdrLen: 0x%X", imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgHdrLen); - ChipLogProgress(SoftwareUpdate, "Checksum: 0x%X", imageProcessor->pOtaTgtHdr->FileImgHdr[0].Checksum); - ChipLogProgress(SoftwareUpdate, "ImgLen: 0x%X", imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgLen); - ChipLogProgress(SoftwareUpdate, "Offset: 0x%X", imageProcessor->pOtaTgtHdr->FileImgHdr[0].Offset); - ChipLogProgress(SoftwareUpdate, "FlashAddr: 0x%X", imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr); - - // Erase update partition - ChipLogProgress(SoftwareUpdate, "Erasing target partition..."); - erase_ota_target_flash(imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr, - imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgLen); - ChipLogProgress(SoftwareUpdate, "Erased partition OTA%d", imageProcessor->ota_target_index + 1); - - // Set RemainBytes to image length, excluding 8bytes of signature - imageProcessor->RemainBytes = imageProcessor->pOtaTgtHdr->FileImgHdr[0].ImgLen - 8; - - // Set flash address, incremented by 8bytes to account for signature - imageProcessor->flash_addr = imageProcessor->pOtaTgtHdr->FileImgHdr[0].FlashAddr - SPI_FLASH_BASE + 8; - - // Set signature to point to pOtaTgtHdr->Sign - imageProcessor->signature = &(imageProcessor->pOtaTgtHdr->Sign[0][0]); - - // Store the signature temporarily - uint8_t * tempbufptr = const_cast(block.data() + imageProcessor->pOtaTgtHdr->FileImgHdr[0].Offset); - memcpy(imageProcessor->signature, tempbufptr, 8); - tempbufptr += 8; - - // Write remaining downloaded bytes to flash_addr - uint32_t tempsize = block.size() - imageProcessor->pOtaTgtHdr->FileImgHdr[0].Offset - 8; - device_mutex_lock(RT_DEV_LOCK_FLASH); - if (ota_writestream_user(imageProcessor->flash_addr + imageProcessor->size, tempsize, tempbufptr) < 0) - { - ChipLogError(SoftwareUpdate, "Write to flash failed"); - device_mutex_unlock(RT_DEV_LOCK_FLASH); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; - } - device_mutex_unlock(RT_DEV_LOCK_FLASH); - - imageProcessor->RemainHeader = 0; - imageProcessor->size += tempsize; - imageProcessor->RemainBytes -= tempsize; + writeLength -= remainHeader; + writePointer += remainHeader; } - else // block.size < imageProcessor->RemainHeader - { - memcpy(imageProcessor->AmebaHeader + HeaderOffset, block.data(), block.size()); - imageProcessor->RemainHeader -= block.size(); - } - } - else // received subsequent blocks - { - device_mutex_lock(RT_DEV_LOCK_FLASH); - if (ota_writestream_user(imageProcessor->flash_addr + imageProcessor->size, block.size(), block.data()) < 0) - { - ChipLogError(SoftwareUpdate, "Write to flash failed"); - device_mutex_unlock(RT_DEV_LOCK_FLASH); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; - } - device_mutex_unlock(RT_DEV_LOCK_FLASH); - - imageProcessor->size += block.size(); - imageProcessor->RemainBytes -= block.size(); - } -#elif defined(CONFIG_PLATFORM_8710C) - if (imageProcessor->RemainHeader != 0) // Still not yet received full ameba header - { - if (block.size() >= imageProcessor->RemainHeader) + else { - // Store signature temporarily - memcpy(imageProcessor->signature + HeaderOffset, block.data(), imageProcessor->RemainHeader); - - imageProcessor->block_len = block.size() - 32; // minus 32 to account for signature - - // Erase target partition - ChipLogProgress(SoftwareUpdate, "Erasing partition"); - imageProcessor->NewFWBlkSize = - ((0x1AC000 - 1) / 4096) + 1; // Use a fixed image length of 0x1AC000, change in the future - ChipLogProgress(SoftwareUpdate, "Erasing %d sectors", imageProcessor->NewFWBlkSize); - device_mutex_lock(RT_DEV_LOCK_FLASH); - for (int i = 0; i < imageProcessor->NewFWBlkSize; i++) - flash_erase_sector(&flash_ota, imageProcessor->flash_addr + i * 4096); - device_mutex_unlock(RT_DEV_LOCK_FLASH); - - // Write first block to target flash - if (imageProcessor->block_len > 0) - { - device_mutex_lock(RT_DEV_LOCK_FLASH); - if (flash_burst_write(&flash_ota, imageProcessor->flash_addr + 32, imageProcessor->block_len, block.data() + 32) < - 0) - { - device_mutex_unlock(RT_DEV_LOCK_FLASH); - ChipLogError(SoftwareUpdate, "Write to flash failed"); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; - } - else - { - imageProcessor->size += imageProcessor->block_len; - device_mutex_unlock(RT_DEV_LOCK_FLASH); - } - } - else + if (AmebaUtils::MapError(matter_ota_store_header((uint8_t *) block.data(), block.size()), + AmebaErrorType::kFlashError) != CHIP_NO_ERROR) { - ChipLogError(SoftwareUpdate, "Invalid size"); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + ChipLogError(SoftwareUpdate, "Failed to store OTA header"); return; } - - imageProcessor->RemainHeader = 0; - } - else // block.size() < imageProcessor->RemainHeader - { - memcpy(imageProcessor->AmebaHeader + HeaderOffset, block.data(), block.size()); - imageProcessor->RemainHeader -= block.size(); + writeLength = 0; } } - else // received subsequent blocks - { - imageProcessor->block_len = block.size(); - if (imageProcessor->block_len > 0) - { - device_mutex_lock(RT_DEV_LOCK_FLASH); - if (flash_burst_write(&flash_ota, imageProcessor->flash_addr + 32 + imageProcessor->size, imageProcessor->block_len, - block.data()) < 0) - { - device_mutex_unlock(RT_DEV_LOCK_FLASH); - ChipLogError(SoftwareUpdate, "Write to flash failed"); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; - } - else - { - imageProcessor->size += imageProcessor->block_len; - device_mutex_unlock(RT_DEV_LOCK_FLASH); - } - } - else - { - ChipLogError(SoftwareUpdate, "Invalid size"); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; - } + // 2. Write data to flash, flash erasure logic will be handled by lower layer + if (AmebaUtils::MapError(matter_ota_flash_burst_write(writePointer, writeLength), AmebaErrorType::kFlashError) != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "OTA write failed"); + return; } -#endif + + // 3. Fetch next data block imageProcessor->mParams.downloadedBytes += block.size(); imageProcessor->mDownloader->FetchNextData(); } @@ -405,26 +235,12 @@ void AmebaOTAImageProcessor::HandleApply(intptr_t context) } // Update signature -#if defined(CONFIG_PLATFORM_8721D) - if (change_ota_signature(imageProcessor->pOtaTgtHdr, imageProcessor->ota_target_index) != 1) + if (AmebaUtils::MapError(matter_ota_update_signature(), AmebaErrorType::kFlashError) != CHIP_NO_ERROR) { - ota_update_free(imageProcessor->pOtaTgtHdr); ChipLogError(SoftwareUpdate, "OTA update signature failed"); GetRequestorInstance()->CancelImageUpdate(); return; } -#elif defined(CONFIG_PLATFORM_8710C) - if (update_ota_signature(imageProcessor->signature, imageProcessor->flash_addr) < 0) - { - ChipLogError(SoftwareUpdate, "OTA update signature failed"); - GetRequestorInstance()->CancelImageUpdate(); - return; - } -#endif - -#if defined(CONFIG_PLATFORM_8721D) - ota_update_free(imageProcessor->pOtaTgtHdr); -#endif ChipLogProgress(SoftwareUpdate, "Rebooting in 10 seconds..."); @@ -434,7 +250,7 @@ void AmebaOTAImageProcessor::HandleApply(intptr_t context) void AmebaOTAImageProcessor::HandleRestart(chip::System::Layer * systemLayer, void * appState) { - ota_platform_reset(); + matter_ota_platform_reset(); } CHIP_ERROR AmebaOTAImageProcessor::ProcessHeader(ByteSpan & block) diff --git a/src/platform/Ameba/AmebaOTAImageProcessor.h b/src/platform/Ameba/AmebaOTAImageProcessor.h index 3d05b203bcabb5..a7901d7789bb55 100644 --- a/src/platform/Ameba/AmebaOTAImageProcessor.h +++ b/src/platform/Ameba/AmebaOTAImageProcessor.h @@ -25,14 +25,6 @@ #include #include -#if defined(CONFIG_PLATFORM_8710C) -#include "ota_8710c.h" -#include "sys.h" -#include "sys_api.h" -#elif defined(CONFIG_PLATFORM_8721D) -#include "rtl8721d_ota.h" -#endif - namespace chip { class AmebaOTAImageProcessor : public OTAImageProcessorInterface @@ -69,23 +61,8 @@ class AmebaOTAImageProcessor : public OTAImageProcessorInterface */ CHIP_ERROR ReleaseBlock(); -#if defined(CONFIG_PLATFORM_8721D) - uint32_t ota_target_index = OTA_INDEX_2; - update_ota_target_hdr * pOtaTgtHdr; - uint32_t RemainBytes; - uint8_t * signature; -#elif defined(CONFIG_PLATFORM_8710C) - uint32_t ota_target_index; - uint32_t NewFWBlkSize = 0; - uint32_t block_len = 0; - uint8_t signature[32]; -#endif MutableByteSpan mBlock; OTADownloader * mDownloader; - uint32_t size = 0; - uint8_t RemainHeader = 32; - uint8_t AmebaHeader[32] = { 0 }; - uint32_t flash_addr; OTAImageHeaderParser mHeaderParser; uint32_t mSoftwareVersion; }; From 7a815f675c15e7b9d35bddde1324306ce7887b9e Mon Sep 17 00:00:00 2001 From: Artur Tynecki <77382963+ATmobica@users.noreply.github.com> Date: Tue, 18 Jul 2023 21:00:15 +0200 Subject: [PATCH 5/5] [OIS] OTA requestor and DFU implementation (#27573) * [OIS] Add OTAImageProcessorImpl class Provides the implementation of the OTA Image Processor class for Open IOT SDK platform. Signed-off-by: ATmobica * [OIS] Add Matter OTA support Add Device Firmware Update manager class implementation. It provides firmware update functionality based on Matter OTA Requestor cluster. Add OTA enable support flag in Cmake build, passing it to Matter stack build. Add DFU manager to OIS platform code. Add post-build command to create OTA update image from signed binary. Extend OIS example documentation with TF-M and DFU support. Signed-off-by: ATmobica * [OIS] Add OTA Requestor application OIS implementation of OTA requestor example. Add new example to build script and VScode tasks. Signed-off-by: ATmobica * [OIS] Extend integration tests suite Add updateBinaryPath, otaProvider and softwareVersion options to OIS integraiton test suite. Propagating them to fixtures module. Add terminal device implementation. Run Linux applications as subprocess, read/write process output/input. Add ota_provider fixture - run OTA provider application as terminal device. Signed-off-by: ATmobica * [OIS] Add OTA requestor integration test and CI Add OTA requestor integration test implementation. Add OTA requestor test options in run script. Extending OIS workflow with build the OTA requestor example, build the OTA provider (Linux), test OTA requestor example. Signed-off-by: ATmobica --------- Signed-off-by: ATmobica --- .github/workflows/examples-openiotsdk.yaml | 32 +- config/openiotsdk/CMakeLists.txt | 1 + config/openiotsdk/cmake/chip.cmake | 1 + config/openiotsdk/cmake/sdk.cmake | 36 ++ docs/guides/README.md | 1 + docs/guides/openiotsdk_examples.md | 47 ++- .../openiotsdk_examples_software_update.md | 229 ++++++++++++ .../ota-requestor-app/openiotsdk/.gitignore | 1 + .../openiotsdk/CMakeLists.txt | 64 ++++ .../ota-requestor-app/openiotsdk/README.md | 81 +++++ .../openiotsdk/cmsis-config/RTE_Components.h | 22 ++ .../freertos-config/FreeRTOSConfig.h | 257 ++++++++++++++ .../main/include/CHIPProjectConfig.h | 26 ++ .../openiotsdk/main/main_ns.cpp | 64 ++++ .../openiotsdk/tf-m-config/TfmProjectConfig.h | 168 +++++++++ .../platform/openiotsdk/app/CMakeLists.txt | 17 + .../app/dfu/openiotsdk_dfu_manager.cpp | 68 ++++ .../app/dfu/openiotsdk_dfu_manager.h | 65 ++++ .../openiotsdk/app/openiotsdk_platform.cpp | 13 + .../openiotsdk/supported_examples.txt | 1 + scripts/examples/openiotsdk_example.sh | 12 + src/platform/openiotsdk/BUILD.gn | 7 + .../openiotsdk/OTAImageProcessorImpl.cpp | 331 ++++++++++++++++++ .../openiotsdk/OTAImageProcessorImpl.h | 95 +++++ .../integration-tests/common/fixtures.py | 38 ++ .../common/terminal_device.py | 95 +++++ .../openiotsdk/integration-tests/conftest.py | 6 + .../ota-requestor-app/__init__.py | 0 .../ota-requestor-app/test_app.py | 190 ++++++++++ 29 files changed, 1966 insertions(+), 2 deletions(-) create mode 100644 docs/guides/openiotsdk_examples_software_update.md create mode 100644 examples/ota-requestor-app/openiotsdk/.gitignore create mode 100644 examples/ota-requestor-app/openiotsdk/CMakeLists.txt create mode 100644 examples/ota-requestor-app/openiotsdk/README.md create mode 100644 examples/ota-requestor-app/openiotsdk/cmsis-config/RTE_Components.h create mode 100644 examples/ota-requestor-app/openiotsdk/freertos-config/FreeRTOSConfig.h create mode 100644 examples/ota-requestor-app/openiotsdk/main/include/CHIPProjectConfig.h create mode 100644 examples/ota-requestor-app/openiotsdk/main/main_ns.cpp create mode 100644 examples/ota-requestor-app/openiotsdk/tf-m-config/TfmProjectConfig.h create mode 100644 examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.cpp create mode 100644 examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.h create mode 100644 src/platform/openiotsdk/OTAImageProcessorImpl.cpp create mode 100644 src/platform/openiotsdk/OTAImageProcessorImpl.h create mode 100644 src/test_driver/openiotsdk/integration-tests/common/terminal_device.py create mode 100644 src/test_driver/openiotsdk/integration-tests/ota-requestor-app/__init__.py create mode 100644 src/test_driver/openiotsdk/integration-tests/ota-requestor-app/test_app.py diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index 338067b53cbe63..e81e15635e607d 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -49,7 +49,7 @@ jobs: - name: Checkout submodules & Bootstrap uses: ./.github/actions/checkout-submodules-and-bootstrap with: - platform: openiotsdk + platform: openiotsdk linux extra-submodule-parameters: " --recursive" - name: Set up environment for size reports @@ -101,11 +101,28 @@ jobs: examples/all-clusters-app/openiotsdk/build/chip-openiotsdk-all-clusters-app-example.elf \ /tmp/bloat_reports/ + - name: Build ota-requestor-app example + id: build_ota_requestor_app + timeout-minutes: 10 + run: | + scripts/examples/openiotsdk_example.sh -v 1 -V 0.0.1 ota-requestor-app + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + openiotsdk release ota-requestor-app \ + examples/ota-requestor-app/openiotsdk/build/chip-openiotsdk-ota-requestor-app-example.elf \ + /tmp/bloat_reports/ + - name: Build unit tests (mbedtls) id: build_unit_tests_mbedtls run: | scripts/examples/openiotsdk_example.sh -b mbedtls unit-tests + - name: Build the OTA provider (Linux) + id: build_ota_provider_app + if: steps.build_ota_requestor_app.outcome == 'success' + timeout-minutes: 10 + run: | + scripts/examples/gn_build_example.sh examples/ota-provider-app/linux/ out/ota-provider chip_config_network_layer_ble=false + - name: "Test: shell example" if: steps.build_shell.outcome == 'success' run: | @@ -138,6 +155,19 @@ jobs: 'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -C test -n ${TEST_NETWORK_NAME}tap all-clusters-app' scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down + - name: "Test: ota-requestor-app example" + if: steps.build_ota_requestor_app.outcome == 'success' && steps.build_ota_provider_app.outcome == 'success' + timeout-minutes: 30 + run: | + mkdir out/binaries + cp examples/ota-requestor-app/openiotsdk/build/chip-openiotsdk-ota-requestor-app-example.elf out/binaries/ + scripts/examples/openiotsdk_example.sh -c -v 2 -V 0.0.2 ota-requestor-app + cp examples/ota-requestor-app/openiotsdk/build/chip-openiotsdk-ota-requestor-app-example.ota out/binaries/ + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME up + scripts/run_in_python_env.sh out/venv \ + 'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -p out/binaries -v 2 -V 0.0.2 -C test -n ${TEST_NETWORK_NAME}tap ota-requestor-app' + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down + - name: "Test: unit-tests (mbedtls)" if: steps.build_unit_tests_mbedtls.outcome == 'success' run: | diff --git a/config/openiotsdk/CMakeLists.txt b/config/openiotsdk/CMakeLists.txt index eca153e3f59505..ad659d091c4fd3 100644 --- a/config/openiotsdk/CMakeLists.txt +++ b/config/openiotsdk/CMakeLists.txt @@ -64,6 +64,7 @@ matter_add_gn_arg_bool ("chip_error_logging" CONFIG_CHIP_ERRO matter_add_gn_arg_string("chip_crypto" "${CONFIG_CHIP_CRYPTO}") matter_add_gn_arg_string("chip_openiotsdk_software_version" "${CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION}") matter_add_gn_arg_string("chip_openiotsdk_software_version_string" "${CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING}") +matter_add_gn_arg_bool ("chip_enable_ota_requestor" CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE) if (TARGET cmsis-rtos-api) matter_add_gn_arg_string("target_os" "cmsis-rtos") endif() diff --git a/config/openiotsdk/cmake/chip.cmake b/config/openiotsdk/cmake/chip.cmake index 7b5d77fddf0fdb..1cb5a61cdeff02 100644 --- a/config/openiotsdk/cmake/chip.cmake +++ b/config/openiotsdk/cmake/chip.cmake @@ -35,6 +35,7 @@ set(CONFIG_CHIP_ERROR_LOGGING YES CACHE BOOL "Enable logging at error level") set(CONFIG_CHIP_CRYPTO "mbedtls" CACHE STRING "Matter crypto backend. Mbedtls as default") set(CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION "0" CACHE STRING "Software version number") set(CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING ${TFM_NS_APP_VERSION} CACHE STRING "Software version in string format x.x.x") +set(CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE NO CACHE BOOL "Enable OTA support") set(CONFIG_GN_DEPENDENCIES "") if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") diff --git a/config/openiotsdk/cmake/sdk.cmake b/config/openiotsdk/cmake/sdk.cmake index f4d151455c6eea..cee548ae457d19 100644 --- a/config/openiotsdk/cmake/sdk.cmake +++ b/config/openiotsdk/cmake/sdk.cmake @@ -300,6 +300,42 @@ function(sdk_post_build target) VERBATIM ) iotsdk_tf_m_merge_images(${target} 0x10000000 0x38000000 0x28060000) +if(CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE) + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $/${target}.bin + COMMAND + # Sign the update image + python3 ${BINARY_DIR}/install/image_signing/scripts/wrapper/wrapper.py + --layout ${BINARY_DIR}/install/image_signing/layout_files/signing_layout_ns.o + -v ${MCUBOOT_IMAGE_VERSION_NS} + -k ${BINARY_DIR}/install/image_signing/keys/root-RSA-3072_1.pem + --public-key-format full + --align 1 --pad-header -H 0x400 -s auto -d "(0, 0.0.0+0)" + $/${target}.bin + --overwrite-only + --measured-boot-record + $/${target}_signed.ota + COMMAND + # Create OTA udpate file + ${CHIP_ROOT}/src/app/ota_image_tool.py + create + -v 0xfff1 -p 0x8001 + -vn ${CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION} + -vs "${CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING}" + -da sha256 + $/${target}_signed.ota + $/${APP_NAME}.ota + # Cleanup + COMMAND rm + ARGS -Rf + $/${target}_signed.ota + VERBATIM + ) +endif() # Cleanup add_custom_command( TARGET diff --git a/docs/guides/README.md b/docs/guides/README.md index d37c959e3a602c..552f3a30772327 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -27,6 +27,7 @@ - [Open IoT SDK - Examples](./openiotsdk_examples.md) - [Open IoT SDK - Unit Tests](./openiotsdk_unit_tests.md) - [Open IoT SDK - Commissioning](./openiotsdk_commissioning.md) +- [Open IoT SDK - Software Update](./openiotsdk_examples_software_update.md) ## Development Guides diff --git a/docs/guides/openiotsdk_examples.md b/docs/guides/openiotsdk_examples.md index d779f34b6c5358..b80ce6304f9ba0 100644 --- a/docs/guides/openiotsdk_examples.md +++ b/docs/guides/openiotsdk_examples.md @@ -12,6 +12,7 @@ shell lock-app tv-app all-clusters-app +ota-requestor-app ``` You can use these examples as a reference for creating your own applications. @@ -291,7 +292,20 @@ Processing Environment (`NSPE`). The bootloader and the secure part are also built from `TF-M` sources. All components are merged into a single executable file at the end of the building process. -You can also provide the own version of Matter example by setting +The project-specific configuration of `TF-M` can be provide by defining its own +header file for `TF-M` config and passing the path to it via the +`TFM_PROJECT_CONFIG_HEADER_FILE` variable. + +``` +set(TFM_PROJECT_CONFIG_HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/tf-m-config/TfmProjectConfig.h") +``` + +If the project-specific configuration is not provided the base `TF-M` settings +are used +[config_base.h](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/config/config_base.h). +It can be used as a pattern for the custom configuration header. + +You can also provide your own version of a Matter example by setting the `TFM_NS_APP_VERSION` variable. ``` @@ -365,6 +379,37 @@ cmake -G <...> -DCONFIG_CHIP_CRYPTO= <...> > The `TF-M PSA crypto` option requires enabling [TF-M](#trusted-firmware-m) > support. +### Device Firmware Update + +Device Firmware Update (`DFU`) can be enabled in the application by setting the +`CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE` variable: + +``` +set(CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE YES) +``` + +This provides the proper service for Matter's `OTA Requestor` cluster. The +[TF-M Firmware Update Service](https://arm-software.github.io/psa-api/fwu/1.0/) +is the backend for all firmware update operations. The `DFU Manager` module is +attached to the application and allows full usage of the `OTA Requestor` +cluster. + +You can also provide your own version of the Matter example to the Matter stack +by setting `CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION` and +`CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING` variables. + +``` +set(CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION "1") +set(CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING "0.0.1") +``` + +The default value for `CONFIG_CHIP_OPEN_IOT_SDK_SOFTWARE_VERSION_STRING` is set +to `TFM_NS_APP_VERSION`. + +> 💡 **Notes**: +> +> The `DFU` option requires enabling [TF-M](#trusted-firmware-m) support. + ## Building You can build examples using the dedicated VSCode task or by calling directly diff --git a/docs/guides/openiotsdk_examples_software_update.md b/docs/guides/openiotsdk_examples_software_update.md new file mode 100644 index 00000000000000..73129b84e50966 --- /dev/null +++ b/docs/guides/openiotsdk_examples_software_update.md @@ -0,0 +1,229 @@ +# Matter Open IoT SDK Example Device Firmware Upgrade + +Matter Open IoT SDK examples can support over-the-air (`OTA`) Device Firmware +Upgrade (`DFU`) based on Matter-compliant OTA update protocol that uses the +Matter operational network for querying and downloading a new firmware image. + +## Device Firmware Upgrade over Matter OTA cluster + +The `DFU` over Matter OTA clusters requires two kinds of nodes: + +- `OTA Provider` is an application that implements the OTA provider cluster + service. It can respond to the OTA Requestors' queries about available + software updates and share the update image with them. +- `OTA Requestor` is an application that implements the OTA requestor cluster + service. It can communicate with the OTA Provider to fetch applicable + software updates and apply them. + +The last required element is a Matter controller. This application controls both +nodes and manages the entire software update process. + +In the procedure described below, the `OTA Provider` will be a +[Linux application](../../examples/ota-provider-app/linux/README.md) and the +Open IoT SDK example with +[DFU support](./openiotsdk_examples.md#device-firmware-update) will work as the +OTA Requestor. The [chip-tool](../../examples/chip-tool/README.md) application +used as the Matter controller. Each application should be launched in a separate +terminal. + +List of `OIS` examples that currently support the `DFU` over Matter: + +- ota-requestor-app + +### Device Firmware Upgrade over Matter procedure + +1. Navigate to the CHIP root directory. + +2. Build the `OTA Provider` application: + + ``` + scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider chip_config_network_layer_ble=false + ``` + + More details about the `OTA provider` application can be found + [here](../../examples/ota-provider-app/linux/README.md). + +3. Build `chip-tool`: + + ``` + scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool + ``` + + More details about the `chip-tool` application can be found + [here](../../examples/chip-tool/README.md). + +4. Build `OIS` example application + + ``` + scripts/examples/openiotsdk_example.sh -v 1 -V 0.0.1 + ``` + + This is first version of the application that can be updated. + +5. Build `OIS` update image + + ``` + scripts/examples/openiotsdk_example.sh -p out/update -v 2 -V 0.0.2 + ``` + + Pass the build path (`-p out/update`) in this step to not override the + example application. In that directory you should find the update image file + with `.ota` extension (`chip-openiotsdk--example.ota`). + +6. Setup `OIS` network environment + + ``` + sudo ./scripts/setup/openiotsdk/network_setup.sh -n OISupdate up + ``` + + More details about `OIS` network environment can be found + [here](./openiotsdk_examples.md#networking-setup). + +7. In `terminal 1`: run the `OTA Provider` application in the network + environment and provide a path to the update image: + + ``` + scripts/run_in_ns.sh OISupdate out/ota-provider/chip-ota-provider-app --KVS /tmp/chip-ota-provider --discriminator 3841 --secured-device-port 5580 --filepath out/update/chip-openiotsdk--example.ota + ``` + + The node details should be printed: + + ``` + ... + CHIP:DL: Device Configuration: + CHIP:DL: Serial Number: TEST_SN + CHIP:DL: Vendor Id: 65521 (0xFFF1) + CHIP:DL: Product Id: 32769 (0x8001) + CHIP:DL: Hardware Version: 0 + CHIP:DL: Setup Pin Code (0 for UNKNOWN/ERROR): 20202021 + CHIP:DL: Setup Discriminator (0xFFFF for UNKNOWN/ERROR): 3841 (0xF01) + CHIP:DL: Manufacturing Date: (not set) + CHIP:DL: Device Type: 65535 (0xFFFF) + CHIP:SVR: SetupQRCode: [MT:-24J0IRV01KA0648G00] + CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: + CHIP:SVR: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J0IRV01KA0648G00 + CHIP:SVR: Manual pairing code: [34970112332] + CHIP:SWU: Using OTA file: out/update/chip-openiotsdk-ota-requestor-app-example.ota + ... + ``` + + > 💡 **Notes**: + > + > Set the custom Key Value Store path for `OTA provider`. + > + > The `OTA provider` discriminator must be different from the value used by + > the example application. `OIS` examples use the default discriminator + > value `3840`. + > + > The `OTA provider` UDP port must be different from the value used by the + > example application. `OIS` examples use the default discriminator value + > `5540`. + +8. In `terminal 2`: run the `OIS` example application in the network + environment: + + ``` + scripts/run_in_ns.sh OISupdate scripts/examples/openiotsdk_example.sh -C run -n OISupdatetap + ``` + + The node details should be printed to terminal: + + ``` + ... + [INF] [DL] Device Configuration: + [INF] [DL] Serial Number: TEST_SN + [INF] [DL] Vendor Id: 65521 (0xFFF1) + [INF] [DL] Product Id: 32769 (0x8001) + [INF] [DL] Hardware Version: 0 + [INF] [DL] Setup Pin Code (0 for UNKNOWN/ERROR): 20202021 + [INF] [DL] Setup Discriminator (0xFFFF for UNKNOWN/ERROR): 3840 (0xF00) + [INF] [DL] Manufacturing Date: (not set) + [INF] [DL] Device Type: 65535 (0xFFFF) + [INF] [SVR] SetupQRCode: [MT:-24J0AFN00KA0648G00] + [INF] [SVR] Copy/paste the below URL in a browser to see the QR Code: + [INF] [SVR] https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J0AFN00KA0648G00 + [INF] [SVR] Manual pairing code: [34970112332] + [INF] [-] Current software version: [1] 0.0.1 + [INF] [SWU] Stopping the watchdog timer + [INF] [SWU] Starting the periodic query timer, timeout: 86400 seconds + [INF] [-] Open IoT SDK ota-requestor-app example application run + ... + ``` + +9. In `terminal 3`: commission the `OTA Provider` application into the Matter + network: + + ``` + scripts/run_in_ns.sh OISupdate ./out/chip-tool/chip-tool pairing onnetwork-long 123 20202021 3841 + ``` + + Set node ID to `123`. + + The confirmation of commissioning success will be printed on the terminal: + + ``` + CHIP:SVR: Commissioning completed successfully + ``` + +10. In `terminal 3`: commission the `OIS` example application into the Matter + network: + + ``` + scripts/run_in_ns.sh OISupdate ./out/chip-tool/chip-tool pairing onnetwork-long 321 20202021 3840 + ``` + + Set node ID to `321`. + + The confirmation of commissioning success will be printed on the terminal: + + ``` + [INF] [SVR] Commissioning completed successfully + ``` + +11. In `terminal 3`: configure the `OTA Provider` with the access control list + (ACL) that grants _Operate_ privileges to all nodes in the fabric. This is + necessary to allow the nodes to send cluster commands to the `OTA Provider`: + + ``` + scripts/run_in_ns.sh OISupdate ./out/chip-tool/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [321], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 123 0 + ``` + +12. Initiate the `DFU` procedure: + + In `terminal 3`: send the `Announce OTA Provider` command to the example + application. The numeric arguments are: provider node ID, provider vendor + ID, announcement reason, provider endpoint ID, requestor node ID and + requestor Endpoint Id, respectively. + + ``` + scripts/run_in_ns.sh OISupdate ./out/chip-tool/chip-tool otasoftwareupdaterequestor announce-otaprovider 123 0 2 0 321 0 + ``` + + The example application is notified of the `OTA Provider` node and it + automatically queries for a new firmware image. If a new version of firmware + is available, the downloading step starts. + +13. When the firmware image download is complete, the device is automatically + rebooted to apply the update. + + The new version of firmware will be printed in the log `terminal 2`: + + ``` + ... + [INF] [-] Current software version: [2] 0.0.2 + ... + ``` + +14. Now, you can manually close the nodes applications and terminals sessions: + + - `OTA Provider` - `terminal 1` + - `OIS` example - `terminal 2`. More details about terminating `OIS` + example can be found [here](./openiotsdk_examples.md#running). + +15. Cleanup after update (disable network environment, remove `KVS` storage + files): + + ``` + sudo ./scripts/setup/openiotsdk/network_setup.sh -n OISupdate down + sudo rm /tmp/chip-ota-provider + ``` diff --git a/examples/ota-requestor-app/openiotsdk/.gitignore b/examples/ota-requestor-app/openiotsdk/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/examples/ota-requestor-app/openiotsdk/CMakeLists.txt b/examples/ota-requestor-app/openiotsdk/CMakeLists.txt new file mode 100644 index 00000000000000..a8b178aa5df9c9 --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/CMakeLists.txt @@ -0,0 +1,64 @@ +# +# 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. +# + +cmake_minimum_required(VERSION 3.21) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) +get_filename_component(OPEN_IOT_SDK_CONFIG ${CHIP_ROOT}/config/openiotsdk REALPATH) +get_filename_component(OPEN_IOT_SDK_EXAMPLE_COMMON ${CHIP_ROOT}/examples/platform/openiotsdk REALPATH) + +list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) + +set(APP_TARGET chip-openiotsdk-ota-requestor-app-example_ns) + +set(TFM_PROJECT_CONFIG_HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/tf-m-config/TfmProjectConfig.h") +set(CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE YES) + +# Toolchain files need to exist before first call to project +include(toolchain) + +project(${APP_TARGET} LANGUAGES C CXX ASM) + +include(sdk) + +add_executable(${APP_TARGET}) + +# Application CHIP build configuration +include(chip) + +add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) + +chip_add_data_model(openiotsdk-app PUBLIC ota-requestor) + +target_include_directories(${APP_TARGET} + PRIVATE + main/include +) + +target_sources(${APP_TARGET} + PRIVATE + main/main_ns.cpp +) + +target_link_libraries(${APP_TARGET} + openiotsdk-startup + openiotsdk-app +) + +include(linker) +set_target_link(${APP_TARGET}) + +sdk_post_build(${APP_TARGET}) diff --git a/examples/ota-requestor-app/openiotsdk/README.md b/examples/ota-requestor-app/openiotsdk/README.md new file mode 100644 index 00000000000000..d9a98c44d3888a --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/README.md @@ -0,0 +1,81 @@ +# Matter Open IoT SDK OTA-Requestor-App Example Application + +The Open IoT SDK OTA-Requestor Example demonstrates how to remotely trigger +update image downloading and apply it if needed. It provides the service for +Matter's `OTA` clusters. This application plays both roles: the server for the +`OTA Requestor` cluster, and the client of the `OTA Provider` cluster. It can +initiate a software update with a given `OTA Provider` node, download a binary +file and apply it. + +The application is configured to support: + +- [TF-M](../../../docs/guides/openiotsdk_examples.md#trusted-firmware-m) +- [Device Firmware Update](../../../docs/guides/openiotsdk_examples.md#device-firmware-update) + +The example behaves as a Matter accessory, device that can be paired into an +existing Matter network and can be controlled by it. + +## Build-run-test-debug + +For information on how to build, run, test and debug this example and further +information about the platform it is run on see +[Open IoT SDK examples](../../../docs/guides/openiotsdk_examples.md). + +The example name to use in the scripts is `ota-requestor-app`. + +## Example output + +When the example runs, these lines should be visible: + +``` +[INF] [-] Open IoT SDK ota-requestor-app example application start +... +[INF] [-] Open IoT SDK ota-requestor-app example application run +``` + +This means the ota-requestor-app application launched correctly and you can +follow traces in the terminal. + +### Commissioning + +Read the +[Open IoT SDK commissioning guide](../../../docs/guides/openiotsdk_commissioning.md) +to see how to use the Matter controller to commission and control the +application. + +### Device Firmware Upgrade + +Read the +[Matter Open IoT SDK Example Device Firmware Upgrade](../../../docs/guides/openiotsdk_examples_software_update.md) +to see how to use Matter OTA for firmware update. + +### OtaSoftwareUpdateRequestor cluster usage + +The application fully supports the `OTA Requestor` cluster. Use its commands to +trigger actions on the device. You can issue commands through the same Matter +controller you used to perform the commissioning step above. + +Example command: + +``` +chip-tool otasoftwareupdaterequestor announce-ota-provider 1234 0 2 0 4321 0 +``` + +The `OTA Requestor` application with node ID 1234 will process this command and +send a `QueryImage` command to the `OTA Provider` with node ID 4321. This starts +the `OTA` process. On receiving the `QueryImageResponse` from the `OTA Provider` +application, the `OTA Requestor` application will verify that the software +version specified in the `SoftwareVersion` field of the response contains a +value newer than the current running version. The available version will be +printed to the terminal, for example: + +``` +[INF] [-] New version of the software is available: 2 +``` + +If the validation does not pass the update will not proceed. The next step is +downloading the update image. If this step is completed, a new image will be +installed and the application will be reboot. + +More details about device firmware update over Matter can be found +[here](../../../docs/guides/openiotsdk_examples_software_update.md). diff --git a/examples/ota-requestor-app/openiotsdk/cmsis-config/RTE_Components.h b/examples/ota-requestor-app/openiotsdk/cmsis-config/RTE_Components.h new file mode 100644 index 00000000000000..e86df2b4e44e06 --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/cmsis-config/RTE_Components.h @@ -0,0 +1,22 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + +#endif // RTE_COMPONENTS_H diff --git a/examples/ota-requestor-app/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/ota-requestor-app/openiotsdk/freertos-config/FreeRTOSConfig.h new file mode 100644 index 00000000000000..9efedc9f133712 --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/freertos-config/FreeRTOSConfig.h @@ -0,0 +1,257 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) +#include + +extern uint32_t SystemCoreClock; +#endif + +// Minimal stack size [words] <0-65535> +// Stack for idle task and default task stack in words. +// Default: 4kB +#define configMINIMAL_STACK_SIZE ((uint16_t)(4 * 1024)) + +// Total heap size [bytes] <0-0xFFFFFFFF> +// Heap memory size in bytes. +// Default: 32kB +#define configTOTAL_HEAP_SIZE ((size_t)(32 * 1024)) + +// Kernel tick frequency [Hz] <0-0xFFFFFFFF> +// Kernel tick rate in Hz. +// Default: 1000 +#define configTICK_RATE_HZ ((TickType_t) 1000) + +// Timer task stack depth [words] <0-65535> +// Stack for timer task in words. +// Default: 80 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +// Timer task priority <0-56> +// Timer task priority. +// Default: 40 (High) +#define configTIMER_TASK_PRIORITY 40 + +// Timer queue length <0-1024> +// Timer command queue length. +// Default: 5 +#define configTIMER_QUEUE_LENGTH 5 + +// Preemption interrupt priority +// Maximum priority of interrupts that are safe to call FreeRTOS API. +// Default: 16 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (5 << (8 - configPRIO_BITS)) + +// Use time slicing +// Enable setting to use timeslicing. +// Default: 1 +#define configUSE_TIME_SLICING 1 + +// Idle should yield +// Control Yield behaviour of the idle task. +// Default: 1 +#define configIDLE_SHOULD_YIELD 1 + +// Check for stack overflow +// <0=>Disable <1=>Method one <2=>Method two +// Enable or disable stack overflow checking. +// Callback function vApplicationStackOverflowHook implementation is required when stack checking is enabled. +// Default: 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 + +// Use idle hook +// Enable callback function call on each idle task iteration. +// Callback function vApplicationIdleHook implementation is required when idle hook is enabled. +// Default: 0 +#define configUSE_IDLE_HOOK 0 + +// Use tick hook +// Enable callback function call during each tick interrupt. +// Callback function vApplicationTickHook implementation is required when tick hook is enabled. +// Default: 0 +#define configUSE_TICK_HOOK 0 + +// Use deamon task startup hook +// Enable callback function call when timer service starts. +// Callback function vApplicationDaemonTaskStartupHook implementation is required when deamon task startup hook is +// enabled. Default: 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +// Use malloc failed hook +// Enable callback function call when out of dynamic memory. +// Callback function vApplicationMallocFailedHook implementation is required when malloc failed hook is enabled. +// Default: 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +// Queue registry size +// Define maximum number of queue objects registered for debug purposes. +// The queue registry is used by kernel aware debuggers to locate queue and semaphore structures and display +// associated text names. Default: 0 +#define configQUEUE_REGISTRY_SIZE 0 + +// Event Recorder configuration +// Initialize and setup Event Recorder level filtering. +// Settings have no effect when Event Recorder is not present. + +// Initialize Event Recorder +// Initialize Event Recorder before FreeRTOS kernel start. +// Default: 1 +#define configEVR_INITIALIZE 1 + +// Setup recording level filter +// Enable configuration of FreeRTOS events recording level +// Default: 1 +#define configEVR_SETUP_LEVEL 1 + +// Tasks functions +// Define event recording level bitmask for events generated from Tasks functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TASKS 0x05 + +// Queue functions +// Define event recording level bitmask for events generated from Queue functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_QUEUE 0x05 + +// Timer functions +// Define event recording level bitmask for events generated from Timer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TIMERS 0x05 + +// Event Groups functions +// Define event recording level bitmask for events generated from Event Groups functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_EVENTGROUPS 0x05 + +// Heap functions +// Define event recording level bitmask for events generated from Heap functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_HEAP 0x05 + +// Stream Buffer functions +// Define event recording level bitmask for events generated from Stream Buffer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_STREAMBUFFER 0x05 +// +// + +// Port Specific Features +// Enable and configure port specific features. +// Check FreeRTOS documentation for definitions that apply for the used port. + +// Use Floating Point Unit +// Using Floating Point Unit (FPU) affects context handling. +// Enable FPU when application uses floating point operations. +// Default: 1 +#define configENABLE_FPU 1 + +// Use Memory Protection Unit +// Using Memory Protection Unit (MPU) requires detailed memory map definition. +// This setting is only releavant for MPU enabled ports. +// Default: 0 +#define configENABLE_MPU 0 + +// Use TrustZone Secure Side Only +// This settings prevents FreeRTOS contex switch to Non-Secure side. +// Enable this setting when FreeRTOS runs on the Secure side only. +#define configRUN_FREERTOS_SECURE_ONLY 0 + +// Use TrustZone Security Extension +// Using TrustZone affects context handling. +// Enable TrustZone when FreeRTOS runs on the Non-Secure side and calls functions from the Secure side. +// Default: 1 +#define configENABLE_TRUSTZONE 0 + +// Minimal secure stack size [words] <0-65535> +// Stack for idle task Secure side context in words. +// This setting is only relevant when TrustZone extension is enabled. +// Default: 128 +#define configMINIMAL_SECURE_STACK_SIZE ((uint32_t) 128) +// + +#ifdef __NVIC_PRIO_BITS +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 4 +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +/* Defines needed by FreeRTOS to implement CMSIS RTOS2 API. Do not change! */ +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_PREEMPTION 1 +#define configUSE_TIMERS 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configMAX_PRIORITIES 56 +#define configKERNEL_INTERRUPT_PRIORITY (0x07 << (8 - configPRIO_BITS)) + +/* Defines that include FreeRTOS functions which implement CMSIS RTOS2 API. Do not change! */ +#define INCLUDE_xEventGroupSetBitsFromISR 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskDelayUntil 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ +#define xPortPendSVHandler PendSV_Handler +#define vPortSVCHandler SVC_Handler + +/* Ensure Cortex-M port compatibility. */ +#define SysTick_Handler xPortSysTickHandler + +#include "RTE_Components.h" +#include CMSIS_device_header + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/ota-requestor-app/openiotsdk/main/include/CHIPProjectConfig.h b/examples/ota-requestor-app/openiotsdk/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..6a1fe3b8068078 --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/main/include/CHIPProjectConfig.h @@ -0,0 +1,26 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 diff --git a/examples/ota-requestor-app/openiotsdk/main/main_ns.cpp b/examples/ota-requestor-app/openiotsdk/main/main_ns.cpp new file mode 100644 index 00000000000000..31002663cc001a --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/main/main_ns.cpp @@ -0,0 +1,64 @@ +/* + * + * 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. + */ + +#include +#include + +#include + +#include "openiotsdk_platform.h" + +int main() +{ + ChipLogProgress(NotSpecified, "Open IoT SDK ota-requestor-app example application start"); + + if (openiotsdk_platform_init()) + { + ChipLogError(NotSpecified, "Open IoT SDK platform initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_chip_init()) + { + ChipLogError(NotSpecified, "Open IoT SDK CHIP stack initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_network_init(true)) + { + ChipLogError(NotSpecified, "Network initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_chip_run()) + { + ChipLogError(NotSpecified, "CHIP stack run failed"); + return EXIT_FAILURE; + } + + ChipLogProgress(NotSpecified, "Open IoT SDK ota-requestor-app example application run"); + + while (true) + { + // Add forever delay to ensure proper workload for this thread + osDelay(osWaitForever); + } + + openiotsdk_chip_shutdown(); + + return EXIT_SUCCESS; +} diff --git a/examples/ota-requestor-app/openiotsdk/tf-m-config/TfmProjectConfig.h b/examples/ota-requestor-app/openiotsdk/tf-m-config/TfmProjectConfig.h new file mode 100644 index 00000000000000..c32bddaba40d20 --- /dev/null +++ b/examples/ota-requestor-app/openiotsdk/tf-m-config/TfmProjectConfig.h @@ -0,0 +1,168 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#ifndef TFM_PROJECT_CONFIG_H +#define TFM_PROJECT_CONFIG_H + +/* Platform Partition Configs */ + +/* Size of input buffer in platform service */ +#define PLATFORM_SERVICE_INPUT_BUFFER_SIZE 64 + +/* Size of output buffer in platform service */ +#define PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE 64 + +/* The stack size of the Platform Secure Partition */ +#define PLATFORM_SP_STACK_SIZE 0x500 + +/* Disable Non-volatile counter module */ +#define PLATFORM_NV_COUNTER_MODULE_DISABLED 0 + +/* Crypto Partition Configs */ + +/* + * Heap size for the crypto backend + * CRYPTO_ENGINE_BUF_SIZE needs to be >8KB for EC signing by attest module. + */ +#define CRYPTO_ENGINE_BUF_SIZE 0x2080 + +/* The max number of concurrent operations that can be active (allocated) at any time in Crypto */ +#define CRYPTO_CONC_OPER_NUM 8 + +/* Enable PSA Crypto random number generator module */ +#define CRYPTO_RNG_MODULE_ENABLED 1 + +/* Enable PSA Crypto Key module */ +#define CRYPTO_KEY_MODULE_ENABLED 1 + +/* Enable PSA Crypto AEAD module */ +#define CRYPTO_AEAD_MODULE_ENABLED 1 + +/* Enable PSA Crypto MAC module */ +#define CRYPTO_MAC_MODULE_ENABLED 1 + +/* Enable PSA Crypto Hash module */ +#define CRYPTO_HASH_MODULE_ENABLED 1 + +/* Enable PSA Crypto Cipher module */ +#define CRYPTO_CIPHER_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key signature module */ +#define CRYPTO_ASYM_SIGN_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key encryption module */ +#define CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED 0 + +/* Enable PSA Crypto key derivation module */ +#define CRYPTO_KEY_DERIVATION_MODULE_ENABLED 1 + +/* Default size of the internal scratch buffer used for PSA FF IOVec allocations */ +#define CRYPTO_IOVEC_BUFFER_SIZE 5120 + +/* Use stored NV seed to provide entropy */ +#define CRYPTO_NV_SEED 1 + +/* + * Only enable multi-part operations in Hash, MAC, AEAD and symmetric ciphers, + * to optimize memory footprint in resource-constrained devices. + */ +#define CRYPTO_SINGLE_PART_FUNCS_DISABLED 0 + +/* The stack size of the Crypto Secure Partition */ +#define CRYPTO_STACK_SIZE 0x1B00 + +/* FWU Partition Configs */ + +/* Size of the FWU internal data transfer buffer */ +#define TFM_FWU_BUF_SIZE PSA_FWU_MAX_WRITE_SIZE + +/* The stack size of the Firmware Update Secure Partition */ +#define FWU_STACK_SIZE 0x600 + +/* Attest Partition Configs */ + +/* Include optional claims in initial attestation token */ +#define ATTEST_INCLUDE_OPTIONAL_CLAIMS 1 + +/* Include COSE key-id in initial attestation token */ +#define ATTEST_INCLUDE_COSE_KEY_ID 0 + +/* The stack size of the Initial Attestation Secure Partition */ +#define ATTEST_STACK_SIZE 0x700 + +/* Set the initial attestation token profile */ +#define ATTEST_TOKEN_PROFILE_PSA_IOT_1 1 + +/* ITS Partition Configs */ + +/* Create flash FS if it doesn't exist for Internal Trusted Storage partition */ +#define ITS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Internal Trusted Storage partition */ +#define ITS_RAM_FS 0 + +/* Validate filesystem metadata every time it is read from flash */ +#define ITS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Internal Trusted Storage */ +#define ITS_MAX_ASSET_SIZE 512 + +/* + * Size of the ITS internal data transfer buffer + * (Default to the max asset size so that all requests can be handled in one iteration.) + */ +#define ITS_BUF_SIZE ITS_MAX_ASSET_SIZE + +/* The maximum number of assets to be stored in the Internal Trusted Storage */ +#define ITS_NUM_ASSETS 10 + +/* The stack size of the Internal Trusted Storage Secure Partition */ +#define ITS_STACK_SIZE 0x720 + +/* PS Partition Configs */ + +/* Create flash FS if it doesn't exist for Protected Storage partition */ +#define PS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Protected Storage partition */ +#define PS_RAM_FS 0 + +/* Enable rollback protection for Protected Storage partition */ +#define PS_ROLLBACK_PROTECTION 1 + +/* Validate filesystem metadata every time it is read from flash */ +#define PS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Protected Storage */ +#define PS_MAX_ASSET_SIZE 2048 + +/* The maximum number of assets to be stored in the Protected Storage */ +#define PS_NUM_ASSETS 30 + +/* The stack size of the Protected Storage Secure Partition */ +#define PS_STACK_SIZE 0x700 + +/* SPM Partition Configs */ + +/* The maximal number of secure services that are connected or requested at the same time */ +#define CONFIG_TFM_CONN_HANDLE_MAX_NUM 8 + +/* Disable the doorbell APIs */ +#define CONFIG_TFM_DOORBELL_API 0 + +#endif /* TFM_PROJECT_CONFIG_H */ diff --git a/examples/platform/openiotsdk/app/CMakeLists.txt b/examples/platform/openiotsdk/app/CMakeLists.txt index c4caf953b34e9b..f7cc06f9fa14d1 100644 --- a/examples/platform/openiotsdk/app/CMakeLists.txt +++ b/examples/platform/openiotsdk/app/CMakeLists.txt @@ -53,3 +53,20 @@ target_link_libraries(openiotsdk-app PUBLIC chip ) + +if(CONFIG_CHIP_OPEN_IOT_SDK_OTA_ENABLE) + target_include_directories(openiotsdk-app + PUBLIC + dfu + ) + + target_sources(openiotsdk-app + PUBLIC + dfu/openiotsdk_dfu_manager.cpp + ) + + target_compile_definitions(openiotsdk-app + PUBLIC + CHIP_OPEN_IOT_SDK_OTA_ENABLE + ) +endif() diff --git a/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.cpp b/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.cpp new file mode 100644 index 00000000000000..583f49df43f18d --- /dev/null +++ b/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.cpp @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file + * This file provides the Device Firmware Update manager class implementation. + * It provides firmware update functionality based on Matter OTA Requestor cluster. + */ + +#include "openiotsdk_dfu_manager.h" + +#include "psa/fwu_config.h" + +DFUManager DFUManager::sDFUMgr; + +UserConsentState CustomOTARequestorUserConsent::GetUserConsentState(const UserConsentSubject & subject) +{ + UserConsentState curUserConsentState = CheckDeferredUserConsentState(); + + ChipLogProgress(SoftwareUpdate, "New version of the software is available: %d", subject.requestorTargetVersion); + SetUserConsentState(chip::ota::UserConsentState::kGranted); + + return curUserConsentState; +} + +CHIP_ERROR DFUManager::Init() +{ + int ret; + CHIP_ERROR err = CHIP_NO_ERROR; + + // Set the global instance of the OTA requestor core component + SetRequestorInstance(&mRequestorCore); + + // Periodic query timeout must be set prior to the driver being initialized + mRequestorDriver.SetPeriodicQueryTimeout(0); + + // Watchdog timeout can be set any time before a query image is sent + mRequestorDriver.SetWatchdogTimeout(0); + + mRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + mRequestorCore.Init(chip::Server::GetInstance(), mRequestorStorage, mRequestorDriver, mDownloader); + mRequestorDriver.Init(&mRequestorCore, &mImageProcessor); + + mImageProcessor.SetOTADownloader(&mDownloader); + mImageProcessor.SetImageId(FWU_COMPONENT_ID_NONSECURE); + + // Set the image processor instance used for handling image being downloaded + mDownloader.SetImageProcessorDelegate(&mImageProcessor); + + mRequestorDriver.SetUserConsentDelegate(&mUserConsentProvider); + + return err; +} diff --git a/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.h b/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.h new file mode 100644 index 00000000000000..0e216c4c742ced --- /dev/null +++ b/examples/platform/openiotsdk/app/dfu/openiotsdk_dfu_manager.h @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file + * This file provides the Device Firmware Update manager class implementation. + * It provides firmware update functionality based on Matter OTA Requestor cluster. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::ota; +using namespace ::chip::DeviceLayer; + +class CustomOTARequestorUserConsent : public DefaultOTARequestorUserConsent +{ +public: + UserConsentState GetUserConsentState(const UserConsentSubject & subject) override; +}; + +class DFUManager +{ +public: + CHIP_ERROR Init(); + +private: + friend DFUManager & GetDFUManager(void); + + static DFUManager sDFUMgr; + + DefaultOTARequestor mRequestorCore; + DefaultOTARequestorStorage mRequestorStorage; + ExtendedOTARequestorDriver mRequestorDriver; + BDXDownloader mDownloader; + OTAImageProcessorImpl mImageProcessor; + CustomOTARequestorUserConsent mUserConsentProvider; +}; + +inline DFUManager & GetDFUManager(void) +{ + return DFUManager::sDFUMgr; +} diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp index e787112a0efb1d..29662d6e8df4e9 100644 --- a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp @@ -48,6 +48,10 @@ #include #endif // USE_CHIP_DATA_MODEL +#ifdef CHIP_OPEN_IOT_SDK_OTA_ENABLE +#include "openiotsdk_dfu_manager.h" +#endif // CHIP_OPEN_IOT_SDK_OTA_ENABLE + #include "psa/fwu_config.h" #include "psa/update.h" #include "tfm_ns_interface.h" @@ -295,6 +299,15 @@ int openiotsdk_chip_run(void) ChipLogProgress(NotSpecified, "Current software version: [%ld] %s", uint32_t(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION), CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#ifdef CHIP_OPEN_IOT_SDK_OTA_ENABLE + err = GetDFUManager().Init(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", err.AsString()); + return EXIT_FAILURE; + } +#endif + return EXIT_SUCCESS; } diff --git a/examples/platform/openiotsdk/supported_examples.txt b/examples/platform/openiotsdk/supported_examples.txt index b7d7f985fb87bf..3e75abe968fc9b 100644 --- a/examples/platform/openiotsdk/supported_examples.txt +++ b/examples/platform/openiotsdk/supported_examples.txt @@ -2,3 +2,4 @@ shell lock-app tv-app all-clusters-app +ota-requestor-app diff --git a/scripts/examples/openiotsdk_example.sh b/scripts/examples/openiotsdk_example.sh index 968e95127f871d..ea33d6026526e9 100755 --- a/scripts/examples/openiotsdk_example.sh +++ b/scripts/examples/openiotsdk_example.sh @@ -251,6 +251,18 @@ function run_test() { TEST_OPTIONS+=(--networkInterface="$FVP_NETWORK") fi + if [[ "$EXAMPLE" == "ota-requestor-app" ]]; then + TEST_OPTIONS+=(--updateBinaryPath="${EXAMPLE_EXE_PATH/elf/"ota"}") + # Check if OTA provider exists, if so get the path to it + OTA_PROVIDER_APP=$(find . -type f -name "chip-ota-provider-app") + if [ -z "$OTA_PROVIDER_APP" ]; then + echo "Error: OTA provider application does not exist." >&2 + exit 1 + fi + TEST_OPTIONS+=(--otaProvider="$OTA_PROVIDER_APP") + TEST_OPTIONS+=(--softwareVersion="$APP_VERSION:$APP_VERSION_STR") + fi + if [[ -f $EXAMPLE_TEST_PATH/test_report_$EXAMPLE.json ]]; then rm -rf "$EXAMPLE_TEST_PATH/test_report_$EXAMPLE".json fi diff --git a/src/platform/openiotsdk/BUILD.gn b/src/platform/openiotsdk/BUILD.gn index 843e3ad08ec5f0..3826e1d7eae37d 100644 --- a/src/platform/openiotsdk/BUILD.gn +++ b/src/platform/openiotsdk/BUILD.gn @@ -76,5 +76,12 @@ static_library("openiotsdk") { "${chip_root}/src/platform:platform_base", ] + if (chip_enable_ota_requestor) { + sources += [ + "OTAImageProcessorImpl.cpp", + "OTAImageProcessorImpl.h", + ] + } + cflags = [ "-Wconversion" ] } diff --git a/src/platform/openiotsdk/OTAImageProcessorImpl.cpp b/src/platform/openiotsdk/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..ca1edf6d2d9cd2 --- /dev/null +++ b/src/platform/openiotsdk/OTAImageProcessorImpl.cpp @@ -0,0 +1,331 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file + * Provides the implementation of the OTA Image Processor class + * for Open IOT SDK platform. + */ + +#include +#include + +#include "OTAImageProcessorImpl.h" + +namespace chip { + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::OnOTAStateChange(DeviceLayer::OtaState state) +{ + DeviceLayer::ChipDeviceEvent otaChange; + otaChange.Type = DeviceLayer::DeviceEventType::kOtaStateChanged; + otaChange.OtaStateChanged.newState = state; + CHIP_ERROR error = DeviceLayer::PlatformMgr().PostEvent(&otaChange); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Posting OTA state change failed %" CHIP_ERROR_FORMAT, error.Format()); + } +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + // Store block data for HandleProcessBlock to access + CHIP_ERROR err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +bool OTAImageProcessorImpl::IsFirstImageRun() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return false; + } + + return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; +} + +CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + uint32_t currentVersion; + uint32_t targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion, + targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + psa_status_t rc = psa_fwu_start(imageProcessor->mImageId, NULL, 0); + if (rc != PSA_SUCCESS) + { + ChipLogError(SoftwareUpdate, "Begin a firmware update operation for image %d failed [%ld]", imageProcessor->mImageId, rc); + return; + } + + imageProcessor->mParams.downloadedBytes = 0; + imageProcessor->mParams.totalFileBytes = 0; + + imageProcessor->mHeaderParser.Init(); + + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadInProgress); +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + psa_status_t rc = psa_fwu_finish(imageProcessor->mImageId); + if (rc != PSA_SUCCESS) + { + ChipLogError(SoftwareUpdate, "Mark the image %d as ready for installation failed [%ld]", imageProcessor->mImageId, rc); + imageProcessor->UpdateShutdown(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadFailed); + return; + } + + imageProcessor->ReleaseBlock(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadComplete); +} + +void OTAImageProcessorImpl::HandleApply(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + VerifyOrReturn(imageProcessor != nullptr); + + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + VerifyOrReturn(requestor != nullptr); + + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaApplyInProgress); + + // Only check ready for reboot state. + // The PSA_SUCCESS_RESTART is related to restarting the external components which are not supported here. + psa_status_t rc = psa_fwu_install(); + if (rc != PSA_SUCCESS_REBOOT) + { + ChipLogError(SoftwareUpdate, "Start the installation of the image %d failed [%ld]", imageProcessor->mImageId, rc); + imageProcessor->UpdateShutdown(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaApplyFailed); + return; + } + + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaApplyComplete); + + DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { DeviceLayer::PlatformMgr().HandleServerShuttingDown(); }); + DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { + DeviceLayer::PlatformMgr().StopEventLoopTask(); + DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Shutdown(); + psa_fwu_request_reboot(); + }); +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + imageProcessor->UpdateShutdown(); + + imageProcessor->ReleaseBlock(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadAborted); +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + ByteSpan block = imageProcessor->mBlock; + CHIP_ERROR error = imageProcessor->ProcessHeader(block); + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Image does not contain a valid header"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_INVALID_FILE_IDENTIFIER); + imageProcessor->UpdateShutdown(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadFailed); + return; + } + + psa_status_t rc = + psa_fwu_write(imageProcessor->mImageId, (size_t) imageProcessor->mParams.downloadedBytes, block.data(), block.size()); + if (rc != PSA_SUCCESS) + { + ChipLogError(SoftwareUpdate, "Write image %d chunk failed [%ld]", imageProcessor->mImageId, rc); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + imageProcessor->UpdateShutdown(); + imageProcessor->OnOTAStateChange(DeviceLayer::kOtaDownloadFailed); + return; + } + + imageProcessor->mParams.downloadedBytes += block.size(); + imageProcessor->mDownloader->FetchNextData(); +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) +{ + if (mHeaderParser.IsInitialized()) + { + OTAImageHeader header; + CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); + + // Needs more data to decode the header + ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + ReturnErrorOnFailure(error); + + mParams.totalFileBytes = header.mPayloadSize; + mHeaderParser.Clear(); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if (!IsSpanUsable(block)) + { + ReleaseBlock(); + return CHIP_NO_ERROR; + } + if (mBlock.size() < block.size()) + { + if (!mBlock.empty()) + { + ReleaseBlock(); + } + uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); + if (mBlock_ptr == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + mBlock = MutableByteSpan(mBlock_ptr, block.size()); + } + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::UpdateShutdown() +{ + psa_fwu_component_info_t info; + + psa_status_t rc = psa_fwu_query(mImageId, &info); + + if (rc == PSA_SUCCESS) + { + switch (info.state) + { + case PSA_FWU_WRITING: + case PSA_FWU_CANDIDATE: + psa_fwu_cancel(mImageId); + psa_fwu_clean(mImageId); + break; + case PSA_FWU_FAILED: + case PSA_FWU_UPDATED: + psa_fwu_clean(mImageId); + break; + } + } +} + +} // namespace chip diff --git a/src/platform/openiotsdk/OTAImageProcessorImpl.h b/src/platform/openiotsdk/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..59180add71752c --- /dev/null +++ b/src/platform/openiotsdk/OTAImageProcessorImpl.h @@ -0,0 +1,95 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file + * Provides the implementation of the OTA Image Processor class + * for Open IOT SDK platform. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + bool IsFirstImageRun() override; + CHIP_ERROR ConfirmCurrentImage() override; + + void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } + void SetImageId(psa_fwu_component_t id); + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleApply(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + /** + * Called to post OTA state change event + */ + void OnOTAStateChange(DeviceLayer::OtaState state); + + /** + * Called to accumulate and decode header from data chunk + */ + CHIP_ERROR ProcessHeader(ByteSpan & block); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + /** + * Called to clean up image preparation + */ + void UpdateShutdown(); + + MutableByteSpan mBlock; + OTADownloader * mDownloader; + OTAImageHeaderParser mHeaderParser; + psa_fwu_component_t mImageId; +}; + +inline void OTAImageProcessorImpl::SetImageId(psa_fwu_component_t id) +{ + mImageId = id; +} + +} // namespace chip diff --git a/src/test_driver/openiotsdk/integration-tests/common/fixtures.py b/src/test_driver/openiotsdk/integration-tests/common/fixtures.py index 1bbb75d9e9eab6..08f9b55d6d61dc 100644 --- a/src/test_driver/openiotsdk/integration-tests/common/fixtures.py +++ b/src/test_driver/openiotsdk/integration-tests/common/fixtures.py @@ -27,6 +27,7 @@ from .fvp_device import FvpDevice from .telnet_connection import TelnetConnection +from .terminal_device import TerminalDevice log = logging.getLogger(__name__) @@ -65,6 +66,24 @@ def networkInterface(request): return None +@pytest.fixture(scope="session") +def otaProvider(request, rootDir): + if request.config.getoption('otaProvider'): + return request.config.getoption('otaProvider') + else: + return os.path.join(rootDir, 'out/chip-ota-provider-app') + + +@pytest.fixture(scope="session") +def softwareVersion(request): + if request.config.getoption('softwareVersion'): + version = request.config.getoption('softwareVersion') + params = version.split(':') + return (params[0], params[1]) + else: + return ("1", "0.0.1") + + @pytest.fixture(scope="function") def device(fvp, fvpConfig, binaryPath, telnetPort, networkInterface): connection = TelnetConnection('localhost', telnetPort) @@ -107,3 +126,22 @@ def controller(controllerConfig): certificateAuthorityManager.Shutdown() chipStack.Shutdown() os.remove(controllerConfig['persistentStoragePath']) + + +@pytest.fixture(scope="session") +def ota_provider(otaProvider, otaProviderConfig): + args = [ + '--discriminator', otaProviderConfig['discriminator'], + '--secured-device-port', otaProviderConfig['port'], + '-c', + '--KVS', otaProviderConfig['persistentStoragePath'], + '--filepath', otaProviderConfig['filePath'], + ] + + device = TerminalDevice(otaProvider, args, "OTAprovider") + device.start() + + yield device + + device.stop() + os.remove(otaProviderConfig['persistentStoragePath']) diff --git a/src/test_driver/openiotsdk/integration-tests/common/terminal_device.py b/src/test_driver/openiotsdk/integration-tests/common/terminal_device.py new file mode 100644 index 00000000000000..1d0d3881f588d7 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/terminal_device.py @@ -0,0 +1,95 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# 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 logging +import subprocess +import threading + +from .device import Device + +log = logging.getLogger(__name__) + + +class TerminalDevice(Device): + + def __init__(self, app, args, name=None): + + self.run = False + super(TerminalDevice, self).__init__(name) + + input_thread_name = '<-- {}'.format(self.name) + output_thread_name = '--> {}'.format(self.name) + + self.cmd = [app] + args + + self.it = threading.Thread( + target=self._input_thread, name=input_thread_name) + self.ot = threading.Thread( + target=self._output_thread, name=output_thread_name) + + def start(self, expectedStartupLog: str = None, startupTimeout: int = 20): + """ + Start the terminal application + """ + log.info('Starting "{}" runner...'.format(self.name)) + + self.proc = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE) + + if self.proc.poll() is not None: + raise Exception("Terminal application start failed") + + self.run = True + self.it.start() + self.ot.start() + log.info('"{}" runner started'.format(self.name)) + + def stop(self): + """ + Stop the the terminal application + """ + log.info('Stopping "{}" runner...'.format(self.name)) + self.run = False + self.proc.stdin.close() + self.proc.terminate() + self.proc.wait() + self.oq.put(None) + self.it.join() + self.ot.join() + log.info('"{}" runner stoped'.format(self.name)) + + def _input_thread(self): + while self.run: + line = self.proc.stdout.readline().decode('utf8') + # Check if process still running + if line == '' and self.proc.poll() is not None: + pass + else: + if self.verbose: + log.info('<--|{}| {}'.format(self.name, line.strip())) + self.iq.put(line) + + def _output_thread(self): + while self.run: + line = self.oq.get() + if self.proc.poll() is not None: + pass + if line: + if self.verbose: + log.info('-->|{}| {}'.format(self.name, line.strip())) + self.proc.stdin.write(line) + else: + log.debug('Nothing sent') diff --git a/src/test_driver/openiotsdk/integration-tests/conftest.py b/src/test_driver/openiotsdk/integration-tests/conftest.py index 0181911de7e8b2..922d36501e101d 100644 --- a/src/test_driver/openiotsdk/integration-tests/conftest.py +++ b/src/test_driver/openiotsdk/integration-tests/conftest.py @@ -34,3 +34,9 @@ def pytest_addoption(parser): help='Telnet terminal port number.', default="5000") parser.addoption('--networkInterface', action='store', help='FVP network interface name') + parser.addoption('--updateBinaryPath', action='store', + help='Application update binary path') + parser.addoption('--otaProvider', action='store', + help='Path to OTA provider application') + parser.addoption('--softwareVersion', action='store', + help='Software version of update image in the format : eg. 1:0.0.01') diff --git a/src/test_driver/openiotsdk/integration-tests/ota-requestor-app/__init__.py b/src/test_driver/openiotsdk/integration-tests/ota-requestor-app/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/test_driver/openiotsdk/integration-tests/ota-requestor-app/test_app.py b/src/test_driver/openiotsdk/integration-tests/ota-requestor-app/test_app.py new file mode 100644 index 00000000000000..9470d5a16e46ef --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/ota-requestor-app/test_app.py @@ -0,0 +1,190 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# 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 logging +import os +import re + +import chip.interaction_model +import pytest +from chip.clusters.Objects import OtaSoftwareUpdateRequestor +from chip.clusters.Types import NullValue +from common.utils import (connect_device, disconnect_device, discover_device, get_setup_payload, send_zcl_command, + write_zcl_attribute) + +log = logging.getLogger(__name__) + + +@pytest.fixture(scope="session") +def binaryPath(request, rootDir): + if request.config.getoption('binaryPath'): + return request.config.getoption('binaryPath') + else: + return os.path.join(rootDir, 'examples/ota-requestor-app/openiotsdk/build/chip-openiotsdk-ota-requestor-app-example.elf') + + +@pytest.fixture(scope="session") +def updateBinaryPath(request, rootDir): + if request.config.getoption('updateBinaryPath'): + return request.config.getoption('updateBinaryPath') + else: + return os.path.join(rootDir, 'examples/ota-requestor-app/openiotsdk/build/chip-openiotsdk-ota-requestor-app-example.ota') + + +@pytest.fixture(scope="session") +def controllerConfig(request): + config = { + 'vendorId': 0xFFF1, + 'fabricId': 1, + 'persistentStoragePath': '/tmp/openiotsdk-test-storage.json' + } + return config + + +@pytest.fixture(scope="session") +def otaProviderConfig(request, updateBinaryPath): + config = { + 'discriminator': '3841', + 'port': '5580', + 'filePath': f'{updateBinaryPath}', + 'persistentStoragePath': '/tmp/openiotsdk-test-ota-provider.json' + } + return config + + +@pytest.mark.smoketest +def test_smoke_test(device): + ret = device.wait_for_output("Open IoT SDK ota-requestor-app example application start") + assert ret is not None and len(ret) > 0 + ret = device.wait_for_output("Open IoT SDK ota-requestor-app example application run") + assert ret is not None and len(ret) > 0 + + +@pytest.mark.commissioningtest +def test_commissioning(device, controller): + assert controller is not None + devCtrl = controller + + ret = device.wait_for_output("Open IoT SDK ota-requestor-app example application start") + assert ret is not None and len(ret) > 0 + + setupPayload = get_setup_payload(device) + assert setupPayload is not None + + commissionable_device = discover_device(devCtrl, setupPayload) + assert commissionable_device is not None + + assert commissionable_device.vendorId == int(setupPayload.attributes['VendorID']) + assert commissionable_device.productId == int(setupPayload.attributes['ProductID']) + assert commissionable_device.addresses[0] is not None + + nodeId = connect_device(devCtrl, setupPayload, commissionable_device) + assert nodeId is not None + log.info("Device {} connected".format(commissionable_device.addresses[0])) + + ret = device.wait_for_output("Commissioning completed successfully") + assert ret is not None and len(ret) > 0 + + assert disconnect_device(devCtrl, nodeId) + + +OTA_REQUESTOR_CTRL_TEST_ENDPOINT_ID = 0 + + +@pytest.mark.ctrltest +def test_update_ctrl(device, controller, ota_provider, softwareVersion): + assert controller is not None + devCtrl = controller + version_number, version_str = softwareVersion + + log.info("Setup OTA provider...") + + # Get OTA provider setup payload + setupPayloadProvider = get_setup_payload(ota_provider) + assert setupPayloadProvider is not None + + # Discover and commission the OTA provider + commissionable_provider_device = discover_device(devCtrl, setupPayloadProvider) + assert commissionable_provider_device is not None + + providerNodeId = connect_device(devCtrl, setupPayloadProvider, commissionable_provider_device) + assert providerNodeId is not None + + ret = ota_provider.wait_for_output("Commissioning completed successfully") + assert ret is not None and len(ret) > 0 + + log.info("OTA provider ready") + log.info("Setup OTA requestor...") + + # Get OTA requestor setup payload + setupPayload = get_setup_payload(device) + assert setupPayload is not None + + # Discover and commission the OTA requestor + commissionable_requestor_device = discover_device(devCtrl, setupPayload) + assert commissionable_requestor_device is not None + + requestorNodeId = connect_device(devCtrl, setupPayload, commissionable_requestor_device) + assert requestorNodeId is not None + + ret = device.wait_for_output("Commissioning completed successfully") + assert ret is not None and len(ret) > 0 + + log.info("OTA requestor ready") + log.info("Install ACL entries") + + # Install necessary ACL entries in OTA provider to enable access by OTA requestor + err, res = write_zcl_attribute(devCtrl, "AccessControl", "Acl", providerNodeId, OTA_REQUESTOR_CTRL_TEST_ENDPOINT_ID, + [{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [requestorNodeId], "targets": NullValue}, + {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": NullValue, "targets": [{"cluster": 41, "endpoint": NullValue, "deviceType": NullValue}]}]) + assert err == 0 + assert res[0].Status == chip.interaction_model.Status.Success + + ota_provider.set_verbose(False) + + log.info("Announce the OTA provider and start the firmware update process") + + # Announce the OTA provider and start the firmware update process + err, res = send_zcl_command(devCtrl, "OtaSoftwareUpdateRequestor", "AnnounceOTAProvider", requestorNodeId, OTA_REQUESTOR_CTRL_TEST_ENDPOINT_ID, + dict(providerNodeID=providerNodeId, vendorID=int(setupPayloadProvider.attributes['VendorID']), + announcementReason=OtaSoftwareUpdateRequestor.Enums.OTAAnnouncementReason.kUrgentUpdateAvailable, + metadataForNode=None, endpoint=0)) + + ret = device.wait_for_output("New version of the software is available") + assert ret is not None and len(ret) > 1 + + version = ret[-1].split()[-1] + assert version_number == version + + device.set_verbose(False) + + log.info("New software image downloading and installing...") + + ret = device.wait_for_output("Open IoT SDK ota-requestor-app example application start", timeout=1200) + assert ret is not None and len(ret) > 0 + + device.set_verbose(True) + + ret = device.wait_for_output("Current software version") + assert ret is not None and len(ret) > 1 + + version_app = ret[-1].split()[-2:] + assert version_number == re.sub(r"[\[\]]", "", version_app[0]) + assert version_str == version_app[1] + + assert disconnect_device(devCtrl, requestorNodeId) + assert disconnect_device(devCtrl, providerNodeId)