From 26e9a97ea3b91ebe952aafd1a9eb76cd911ff785 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 22 Mar 2022 14:08:42 -0400 Subject: [PATCH] Implement required check for adding an already-existing fabric. (#16404) Per spec, AddNOC should fail if the fabric id and root public key of the new NOC match an existing fabric. We were not implementing this check. --- .../templates/partials/test_cluster.zapt | 3 +- .../tests/partials/test_cluster.zapt | 3 +- .../linux/LinuxCommissionableDataProvider.h | 2 +- .../operational-credentials-server.cpp | 4 + src/app/tests/suites/TestMultiAdmin.yaml | 38 +++ .../commissioner/CommissionerCommands.cpp | 42 ++- .../commissioner/CommissionerCommands.h | 5 +- src/controller/CHIPDeviceController.cpp | 3 +- src/credentials/FabricTable.cpp | 25 ++ .../tests/partials/test_cluster.zapt | 2 +- src/lib/core/CHIPError.cpp | 25 +- src/lib/core/CHIPError.h | 69 +---- src/lib/core/tests/TestCHIPErrorStr.cpp | 9 +- src/lib/support/CodeUtils.h | 2 +- .../chip-tool/zap-generated/test/Commands.h | 241 +++++++++++++----- 15 files changed, 313 insertions(+), 160 deletions(-) diff --git a/examples/chip-tool-darwin/templates/partials/test_cluster.zapt b/examples/chip-tool-darwin/templates/partials/test_cluster.zapt index 3b49c707311442..9f2ac193e903da 100644 --- a/examples/chip-tool-darwin/templates/partials/test_cluster.zapt +++ b/examples/chip-tool-darwin/templates/partials/test_cluster.zapt @@ -107,7 +107,8 @@ class {{filename}}: public TestCommandBridge {{else}} {{#if (isString type)}}@"{{/if}}{{definedValue}}{{#if (isString type)}}"{{/if}} {{~/if~}} - {{/chip_tests_item_parameters}}); + {{/chip_tests_item_parameters}} + {{additionalArguments}}); {{else}} CHIPDevice * device = GetConnectedDevice(); CHIPTest{{asUpperCamelCase cluster}} * cluster = [[CHIPTest{{asUpperCamelCase cluster}} alloc] initWithDevice:device endpoint:{{endpoint}} queue:mCallbackQueue]; diff --git a/examples/chip-tool/templates/tests/partials/test_cluster.zapt b/examples/chip-tool/templates/tests/partials/test_cluster.zapt index 27616a54ed9c2e..aa11b89cc0f81b 100644 --- a/examples/chip-tool/templates/tests/partials/test_cluster.zapt +++ b/examples/chip-tool/templates/tests/partials/test_cluster.zapt @@ -203,7 +203,8 @@ class {{filename}}Suite: public TestCommand {{~else if (isString type)}}"{{definedValue}}" {{else}}{{definedValue}} {{~/if~}} - {{/chip_tests_item_parameters}}); + {{/chip_tests_item_parameters}} + {{additionalArguments}}); } {{else if isWait}} CHIP_ERROR {{>testCommand}}() diff --git a/examples/platform/linux/LinuxCommissionableDataProvider.h b/examples/platform/linux/LinuxCommissionableDataProvider.h index 2254177c754734..81a6e6b0f39284 100644 --- a/examples/platform/linux/LinuxCommissionableDataProvider.h +++ b/examples/platform/linux/LinuxCommissionableDataProvider.h @@ -53,7 +53,7 @@ class LinuxCommissionableDataProvider : public chip::DeviceLayer::Commissionable * PASE verifier if `serializedSpake2pVerifier` argument empty. * @param discriminator - Discriminator to use for advertising. * @return CHIP_ERROR_OK on success, CHIP_ERROR_INVALID_ARGUMENT on any invalid argument combinations, - * CHIP_ERROR_INVALID_STATE if already initialized, or other CHIP_ERROR values if inner + * CHIP_ERROR_INCORRECT_STATE if already initialized, or other CHIP_ERROR values if inner * implementation dependencies fail. */ CHIP_ERROR Init(chip::Optional> serializedSpake2pVerifier, diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index e0732e7a8bbe75..7b26f8d9e090cf 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -564,6 +564,10 @@ OperationalCertStatus ConvertToNOCResponseStatus(CHIP_ERROR err) { return OperationalCertStatus::kTableFull; } + else if (err == CHIP_ERROR_FABRIC_EXISTS) + { + return OperationalCertStatus::kFabricConflict; + } return OperationalCertStatus::kInvalidNOC; } diff --git a/src/app/tests/suites/TestMultiAdmin.yaml b/src/app/tests/suites/TestMultiAdmin.yaml index be4c9ba14a8f84..0d60fdaaccaa60 100644 --- a/src/app/tests/suites/TestMultiAdmin.yaml +++ b/src/app/tests/suites/TestMultiAdmin.yaml @@ -16,6 +16,9 @@ name: Test Multi Admin config: nodeId: 0x12344321 + nodeIdForDuplicateCommissioning: + type: NODE_ID + defaultValue: 0x11 nodeId2: type: NODE_ID defaultValue: 0xCAFE @@ -56,6 +59,41 @@ tests: - name: "CommissioningTimeout" value: 120 + - label: "Commission from alpha again" + identity: "alpha" + cluster: "CommissionerCommands" + command: "PairWithQRCode" + additionalArguments: ", CHIP_ERROR_FABRIC_EXISTS" + arguments: + values: + - name: "nodeId" + value: nodeIdForDuplicateCommissioning + - name: "payload" + value: payload + + - label: "Check that we just have the one fabric and did not add a new one" + identity: "alpha" + cluster: "Operational Credentials" + command: "readAttribute" + attribute: "Fabrics" + fabricFiltered: false + response: + value: [{ "nodeID": nodeId }] + + - label: "Close Commissioning Window after failed commissioning" + cluster: "AdministratorCommissioning" + command: "RevokeCommissioning" + timedInteractionTimeoutMs: 10000 + + - label: "Open Commissioning Window from alpha again" + cluster: "AdministratorCommissioning" + command: "OpenBasicCommissioningWindow" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "CommissioningTimeout" + value: 120 + - label: "Commission from beta" identity: "beta" cluster: "CommissionerCommands" diff --git a/src/app/tests/suites/commands/commissioner/CommissionerCommands.cpp b/src/app/tests/suites/commands/commissioner/CommissionerCommands.cpp index ec84e807f4ca63..49e2b0a9ca46d1 100644 --- a/src/app/tests/suites/commands/commissioner/CommissionerCommands.cpp +++ b/src/app/tests/suites/commands/commissioner/CommissionerCommands.cpp @@ -20,10 +20,12 @@ constexpr uint16_t kPayloadMaxSize = 64; -CHIP_ERROR CommissionerCommands::PairWithQRCode(chip::NodeId nodeId, const chip::CharSpan payload) +CHIP_ERROR CommissionerCommands::PairWithQRCode(chip::NodeId nodeId, const chip::CharSpan payload, CHIP_ERROR expectedStatus) { VerifyOrReturnError(payload.size() > 0 && payload.size() < kPayloadMaxSize, CHIP_ERROR_INVALID_ARGUMENT); + mExpectedStatus = expectedStatus; + GetCurrentCommissioner().RegisterPairingDelegate(this); char qrCode[kPayloadMaxSize]; @@ -35,6 +37,8 @@ CHIP_ERROR CommissionerCommands::PairWithManualCode(chip::NodeId nodeId, const c { VerifyOrReturnError(payload.size() > 0 && payload.size() < kPayloadMaxSize, CHIP_ERROR_INVALID_ARGUMENT); + mExpectedStatus = CHIP_NO_ERROR; + GetCurrentCommissioner().RegisterPairingDelegate(this); char manualCode[kPayloadMaxSize]; @@ -44,6 +48,8 @@ CHIP_ERROR CommissionerCommands::PairWithManualCode(chip::NodeId nodeId, const c CHIP_ERROR CommissionerCommands::Unpair(chip::NodeId nodeId) { + mExpectedStatus = CHIP_NO_ERROR; + return GetCurrentCommissioner().UnpairDevice(nodeId); } @@ -71,9 +77,22 @@ void CommissionerCommands::OnPairingComplete(CHIP_ERROR err) void CommissionerCommands::OnPairingDeleted(CHIP_ERROR err) { - if (CHIP_NO_ERROR != err) + if (mExpectedStatus != err) { - ChipLogError(chipTool, "Pairing Delete Failure: %s", ErrorStr(err)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(chipTool, "Pairing Delete Failure: %s", ErrorStr(err)); + } + else + { + ChipLogError(chipTool, "Got success but expected: %s", ErrorStr(mExpectedStatus)); + err = CHIP_ERROR_INCORRECT_STATE; + } + } + else + { + // Treat as success. + err = CHIP_NO_ERROR; } LogErrorOnFailure(ContinueOnChipMainThread(err)); @@ -81,9 +100,22 @@ void CommissionerCommands::OnPairingDeleted(CHIP_ERROR err) void CommissionerCommands::OnCommissioningComplete(chip::NodeId nodeId, CHIP_ERROR err) { - if (CHIP_NO_ERROR != err) + if (mExpectedStatus != err) + { + if (err != CHIP_NO_ERROR) + { + ChipLogError(chipTool, "Commissioning Complete Failure: %s", ErrorStr(err)); + } + else + { + ChipLogError(chipTool, "Got success but expected: %s", ErrorStr(mExpectedStatus)); + err = CHIP_ERROR_INCORRECT_STATE; + } + } + else { - ChipLogError(chipTool, "Commissioning Complete Failure: %s", ErrorStr(err)); + // Treat as success. + err = CHIP_NO_ERROR; } LogErrorOnFailure(ContinueOnChipMainThread(err)); diff --git a/src/app/tests/suites/commands/commissioner/CommissionerCommands.h b/src/app/tests/suites/commands/commissioner/CommissionerCommands.h index bd622c9a10ba31..370723ec498382 100644 --- a/src/app/tests/suites/commands/commissioner/CommissionerCommands.h +++ b/src/app/tests/suites/commands/commissioner/CommissionerCommands.h @@ -30,7 +30,7 @@ class CommissionerCommands : public chip::Controller::DevicePairingDelegate virtual CHIP_ERROR ContinueOnChipMainThread(CHIP_ERROR err) = 0; virtual chip::Controller::DeviceCommissioner & GetCurrentCommissioner() = 0; - CHIP_ERROR PairWithQRCode(chip::NodeId nodeId, const chip::CharSpan payload); + CHIP_ERROR PairWithQRCode(chip::NodeId nodeId, const chip::CharSpan payload, CHIP_ERROR expectedStatus = CHIP_NO_ERROR); CHIP_ERROR PairWithManualCode(chip::NodeId nodeId, const chip::CharSpan payload); CHIP_ERROR Unpair(chip::NodeId nodeId); @@ -39,4 +39,7 @@ class CommissionerCommands : public chip::Controller::DevicePairingDelegate void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR error) override; + +private: + CHIP_ERROR mExpectedStatus = CHIP_NO_ERROR; }; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index e4e78ef22fa051..90553946503d92 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1293,8 +1293,9 @@ CHIP_ERROR DeviceCommissioner::ConvertFromOperationalCertStatus(OperationalCrede return CHIP_ERROR_INCORRECT_STATE; case OperationalCertStatus::kTableFull: return CHIP_ERROR_NO_MEMORY; - case OperationalCertStatus::kInsufficientPrivilege: case OperationalCertStatus::kFabricConflict: + return CHIP_ERROR_FABRIC_EXISTS; + case OperationalCertStatus::kInsufficientPrivilege: case OperationalCertStatus::kLabelConflict: return CHIP_ERROR_INVALID_ARGUMENT; case OperationalCertStatus::kInvalidFabricIndex: diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index 2642e82cb2dbda..e5b1fc37f95bdc 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -677,6 +677,31 @@ CHIP_ERROR FabricTable::AddNewFabric(FabricInfo & newFabric, FabricIndex * outpu { VerifyOrReturnError(outputIndex != nullptr, CHIP_ERROR_INVALID_ARGUMENT); static_assert(kMaxValidFabricIndex <= UINT8_MAX, "Cannot create more fabrics than UINT8_MAX"); + + // Check whether we already have a matching fabric. An incoming fabric does + // not have its fabric id set yet, so we have to extract it here to do the + // comparison. + FabricId fabricId; + { + ByteSpan noc; + ReturnErrorOnFailure(newFabric.GetNOCCert(noc)); + NodeId unused; + ReturnErrorOnFailure(ExtractNodeIdFabricIdFromOpCert(noc, &unused, &fabricId)); + } + for (auto & existingFabric : *this) + { + if (existingFabric.GetFabricId() == fabricId) + { + P256PublicKeySpan existingRootKey, newRootKey; + ReturnErrorOnFailure(existingFabric.GetRootPubkey(existingRootKey)); + ReturnErrorOnFailure(newFabric.GetRootPubkey(newRootKey)); + if (existingRootKey.data_equal(newRootKey)) + { + return CHIP_ERROR_FABRIC_EXISTS; + } + } + } + for (FabricIndex i = mNextAvailableFabricIndex; i <= kMaxValidFabricIndex; i++) { FabricInfo * fabric = FindFabricWithIndex(i); diff --git a/src/darwin/Framework/CHIP/templates/tests/partials/test_cluster.zapt b/src/darwin/Framework/CHIP/templates/tests/partials/test_cluster.zapt index 1ff01dfd9fae4b..bae3552ed913ac 100644 --- a/src/darwin/Framework/CHIP/templates/tests/partials/test_cluster.zapt +++ b/src/darwin/Framework/CHIP/templates/tests/partials/test_cluster.zapt @@ -24,7 +24,7 @@ ResponseHandler {{> subscribeDataCallback}} = nil; {{#if (isTestOnlyCluster cluster)}} dispatch_queue_t queue = dispatch_get_main_queue(); - {{command}}(expectation, queue{{#chip_tests_item_parameters}}, {{#if (isString type)}}@"{{/if}}{{> defined_value}}{{#if (isString type)}}"{{/if}}{{/chip_tests_item_parameters}}); + {{command}}(expectation, queue{{#chip_tests_item_parameters}}, {{#if (isString type)}}@"{{/if}}{{> defined_value}}{{#if (isString type)}}"{{/if}}{{/chip_tests_item_parameters}}{{additionalArguments}}); {{else}} CHIPDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); diff --git a/src/lib/core/CHIPError.cpp b/src/lib/core/CHIPError.cpp index 2f999000ab4443..95476499a175a8 100644 --- a/src/lib/core/CHIPError.cpp +++ b/src/lib/core/CHIPError.cpp @@ -410,29 +410,8 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) case CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED.AsInteger(): desc = "DRBG entropy source failed to generate entropy data"; break; - case CHIP_ERROR_NO_TAKE_AUTH_DELEGATE.AsInteger(): - desc = "No TAKE auth delegate set"; - break; - case CHIP_ERROR_TAKE_RECONFIGURE_REQUIRED.AsInteger(): - desc = "TAKE requires a reconfigure"; - break; - case CHIP_ERROR_TAKE_REAUTH_POSSIBLE.AsInteger(): - desc = "TAKE can do a reauthentication"; - break; - case CHIP_ERROR_INVALID_TAKE_PARAMETER.AsInteger(): - desc = "TAKE received an invalid parameter"; - break; - case CHIP_ERROR_UNSUPPORTED_TAKE_CONFIGURATION.AsInteger(): - desc = "TAKE Unsupported configuration"; - break; - case CHIP_ERROR_TAKE_TOKEN_IDENTIFICATION_FAILED.AsInteger(): - desc = "TAKE token identification failed"; - break; - case CHIP_ERROR_INVALID_TOKENPAIRINGBUNDLE.AsInteger(): - desc = "Invalid Token Pairing Bundle"; - break; - case CHIP_ERROR_UNSUPPORTED_TOKENPAIRINGBUNDLE_VERSION.AsInteger(): - desc = "Unsupported Token Pairing Bundle version"; + case CHIP_ERROR_FABRIC_EXISTS.AsInteger(): + desc = "Trying to add a NOC for a fabric that already exists"; break; case CHIP_ERROR_KEY_NOT_FOUND_FROM_PEER.AsInteger(): desc = "Key not found error code received from peer"; diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index d1f7c440c7312d..82bab653298940 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -1500,77 +1500,28 @@ using CHIP_ERROR = ::chip::ChipError; */ #define CHIP_ERROR_TLV_TAG_NOT_FOUND CHIP_CORE_ERROR(0x76) -/** - * @def CHIP_ERROR_INVALID_TOKENPAIRINGBUNDLE - * - * @brief - * A token pairing bundle is invalid. - * - */ -#define CHIP_ERROR_INVALID_TOKENPAIRINGBUNDLE CHIP_CORE_ERROR(0x77) +// unused CHIP_CORE_ERROR(0x77) -/** - * @def CHIP_ERROR_UNSUPPORTED_TOKENPAIRINGBUNDLE_VERSION - * - * @brief - * A token pairing bundle is invalid. - * - */ -#define CHIP_ERROR_UNSUPPORTED_TOKENPAIRINGBUNDLE_VERSION CHIP_CORE_ERROR(0x78) +// unused CHIP_CORE_ERROR(0x78) -/** - * @def CHIP_ERROR_NO_TAKE_AUTH_DELEGATE - * - * @brief - * No TAKE authentication delegate is set. - * - */ -#define CHIP_ERROR_NO_TAKE_AUTH_DELEGATE CHIP_CORE_ERROR(0x79) +// unused CHIP_CORE_ERROR(0x79) -/** - * @def CHIP_ERROR_TAKE_RECONFIGURE_REQUIRED - * - * @brief - * TAKE requires a reconfigure. - * - */ -#define CHIP_ERROR_TAKE_RECONFIGURE_REQUIRED CHIP_CORE_ERROR(0x7a) +// unused CHIP_CORE_ERROR(0x7a) -/** - * @def CHIP_ERROR_TAKE_REAUTH_POSSIBLE - * - * @brief - * TAKE can do a reauthentication. - * - */ -#define CHIP_ERROR_TAKE_REAUTH_POSSIBLE CHIP_CORE_ERROR(0x7b) +// unused CHIP_CORE_ERROR(0x7b) -/** - * @def CHIP_ERROR_INVALID_TAKE_PARAMETER - * - * @brief - * Received an invalid TAKE parameter. - * - */ -#define CHIP_ERROR_INVALID_TAKE_PARAMETER CHIP_CORE_ERROR(0x7c) +// unused CHIP_CORE_ERROR(0x7c) -/** - * @def CHIP_ERROR_UNSUPPORTED_TAKE_CONFIGURATION - * - * @brief - * This configuration is not supported by TAKE. - * - */ -#define CHIP_ERROR_UNSUPPORTED_TAKE_CONFIGURATION CHIP_CORE_ERROR(0x7d) +// unused CHIP_CORE_ERROR(0x7d) /** - * @def CHIP_ERROR_TAKE_TOKEN_IDENTIFICATION_FAILED + * @def CHIP_ERROR_FABRIC_EXISTS * * @brief - * The TAKE Token Identification failed. + * The fabric with the given fabric id and root public key already exists. * */ -#define CHIP_ERROR_TAKE_TOKEN_IDENTIFICATION_FAILED CHIP_CORE_ERROR(0x7e) +#define CHIP_ERROR_FABRIC_EXISTS CHIP_CORE_ERROR(0x7e) /** * @def CHIP_ERROR_KEY_NOT_FOUND_FROM_PEER diff --git a/src/lib/core/tests/TestCHIPErrorStr.cpp b/src/lib/core/tests/TestCHIPErrorStr.cpp index 9e5b165763e915..3442f0f33dc2be 100644 --- a/src/lib/core/tests/TestCHIPErrorStr.cpp +++ b/src/lib/core/tests/TestCHIPErrorStr.cpp @@ -164,14 +164,7 @@ static const CHIP_ERROR kTestElements[] = CHIP_ERROR_INVALID_FABRIC_ID, CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED, CHIP_ERROR_TLV_TAG_NOT_FOUND, - CHIP_ERROR_INVALID_TOKENPAIRINGBUNDLE, - CHIP_ERROR_UNSUPPORTED_TOKENPAIRINGBUNDLE_VERSION, - CHIP_ERROR_NO_TAKE_AUTH_DELEGATE, - CHIP_ERROR_TAKE_RECONFIGURE_REQUIRED, - CHIP_ERROR_TAKE_REAUTH_POSSIBLE, - CHIP_ERROR_INVALID_TAKE_PARAMETER, - CHIP_ERROR_UNSUPPORTED_TAKE_CONFIGURATION, - CHIP_ERROR_TAKE_TOKEN_IDENTIFICATION_FAILED, + CHIP_ERROR_FABRIC_EXISTS, CHIP_ERROR_KEY_NOT_FOUND_FROM_PEER, CHIP_ERROR_WRONG_ENCRYPTION_TYPE_FROM_PEER, CHIP_ERROR_UNKNOWN_KEY_TYPE_FROM_PEER, diff --git a/src/lib/support/CodeUtils.h b/src/lib/support/CodeUtils.h index 5b4dbbfbdd3515..f896da6c7484d1 100644 --- a/src/lib/support/CodeUtils.h +++ b/src/lib/support/CodeUtils.h @@ -341,7 +341,7 @@ constexpr inline const _T & max(const _T & a, const _T & b) * * @code * ReturnErrorCodeIf(state == kInitialized, CHIP_NO_ERROR); - * ReturnErrorCodeIf(state == kInitialized, CHIP_ERROR_INVALID_STATE); + * ReturnErrorCodeIf(state == kInitialized, CHIP_ERROR_INCORRECT_STATE); * @endcode * * @param[in] expr A Boolean expression to be evaluated. diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index bf960637442638..b864c52c471460 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -91188,6 +91188,7 @@ class TestMultiAdminSuite : public TestCommand TestCommand("TestMultiAdmin", credsIssuerConfig), mTestIndex(0) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("nodeIdForDuplicateCommissioning", 0, UINT64_MAX, &mNodeIdForDuplicateCommissioning); AddArgument("nodeId2", 0, UINT64_MAX, &mNodeId2); AddArgument("nodeId3", 0, UINT64_MAX, &mNodeId3); AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); @@ -91243,40 +91244,56 @@ class TestMultiAdminSuite : public TestCommand err = TestOpenCommissioningWindowFromAlpha_2(); break; case 3: - ChipLogProgress(chipTool, " ***** Test Step 3 : Commission from beta\n"); - err = TestCommissionFromBeta_3(); + ChipLogProgress(chipTool, " ***** Test Step 3 : Commission from alpha again\n"); + err = TestCommissionFromAlphaAgain_3(); break; case 4: - ChipLogProgress(chipTool, " ***** Test Step 4 : Wait for the commissioned device to be retrieved for beta\n"); - err = TestWaitForTheCommissionedDeviceToBeRetrievedForBeta_4(); + ChipLogProgress(chipTool, " ***** Test Step 4 : Check that we just have the one fabric and did not add a new one\n"); + err = TestCheckThatWeJustHaveTheOneFabricAndDidNotAddANewOne_4(); break; case 5: - ChipLogProgress(chipTool, " ***** Test Step 5 : Open Commissioning Window from beta\n"); - err = TestOpenCommissioningWindowFromBeta_5(); + ChipLogProgress(chipTool, " ***** Test Step 5 : Close Commissioning Window after failed commissioning\n"); + err = TestCloseCommissioningWindowAfterFailedCommissioning_5(); break; case 6: - ChipLogProgress(chipTool, " ***** Test Step 6 : Commission from gamma\n"); - err = TestCommissionFromGamma_6(); + ChipLogProgress(chipTool, " ***** Test Step 6 : Open Commissioning Window from alpha again\n"); + err = TestOpenCommissioningWindowFromAlphaAgain_6(); break; case 7: - ChipLogProgress(chipTool, " ***** Test Step 7 : Wait for the commissioned device to be retrieved for gamma\n"); - err = TestWaitForTheCommissionedDeviceToBeRetrievedForGamma_7(); + ChipLogProgress(chipTool, " ***** Test Step 7 : Commission from beta\n"); + err = TestCommissionFromBeta_7(); break; case 8: - ChipLogProgress(chipTool, " ***** Test Step 8 : read the mandatory attribute: NodeLabel from alpha\n"); - err = TestReadTheMandatoryAttributeNodeLabelFromAlpha_8(); + ChipLogProgress(chipTool, " ***** Test Step 8 : Wait for the commissioned device to be retrieved for beta\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrievedForBeta_8(); break; case 9: - ChipLogProgress(chipTool, " ***** Test Step 9 : write the mandatory attribute NodeLabel from beta\n"); - err = TestWriteTheMandatoryAttributeNodeLabelFromBeta_9(); + ChipLogProgress(chipTool, " ***** Test Step 9 : Open Commissioning Window from beta\n"); + err = TestOpenCommissioningWindowFromBeta_9(); break; case 10: - ChipLogProgress(chipTool, " ***** Test Step 10 : read the mandatory attribute: NodeLabel from gamma\n"); - err = TestReadTheMandatoryAttributeNodeLabelFromGamma_10(); + ChipLogProgress(chipTool, " ***** Test Step 10 : Commission from gamma\n"); + err = TestCommissionFromGamma_10(); break; case 11: - ChipLogProgress(chipTool, " ***** Test Step 11 : write the mandatory attribute NodeLabel back to default\n"); - err = TestWriteTheMandatoryAttributeNodeLabelBackToDefault_11(); + ChipLogProgress(chipTool, " ***** Test Step 11 : Wait for the commissioned device to be retrieved for gamma\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrievedForGamma_11(); + break; + case 12: + ChipLogProgress(chipTool, " ***** Test Step 12 : read the mandatory attribute: NodeLabel from alpha\n"); + err = TestReadTheMandatoryAttributeNodeLabelFromAlpha_12(); + break; + case 13: + ChipLogProgress(chipTool, " ***** Test Step 13 : write the mandatory attribute NodeLabel from beta\n"); + err = TestWriteTheMandatoryAttributeNodeLabelFromBeta_13(); + break; + case 14: + ChipLogProgress(chipTool, " ***** Test Step 14 : read the mandatory attribute: NodeLabel from gamma\n"); + err = TestReadTheMandatoryAttributeNodeLabelFromGamma_14(); + break; + case 15: + ChipLogProgress(chipTool, " ***** Test Step 15 : write the mandatory attribute NodeLabel back to default\n"); + err = TestWriteTheMandatoryAttributeNodeLabelBackToDefault_15(); break; } @@ -91294,9 +91311,10 @@ class TestMultiAdminSuite : public TestCommand private: std::atomic_uint16_t mTestIndex; - const uint16_t mTestCount = 12; + const uint16_t mTestCount = 16; chip::Optional mNodeId; + chip::Optional mNodeIdForDuplicateCommissioning; chip::Optional mNodeId2; chip::Optional mNodeId3; chip::Optional mEndpoint; @@ -91315,39 +91333,52 @@ class TestMultiAdminSuite : public TestCommand NextTest(); } - static void OnFailureCallback_8(void * context, CHIP_ERROR error) + static void OnFailureCallback_4(void * context, CHIP_ERROR error) { - (static_cast(context))->OnFailureResponse_8(error); + (static_cast(context))->OnFailureResponse_4(error); } - static void OnSuccessCallback_8(void * context, chip::CharSpan nodeLabel) + static void + OnSuccessCallback_4(void * context, + const chip::app::DataModel::DecodableList< + chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & fabrics) { - (static_cast(context))->OnSuccessResponse_8(nodeLabel); + (static_cast(context))->OnSuccessResponse_4(fabrics); } - static void OnFailureCallback_9(void * context, CHIP_ERROR error) + static void OnFailureCallback_12(void * context, CHIP_ERROR error) { - (static_cast(context))->OnFailureResponse_9(error); + (static_cast(context))->OnFailureResponse_12(error); } - static void OnSuccessCallback_9(void * context) { (static_cast(context))->OnSuccessResponse_9(); } + static void OnSuccessCallback_12(void * context, chip::CharSpan nodeLabel) + { + (static_cast(context))->OnSuccessResponse_12(nodeLabel); + } - static void OnFailureCallback_10(void * context, CHIP_ERROR error) + static void OnFailureCallback_13(void * context, CHIP_ERROR error) { - (static_cast(context))->OnFailureResponse_10(error); + (static_cast(context))->OnFailureResponse_13(error); } - static void OnSuccessCallback_10(void * context, chip::CharSpan nodeLabel) + static void OnSuccessCallback_13(void * context) { (static_cast(context))->OnSuccessResponse_13(); } + + static void OnFailureCallback_14(void * context, CHIP_ERROR error) { - (static_cast(context))->OnSuccessResponse_10(nodeLabel); + (static_cast(context))->OnFailureResponse_14(error); } - static void OnFailureCallback_11(void * context, CHIP_ERROR error) + static void OnSuccessCallback_14(void * context, chip::CharSpan nodeLabel) + { + (static_cast(context))->OnSuccessResponse_14(nodeLabel); + } + + static void OnFailureCallback_15(void * context, CHIP_ERROR error) { - (static_cast(context))->OnFailureResponse_11(error); + (static_cast(context))->OnFailureResponse_15(error); } - static void OnSuccessCallback_11(void * context) { (static_cast(context))->OnSuccessResponse_11(); } + static void OnSuccessCallback_15(void * context) { (static_cast(context))->OnSuccessResponse_15(); } // // Tests methods @@ -91394,20 +91425,114 @@ class TestMultiAdminSuite : public TestCommand void OnSuccessResponse_2() { NextTest(); } - CHIP_ERROR TestCommissionFromBeta_3() + CHIP_ERROR TestCommissionFromAlphaAgain_3() + { + SetIdentity(kIdentityAlpha); + return PairWithQRCode(mNodeIdForDuplicateCommissioning.HasValue() ? mNodeIdForDuplicateCommissioning.Value() : 17ULL, + mPayload.HasValue() ? mPayload.Value() : chip::CharSpan::fromCharString("MT:-24J0AFN00KA0648G00"), + CHIP_ERROR_FABRIC_EXISTS); + } + + CHIP_ERROR TestCheckThatWeJustHaveTheOneFabricAndDidNotAddANewOne_4() + { + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; + chip::Controller::OperationalCredentialsClusterTest cluster; + cluster.Associate(mDevices[kIdentityAlpha], endpoint); + + ReturnErrorOnFailure(cluster.ReadAttribute( + this, OnSuccessCallback_4, OnFailureCallback_4, false)); + return CHIP_NO_ERROR; + } + + void OnFailureResponse_4(CHIP_ERROR error) + { + chip::app::StatusIB status(error); + ThrowFailureResponse(); + } + + void OnSuccessResponse_4(const chip::app::DataModel::DecodableList< + chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & fabrics) + { + { + auto iter_0 = fabrics.begin(); + VerifyOrReturn(CheckNextListItemDecodes("fabrics", iter_0, 0)); + VerifyOrReturn(CheckNoMoreListItems("fabrics", iter_0, 1)); + } + + NextTest(); + } + + CHIP_ERROR TestCloseCommissioningWindowAfterFailedCommissioning_5() + { + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; + using RequestType = chip::app::Clusters::AdministratorCommissioning::Commands::RevokeCommissioning::Type; + + RequestType request; + + auto success = [](void * context, const typename RequestType::ResponseType & data) { + (static_cast(context))->OnSuccessResponse_5(); + }; + + auto failure = [](void * context, CHIP_ERROR error) { + (static_cast(context))->OnFailureResponse_5(error); + }; + + ReturnErrorOnFailure( + chip::Controller::InvokeCommand(mDevices[kIdentityAlpha], this, success, failure, endpoint, request, 10000)); + return CHIP_NO_ERROR; + } + + void OnFailureResponse_5(CHIP_ERROR error) + { + chip::app::StatusIB status(error); + ThrowFailureResponse(); + } + + void OnSuccessResponse_5() { NextTest(); } + + CHIP_ERROR TestOpenCommissioningWindowFromAlphaAgain_6() + { + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; + using RequestType = chip::app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type; + + RequestType request; + request.commissioningTimeout = 120U; + + auto success = [](void * context, const typename RequestType::ResponseType & data) { + (static_cast(context))->OnSuccessResponse_6(); + }; + + auto failure = [](void * context, CHIP_ERROR error) { + (static_cast(context))->OnFailureResponse_6(error); + }; + + ReturnErrorOnFailure( + chip::Controller::InvokeCommand(mDevices[kIdentityAlpha], this, success, failure, endpoint, request, 10000)); + return CHIP_NO_ERROR; + } + + void OnFailureResponse_6(CHIP_ERROR error) + { + chip::app::StatusIB status(error); + ThrowFailureResponse(); + } + + void OnSuccessResponse_6() { NextTest(); } + + CHIP_ERROR TestCommissionFromBeta_7() { SetIdentity(kIdentityBeta); return PairWithQRCode(mNodeId2.HasValue() ? mNodeId2.Value() : 51966ULL, mPayload.HasValue() ? mPayload.Value() : chip::CharSpan::fromCharString("MT:-24J0AFN00KA0648G00")); } - CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForBeta_4() + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForBeta_8() { SetIdentity(kIdentityBeta); return WaitForCommissionee(mNodeId2.HasValue() ? mNodeId2.Value() : 51966ULL); } - CHIP_ERROR TestOpenCommissioningWindowFromBeta_5() + CHIP_ERROR TestOpenCommissioningWindowFromBeta_9() { const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; using RequestType = chip::app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type; @@ -91416,11 +91541,11 @@ class TestMultiAdminSuite : public TestCommand request.commissioningTimeout = 120U; auto success = [](void * context, const typename RequestType::ResponseType & data) { - (static_cast(context))->OnSuccessResponse_5(); + (static_cast(context))->OnSuccessResponse_9(); }; auto failure = [](void * context, CHIP_ERROR error) { - (static_cast(context))->OnFailureResponse_5(error); + (static_cast(context))->OnFailureResponse_9(error); }; ReturnErrorOnFailure( @@ -91428,45 +91553,45 @@ class TestMultiAdminSuite : public TestCommand return CHIP_NO_ERROR; } - void OnFailureResponse_5(CHIP_ERROR error) + void OnFailureResponse_9(CHIP_ERROR error) { chip::app::StatusIB status(error); ThrowFailureResponse(); } - void OnSuccessResponse_5() { NextTest(); } + void OnSuccessResponse_9() { NextTest(); } - CHIP_ERROR TestCommissionFromGamma_6() + CHIP_ERROR TestCommissionFromGamma_10() { SetIdentity(kIdentityGamma); return PairWithQRCode(mNodeId3.HasValue() ? mNodeId3.Value() : 12586990ULL, mPayload.HasValue() ? mPayload.Value() : chip::CharSpan::fromCharString("MT:-24J0AFN00KA0648G00")); } - CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForGamma_7() + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrievedForGamma_11() { SetIdentity(kIdentityGamma); return WaitForCommissionee(mNodeId3.HasValue() ? mNodeId3.Value() : 12586990ULL); } - CHIP_ERROR TestReadTheMandatoryAttributeNodeLabelFromAlpha_8() + CHIP_ERROR TestReadTheMandatoryAttributeNodeLabelFromAlpha_12() { const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::BasicClusterTest cluster; cluster.Associate(mDevices[kIdentityAlpha], endpoint); ReturnErrorOnFailure(cluster.ReadAttribute( - this, OnSuccessCallback_8, OnFailureCallback_8, true)); + this, OnSuccessCallback_12, OnFailureCallback_12, true)); return CHIP_NO_ERROR; } - void OnFailureResponse_8(CHIP_ERROR error) + void OnFailureResponse_12(CHIP_ERROR error) { chip::app::StatusIB status(error); ThrowFailureResponse(); } - void OnSuccessResponse_8(chip::CharSpan nodeLabel) + void OnSuccessResponse_12(chip::CharSpan nodeLabel) { VerifyOrReturn(CheckValueAsString("nodeLabel", nodeLabel, chip::CharSpan("", 0))); @@ -91480,7 +91605,7 @@ class TestMultiAdminSuite : public TestCommand NextTest(); } - CHIP_ERROR TestWriteTheMandatoryAttributeNodeLabelFromBeta_9() + CHIP_ERROR TestWriteTheMandatoryAttributeNodeLabelFromBeta_13() { const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::BasicClusterTest cluster; @@ -91490,43 +91615,43 @@ class TestMultiAdminSuite : public TestCommand nodeLabelArgument = chip::Span("written from betagarbage: not in length on purpose", 17); ReturnErrorOnFailure(cluster.WriteAttribute( - nodeLabelArgument, this, OnSuccessCallback_9, OnFailureCallback_9)); + nodeLabelArgument, this, OnSuccessCallback_13, OnFailureCallback_13)); return CHIP_NO_ERROR; } - void OnFailureResponse_9(CHIP_ERROR error) + void OnFailureResponse_13(CHIP_ERROR error) { chip::app::StatusIB status(error); ThrowFailureResponse(); } - void OnSuccessResponse_9() { NextTest(); } + void OnSuccessResponse_13() { NextTest(); } - CHIP_ERROR TestReadTheMandatoryAttributeNodeLabelFromGamma_10() + CHIP_ERROR TestReadTheMandatoryAttributeNodeLabelFromGamma_14() { const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::BasicClusterTest cluster; cluster.Associate(mDevices[kIdentityGamma], endpoint); ReturnErrorOnFailure(cluster.ReadAttribute( - this, OnSuccessCallback_10, OnFailureCallback_10, true)); + this, OnSuccessCallback_14, OnFailureCallback_14, true)); return CHIP_NO_ERROR; } - void OnFailureResponse_10(CHIP_ERROR error) + void OnFailureResponse_14(CHIP_ERROR error) { chip::app::StatusIB status(error); ThrowFailureResponse(); } - void OnSuccessResponse_10(chip::CharSpan nodeLabel) + void OnSuccessResponse_14(chip::CharSpan nodeLabel) { VerifyOrReturn(CheckConstraintNotValue("nodeLabel", nodeLabel, readFromAlpha)); NextTest(); } - CHIP_ERROR TestWriteTheMandatoryAttributeNodeLabelBackToDefault_11() + CHIP_ERROR TestWriteTheMandatoryAttributeNodeLabelBackToDefault_15() { const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::BasicClusterTest cluster; @@ -91536,17 +91661,17 @@ class TestMultiAdminSuite : public TestCommand nodeLabelArgument = readFromAlpha; ReturnErrorOnFailure(cluster.WriteAttribute( - nodeLabelArgument, this, OnSuccessCallback_11, OnFailureCallback_11)); + nodeLabelArgument, this, OnSuccessCallback_15, OnFailureCallback_15)); return CHIP_NO_ERROR; } - void OnFailureResponse_11(CHIP_ERROR error) + void OnFailureResponse_15(CHIP_ERROR error) { chip::app::StatusIB status(error); ThrowFailureResponse(); } - void OnSuccessResponse_11() { NextTest(); } + void OnSuccessResponse_15() { NextTest(); } }; class Test_TC_SWDIAG_1_1Suite : public TestCommand