From d65d147d656a1dab08754e0e84452dbe0c4cee0c Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 26 Jan 2023 14:51:01 -0500 Subject: [PATCH] Add TC-ACE-1.5 yaml (#24455) * Add TC-ACE-1.5 yaml * Update src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml Co-authored-by: Boris Zbarsky * Fix commissioner node id * Zap for boris' change. * Name changes are fun, but make zap mad. * Restyled by whitespace * Restyled by prettier-yaml Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_ACE_1_5.yaml | 172 ++++++ src/app/tests/suites/ciTests.json | 2 + .../chip-tool/zap-generated/test/Commands.h | 387 +++++++++++++ .../zap-generated/test/Commands.h | 537 ++++++++++++++++++ 4 files changed, 1098 insertions(+) create mode 100644 src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml diff --git a/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml b/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml new file mode 100644 index 00000000000000..f013471c0f6386 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml @@ -0,0 +1,172 @@ +# Copyright (c) 2021 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. +# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default + +name: 42.1.5. [TC-ACE-1.5] Multi-fabric + +config: + nodeId: 0x12344321 + cluster: "Access Control" + endpoint: 0 + payload: + type: char_string + defaultValue: "MT:-24J0AFN00KA0648G00" + +tests: + - label: "Wait for the commissioned device to be retrieved for TH1" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH1 reads the fabric index" + cluster: "Operational Credentials" + command: "readAttribute" + attribute: "CurrentFabricIndex" + response: + saveAs: th1FabricIndex + + - label: "Open Commissioning Window from alpha" + cluster: "Administrator Commissioning" + command: "OpenBasicCommissioningWindow" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "CommissioningTimeout" + value: 180 + + - label: "Commission from TH2" + identity: "beta" + cluster: "CommissionerCommands" + command: "PairWithCode" + arguments: + values: + - name: "nodeId" + value: nodeId + - name: "payload" + value: payload + + - label: "Wait for the commissioned device to be retrieved for TH2" + identity: beta + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH2 reads the fabric index" + identity: "beta" + cluster: "Operational Credentials" + command: "readAttribute" + attribute: "CurrentFabricIndex" + response: + saveAs: th2FabricIndex + + - label: "TH1 writes ACL giving view privilege for descriptor cluster" + command: "writeAttribute" + attribute: "ACL" + arguments: + value: [ + { + FabricIndex: th1FabricIndex, + Privilege: 5, # administer + AuthMode: 2, # case + Subjects: [commissionerNodeId], + Targets: + [{ Cluster: 0x001f, Endpoint: 0, DeviceType: null }], + }, + { + FabricIndex: th1FabricIndex, + Privilege: 1, # view + AuthMode: 2, # case + Subjects: null, + Targets: + [{ Cluster: 0x001d, Endpoint: 0, DeviceType: null }], + }, + ] + + - label: "TH2 writes ACL giving view privilge for basic cluster" + identity: beta + command: "writeAttribute" + attribute: "ACL" + arguments: + value: [ + { + FabricIndex: th2FabricIndex, + Privilege: 5, # administer + AuthMode: 2, # case + Subjects: [commissionerNodeId], + Targets: + [{ Cluster: 0x001f, Endpoint: 0, DeviceType: null }], + }, + { + FabricIndex: th2FabricIndex, + Privilege: 1, # view + AuthMode: 2, # case + Subjects: null, + Targets: + [{ Cluster: 0x0028, Endpoint: 0, DeviceType: null }], + }, + ] + + - label: "TH1 reads descriptor cluster - expect SUCCESS" + command: "readAttribute" + cluster: "Descriptor" + attribute: "DeviceTypeList" + + - label: "TH1 reads basic cluster - expect UNSUPPORTED_ACCESS" + command: "readAttribute" + cluster: "Basic Information" + attribute: "VendorID" + response: + error: UNSUPPORTED_ACCESS + + - label: "TH2 reads descriptor cluster - expect UNSUPPORTED_ACCESS" + identity: "beta" + command: "readAttribute" + cluster: "Descriptor" + attribute: "DeviceTypeList" + response: + error: UNSUPPORTED_ACCESS + + - label: "TH2 reads basic cluster - expect SUCCESS" + identity: "beta" + command: "readAttribute" + cluster: "Basic Information" + attribute: "VendorID" + + - label: "TH1 resets ACL to default" + command: "writeAttribute" + attribute: "ACL" + arguments: + value: [ + { + FabricIndex: 1, + Privilege: 5, # administer + AuthMode: 2, # case + Subjects: [commissionerNodeId], + Targets: null, + }, + ] + + - label: "TH1 sends RemoveFabric command for TH2" + cluster: "Operational Credentials" + command: "RemoveFabric" + arguments: + values: + - name: "FabricIndex" + value: th2FabricIndex diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 0c5f5f95167197..3f89dfc8331129 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -11,6 +11,7 @@ "Test_TC_ACL_2_9", "Test_TC_ACL_2_10" ], + "AccessControlEnforcement": ["Test_TC_ACE_1_5"], "BooleanState": ["Test_TC_BOOL_1_1", "Test_TC_BOOL_2_1"], "Binding": ["Test_TC_BIND_1_1"], "BridgedDeviceBasicInformation": [ @@ -271,6 +272,7 @@ ], "collection": [ "AccessControl", + "AccessControlEnforcement", "BooleanState", "BridgedDeviceBasicInformation", "Actions", diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 755fb2ce055dc9..b4d4de70032db5 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -45,6 +45,7 @@ class TestList : public Command printf("Test_TC_ACL_2_8\n"); printf("Test_TC_ACL_2_9\n"); printf("Test_TC_ACL_2_10\n"); + printf("Test_TC_ACE_1_5\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -7373,6 +7374,391 @@ class Test_TC_ACL_2_10Suite : public TestCommand } }; +class Test_TC_ACE_1_5Suite : public TestCommand +{ +public: + Test_TC_ACE_1_5Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_ACE_1_5", 14, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("payload", &mPayload); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~Test_TC_ACE_1_5Suite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mPayload; + chip::Optional mTimeout; + + uint8_t th1FabricIndex; + uint8_t th2FabricIndex; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + + // Allow yaml to access the current commissioner node id. + // Default to 0 (undefined node id) so we know if this isn't + // set correctly. + // Reset on every step in case it changed. + chip::NodeId commissionerNodeId = mCommissionerNodeId.ValueOr(0); + (void) commissionerNodeId; + + bool shouldContinue = false; + + switch (mTestIndex - 1) + { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint8_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + th1FabricIndex = value; + } + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 5: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + uint8_t value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + th2FabricIndex = value; + } + break; + case 6: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 7: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 8: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList + value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + } + break; + case 9: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + break; + case 11: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::VendorId value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + } + break; + case 12: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 13: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + using namespace chip::app::Clusters; + // Allow yaml to access the current commissioner node id. + // Default to 0 (undefined node id) so we know if this isn't + // set correctly. + // Reset on every step in case it changed. + chip::NodeId commissionerNodeId = mCommissionerNodeId.ValueOr(0); + (void) commissionerNodeId; + switch (testIndex) + { + case 0: { + LogStep(0, "Wait for the commissioned device to be retrieved for TH1"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityAlpha, value); + } + case 1: { + LogStep(1, "TH1 reads the fabric index"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(0), OperationalCredentials::Id, + OperationalCredentials::Attributes::CurrentFabricIndex::Id, true, chip::NullOptional); + } + case 2: { + LogStep(2, "Open Commissioning Window from alpha"); + ListFreer listFreer; + chip::app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type value; + value.commissioningTimeout = 180U; + return SendCommand(kIdentityAlpha, GetEndpoint(0), AdministratorCommissioning::Id, + AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Id, value, + chip::Optional(10000), chip::NullOptional + + ); + } + case 3: { + LogStep(3, "Commission from TH2"); + ListFreer listFreer; + chip::app::Clusters::CommissionerCommands::Commands::PairWithCode::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + value.payload = mPayload.HasValue() ? mPayload.Value() : chip::Span("MT:-24J0AFN00KA0648G00", 22); + return PairWithCode(kIdentityBeta, value); + } + case 4: { + LogStep(4, "Wait for the commissioned device to be retrieved for TH2"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityBeta, value); + } + case 5: { + LogStep(5, "TH2 reads the fabric index"); + return ReadAttribute(kIdentityBeta, GetEndpoint(0), OperationalCredentials::Id, + OperationalCredentials::Attributes::CurrentFabricIndex::Id, true, chip::NullOptional); + } + case 6: { + LogStep(6, "TH1 writes ACL giving view privilege for descriptor cluster"); + ListFreer listFreer; + chip::app::DataModel::List value; + + { + auto * listHolder_0 = + new ListHolder(2); + listFreer.add(listHolder_0); + + listHolder_0->mList[0].privilege = + static_cast(5); + listHolder_0->mList[0].authMode = + static_cast(2); + listHolder_0->mList[0].subjects.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + listHolder_3->mList[0] = commissionerNodeId; + listHolder_0->mList[0].subjects.Value() = chip::app::DataModel::List(listHolder_3->mList, 1); + } + listHolder_0->mList[0].targets.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + + listHolder_3->mList[0].cluster.SetNonNull(); + listHolder_3->mList[0].cluster.Value() = 31UL; + listHolder_3->mList[0].endpoint.SetNonNull(); + listHolder_3->mList[0].endpoint.Value() = 0U; + listHolder_3->mList[0].deviceType.SetNull(); + + listHolder_0->mList[0].targets.Value() = + chip::app::DataModel::List(listHolder_3->mList, + 1); + } + listHolder_0->mList[0].fabricIndex = th1FabricIndex; + + listHolder_0->mList[1].privilege = + static_cast(1); + listHolder_0->mList[1].authMode = + static_cast(2); + listHolder_0->mList[1].subjects.SetNull(); + listHolder_0->mList[1].targets.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + + listHolder_3->mList[0].cluster.SetNonNull(); + listHolder_3->mList[0].cluster.Value() = 29UL; + listHolder_3->mList[0].endpoint.SetNonNull(); + listHolder_3->mList[0].endpoint.Value() = 0U; + listHolder_3->mList[0].deviceType.SetNull(); + + listHolder_0->mList[1].targets.Value() = + chip::app::DataModel::List(listHolder_3->mList, + 1); + } + listHolder_0->mList[1].fabricIndex = th1FabricIndex; + + value = chip::app::DataModel::List( + listHolder_0->mList, 2); + } + return WriteAttribute(kIdentityAlpha, GetEndpoint(0), AccessControl::Id, AccessControl::Attributes::Acl::Id, value, + chip::NullOptional, chip::NullOptional); + } + case 7: { + LogStep(7, "TH2 writes ACL giving view privilge for basic cluster"); + ListFreer listFreer; + chip::app::DataModel::List value; + + { + auto * listHolder_0 = + new ListHolder(2); + listFreer.add(listHolder_0); + + listHolder_0->mList[0].privilege = + static_cast(5); + listHolder_0->mList[0].authMode = + static_cast(2); + listHolder_0->mList[0].subjects.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + listHolder_3->mList[0] = commissionerNodeId; + listHolder_0->mList[0].subjects.Value() = chip::app::DataModel::List(listHolder_3->mList, 1); + } + listHolder_0->mList[0].targets.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + + listHolder_3->mList[0].cluster.SetNonNull(); + listHolder_3->mList[0].cluster.Value() = 31UL; + listHolder_3->mList[0].endpoint.SetNonNull(); + listHolder_3->mList[0].endpoint.Value() = 0U; + listHolder_3->mList[0].deviceType.SetNull(); + + listHolder_0->mList[0].targets.Value() = + chip::app::DataModel::List(listHolder_3->mList, + 1); + } + listHolder_0->mList[0].fabricIndex = th2FabricIndex; + + listHolder_0->mList[1].privilege = + static_cast(1); + listHolder_0->mList[1].authMode = + static_cast(2); + listHolder_0->mList[1].subjects.SetNull(); + listHolder_0->mList[1].targets.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + + listHolder_3->mList[0].cluster.SetNonNull(); + listHolder_3->mList[0].cluster.Value() = 40UL; + listHolder_3->mList[0].endpoint.SetNonNull(); + listHolder_3->mList[0].endpoint.Value() = 0U; + listHolder_3->mList[0].deviceType.SetNull(); + + listHolder_0->mList[1].targets.Value() = + chip::app::DataModel::List(listHolder_3->mList, + 1); + } + listHolder_0->mList[1].fabricIndex = th2FabricIndex; + + value = chip::app::DataModel::List( + listHolder_0->mList, 2); + } + return WriteAttribute(kIdentityBeta, GetEndpoint(0), AccessControl::Id, AccessControl::Attributes::Acl::Id, value, + chip::NullOptional, chip::NullOptional); + } + case 8: { + LogStep(8, "TH1 reads descriptor cluster - expect SUCCESS"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(0), Descriptor::Id, Descriptor::Attributes::DeviceTypeList::Id, true, + chip::NullOptional); + } + case 9: { + LogStep(9, "TH1 reads basic cluster - expect UNSUPPORTED_ACCESS"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(0), BasicInformation::Id, BasicInformation::Attributes::VendorID::Id, + true, chip::NullOptional); + } + case 10: { + LogStep(10, "TH2 reads descriptor cluster - expect UNSUPPORTED_ACCESS"); + return ReadAttribute(kIdentityBeta, GetEndpoint(0), Descriptor::Id, Descriptor::Attributes::DeviceTypeList::Id, true, + chip::NullOptional); + } + case 11: { + LogStep(11, "TH2 reads basic cluster - expect SUCCESS"); + return ReadAttribute(kIdentityBeta, GetEndpoint(0), BasicInformation::Id, BasicInformation::Attributes::VendorID::Id, + true, chip::NullOptional); + } + case 12: { + LogStep(12, "TH1 resets ACL to default"); + ListFreer listFreer; + chip::app::DataModel::List value; + + { + auto * listHolder_0 = + new ListHolder(1); + listFreer.add(listHolder_0); + + listHolder_0->mList[0].privilege = + static_cast(5); + listHolder_0->mList[0].authMode = + static_cast(2); + listHolder_0->mList[0].subjects.SetNonNull(); + + { + auto * listHolder_3 = new ListHolder(1); + listFreer.add(listHolder_3); + listHolder_3->mList[0] = commissionerNodeId; + listHolder_0->mList[0].subjects.Value() = chip::app::DataModel::List(listHolder_3->mList, 1); + } + listHolder_0->mList[0].targets.SetNull(); + listHolder_0->mList[0].fabricIndex = 1U; + + value = chip::app::DataModel::List( + listHolder_0->mList, 1); + } + return WriteAttribute(kIdentityAlpha, GetEndpoint(0), AccessControl::Id, AccessControl::Attributes::Acl::Id, value, + chip::NullOptional, chip::NullOptional); + } + case 13: { + LogStep(13, "TH1 sends RemoveFabric command for TH2"); + ListFreer listFreer; + chip::app::Clusters::OperationalCredentials::Commands::RemoveFabric::Type value; + value.fabricIndex = th2FabricIndex; + return SendCommand(kIdentityAlpha, GetEndpoint(0), OperationalCredentials::Id, + OperationalCredentials::Commands::RemoveFabric::Id, value, chip::NullOptional + + ); + } + } + return CHIP_NO_ERROR; + } +}; + class Test_TC_BOOL_1_1Suite : public TestCommand { public: @@ -118167,6 +118553,7 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), 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 8d2baf95d96803..f49b5909ae11c2 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -41,6 +41,7 @@ class TestList : public Command { printf("Test_TC_ACL_2_1\n"); printf("Test_TC_ACL_2_2\n"); printf("Test_TC_ACL_2_3\n"); + printf("Test_TC_ACE_1_5\n"); printf("Test_TC_BOOL_1_1\n"); printf("Test_TC_BOOL_2_1\n"); printf("Test_TC_BRBINFO_1_1\n"); @@ -4198,6 +4199,541 @@ class Test_TC_ACL_2_3 : public TestCommandBridge { } }; +class Test_TC_ACE_1_5 : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + Test_TC_ACE_1_5() + : TestCommandBridge("Test_TC_ACE_1_5") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("payload", &mPayload); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~Test_TC_ACE_1_5() {} + + // Allow yaml to access the current commissioner node id. + // Default to 0 (undefined node id) so we know if this isn't + // set correctly. + // Reset on every step in case it changed. + chip::NodeId commissionerNodeId = mCommissionerNodeId.ValueOr(0); + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: Test_TC_ACE_1_5\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: Test_TC_ACE_1_5\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) { + case 0: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved for TH1\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrievedForTh1_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : TH1 reads the fabric index\n"); + err = TestTh1ReadsTheFabricIndex_1(); + break; + case 2: + ChipLogProgress(chipTool, " ***** Test Step 2 : Open Commissioning Window from alpha\n"); + err = TestOpenCommissioningWindowFromAlpha_2(); + break; + case 3: + ChipLogProgress(chipTool, " ***** Test Step 3 : Commission from TH2\n"); + err = TestCommissionFromTh2_3(); + break; + case 4: + ChipLogProgress(chipTool, " ***** Test Step 4 : Wait for the commissioned device to be retrieved for TH2\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrievedForTh2_4(); + break; + case 5: + ChipLogProgress(chipTool, " ***** Test Step 5 : TH2 reads the fabric index\n"); + err = TestTh2ReadsTheFabricIndex_5(); + break; + case 6: + ChipLogProgress(chipTool, " ***** Test Step 6 : TH1 writes ACL giving view privilege for descriptor cluster\n"); + err = TestTh1WritesAclGivingViewPrivilegeForDescriptorCluster_6(); + break; + case 7: + ChipLogProgress(chipTool, " ***** Test Step 7 : TH2 writes ACL giving view privilge for basic cluster\n"); + err = TestTh2WritesAclGivingViewPrivilgeForBasicCluster_7(); + break; + case 8: + ChipLogProgress(chipTool, " ***** Test Step 8 : TH1 reads descriptor cluster - expect SUCCESS\n"); + err = TestTh1ReadsDescriptorClusterExpectSuccess_8(); + break; + case 9: + ChipLogProgress(chipTool, " ***** Test Step 9 : TH1 reads basic cluster - expect UNSUPPORTED_ACCESS\n"); + err = TestTh1ReadsBasicClusterExpectUnsupportedAccess_9(); + break; + case 10: + ChipLogProgress(chipTool, " ***** Test Step 10 : TH2 reads descriptor cluster - expect UNSUPPORTED_ACCESS\n"); + err = TestTh2ReadsDescriptorClusterExpectUnsupportedAccess_10(); + break; + case 11: + ChipLogProgress(chipTool, " ***** Test Step 11 : TH2 reads basic cluster - expect SUCCESS\n"); + err = TestTh2ReadsBasicClusterExpectSuccess_11(); + break; + case 12: + ChipLogProgress(chipTool, " ***** Test Step 12 : TH1 resets ACL to default\n"); + err = TestTh1ResetsAclToDefault_12(); + break; + case 13: + ChipLogProgress(chipTool, " ***** Test Step 13 : TH1 sends RemoveFabric command for TH2\n"); + err = TestTh1SendsRemoveFabricCommandForTh2_13(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 2: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 3: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 4: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 5: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 6: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 7: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 8: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 9: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + break; + case 10: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + break; + case 11: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 12: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 13: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 14; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mPayload; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForTh1_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + NSNumber * _Nonnull th1FabricIndex; + + CHIP_ERROR TestTh1ReadsTheFabricIndex_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device + endpointID:@(0) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeCurrentFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH1 reads the fabric index Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + th1FabricIndex = value; + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestOpenCommissioningWindowFromAlpha_2() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device + endpointID:@(0) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + __auto_type * params = [[MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams alloc] init]; + params.commissioningTimeout = [NSNumber numberWithUnsignedShort:180U]; + [cluster openBasicCommissioningWindowWithParams:params + completion:^(NSError * _Nullable err) { + NSLog(@"Open Commissioning Window from alpha Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestCommissionFromTh2_3() + { + + chip::app::Clusters::CommissionerCommands::Commands::PairWithCode::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + value.payload = mPayload.HasValue() ? mPayload.Value() : chip::Span("MT:-24J0AFN00KA0648G00", 22); + return PairWithCode("beta", value); + } + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForTh2_4() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("beta", value); + } + NSNumber * _Nonnull th2FabricIndex; + + CHIP_ERROR TestTh2ReadsTheFabricIndex_5() + { + + MTRBaseDevice * device = GetDevice("beta"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device + endpointID:@(0) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeCurrentFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH2 reads the fabric index Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + th2FabricIndex = value; + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh1WritesAclGivingViewPrivilegeForDescriptorCluster_6() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + id aclArgument; + { + NSMutableArray * temp_0 = [[NSMutableArray alloc] init]; + temp_0[0] = [[MTRAccessControlClusterAccessControlEntryStruct alloc] init]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).privilege = [NSNumber numberWithUnsignedChar:5U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).authMode = [NSNumber numberWithUnsignedChar:2U]; + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [NSNumber numberWithUnsignedLongLong:commissionerNodeId]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).subjects = temp_3; + } + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [[MTRAccessControlClusterTarget alloc] init]; + ((MTRAccessControlClusterTarget *) temp_3[0]).cluster = [NSNumber numberWithUnsignedInt:31UL]; + ((MTRAccessControlClusterTarget *) temp_3[0]).endpoint = [NSNumber numberWithUnsignedShort:0U]; + ((MTRAccessControlClusterTarget *) temp_3[0]).deviceType = nil; + + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).targets = temp_3; + } + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).fabricIndex = [th1FabricIndex copy]; + + temp_0[1] = [[MTRAccessControlClusterAccessControlEntryStruct alloc] init]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).privilege = [NSNumber numberWithUnsignedChar:1U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).authMode = [NSNumber numberWithUnsignedChar:2U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).subjects = nil; + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [[MTRAccessControlClusterTarget alloc] init]; + ((MTRAccessControlClusterTarget *) temp_3[0]).cluster = [NSNumber numberWithUnsignedInt:29UL]; + ((MTRAccessControlClusterTarget *) temp_3[0]).endpoint = [NSNumber numberWithUnsignedShort:0U]; + ((MTRAccessControlClusterTarget *) temp_3[0]).deviceType = nil; + + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).targets = temp_3; + } + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).fabricIndex = [th1FabricIndex copy]; + + aclArgument = temp_0; + } + [cluster writeAttributeACLWithValue:aclArgument + completion:^(NSError * _Nullable err) { + NSLog(@"TH1 writes ACL giving view privilege for descriptor cluster Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh2WritesAclGivingViewPrivilgeForBasicCluster_7() + { + + MTRBaseDevice * device = GetDevice("beta"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + id aclArgument; + { + NSMutableArray * temp_0 = [[NSMutableArray alloc] init]; + temp_0[0] = [[MTRAccessControlClusterAccessControlEntryStruct alloc] init]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).privilege = [NSNumber numberWithUnsignedChar:5U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).authMode = [NSNumber numberWithUnsignedChar:2U]; + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [NSNumber numberWithUnsignedLongLong:commissionerNodeId]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).subjects = temp_3; + } + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [[MTRAccessControlClusterTarget alloc] init]; + ((MTRAccessControlClusterTarget *) temp_3[0]).cluster = [NSNumber numberWithUnsignedInt:31UL]; + ((MTRAccessControlClusterTarget *) temp_3[0]).endpoint = [NSNumber numberWithUnsignedShort:0U]; + ((MTRAccessControlClusterTarget *) temp_3[0]).deviceType = nil; + + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).targets = temp_3; + } + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).fabricIndex = [th2FabricIndex copy]; + + temp_0[1] = [[MTRAccessControlClusterAccessControlEntryStruct alloc] init]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).privilege = [NSNumber numberWithUnsignedChar:1U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).authMode = [NSNumber numberWithUnsignedChar:2U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).subjects = nil; + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [[MTRAccessControlClusterTarget alloc] init]; + ((MTRAccessControlClusterTarget *) temp_3[0]).cluster = [NSNumber numberWithUnsignedInt:40UL]; + ((MTRAccessControlClusterTarget *) temp_3[0]).endpoint = [NSNumber numberWithUnsignedShort:0U]; + ((MTRAccessControlClusterTarget *) temp_3[0]).deviceType = nil; + + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).targets = temp_3; + } + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[1]).fabricIndex = [th2FabricIndex copy]; + + aclArgument = temp_0; + } + [cluster writeAttributeACLWithValue:aclArgument + completion:^(NSError * _Nullable err) { + NSLog(@"TH2 writes ACL giving view privilge for basic cluster Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh1ReadsDescriptorClusterExpectSuccess_8() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeDeviceTypeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH1 reads descriptor cluster - expect SUCCESS Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh1ReadsBasicClusterExpectUnsupportedAccess_9() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH1 reads basic cluster - expect UNSUPPORTED_ACCESS Error: %@", err); + + VerifyOrReturn(CheckValue("status", + err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, + EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh2ReadsDescriptorClusterExpectUnsupportedAccess_10() + { + + MTRBaseDevice * device = GetDevice("beta"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeDeviceTypeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH2 reads descriptor cluster - expect UNSUPPORTED_ACCESS Error: %@", err); + + VerifyOrReturn(CheckValue("status", + err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, + EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS)); + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh2ReadsBasicClusterExpectSuccess_11() + { + + MTRBaseDevice * device = GetDevice("beta"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { + NSLog(@"TH2 reads basic cluster - expect SUCCESS Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh1ResetsAclToDefault_12() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + id aclArgument; + { + NSMutableArray * temp_0 = [[NSMutableArray alloc] init]; + temp_0[0] = [[MTRAccessControlClusterAccessControlEntryStruct alloc] init]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).privilege = [NSNumber numberWithUnsignedChar:5U]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).authMode = [NSNumber numberWithUnsignedChar:2U]; + { + NSMutableArray * temp_3 = [[NSMutableArray alloc] init]; + temp_3[0] = [NSNumber numberWithUnsignedLongLong:commissionerNodeId]; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).subjects = temp_3; + } + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).targets = nil; + ((MTRAccessControlClusterAccessControlEntryStruct *) temp_0[0]).fabricIndex = [NSNumber numberWithUnsignedChar:1U]; + + aclArgument = temp_0; + } + [cluster writeAttributeACLWithValue:aclArgument + completion:^(NSError * _Nullable err) { + NSLog(@"TH1 resets ACL to default Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestTh1SendsRemoveFabricCommandForTh2_13() + { + + MTRBaseDevice * device = GetDevice("alpha"); + commissionerNodeId = mCommissionerNodeId.ValueOr(0); + __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device + endpointID:@(0) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + __auto_type * params = [[MTROperationalCredentialsClusterRemoveFabricParams alloc] init]; + params.fabricIndex = [th2FabricIndex copy]; + [cluster removeFabricWithParams:params + completion:^( + MTROperationalCredentialsClusterNOCResponseParams * _Nullable values, NSError * _Nullable err) { + NSLog(@"TH1 sends RemoveFabric command for TH2 Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + class Test_TC_BOOL_1_1 : public TestCommandBridge { public: // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced @@ -135475,6 +136011,7 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), make_unique(), make_unique(), make_unique(),