diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 2b2506c99134aa..049c34e6aa84a5 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -132,6 +132,30 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() params.SetDSTOffsets(mDSTOffsetList); } + if (!mSkipICDRegistration.ValueOr(false)) + { + params.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + + if (!mICDSymmetricKey.HasValue()) + { + chip::Crypto::DRBG_get_bytes(mRandomGeneratedICDSymmetricKey, sizeof(mRandomGeneratedICDSymmetricKey)); + mICDSymmetricKey.SetValue(ByteSpan(mRandomGeneratedICDSymmetricKey)); + } + if (!mICDCheckInNodeId.HasValue()) + { + mICDCheckInNodeId.SetValue(CurrentCommissioner().GetNodeId()); + } + if (!mICDMonitoredSubject.HasValue()) + { + mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value()); + } + // These Optionals must have values now. + // The commissioner will verify these values. + params.SetICDSymmetricKey(mICDSymmetricKey.Value()); + params.SetICDCheckInNodeId(mICDCheckInNodeId.Value()); + params.SetICDMonitoredSubject(mICDMonitoredSubject.Value()); + } + return params; } @@ -367,6 +391,28 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) SetCommandExitStatus(err); } +void PairingCommand::OnICDRegistrationInfoRequired() +{ + // Since we compute our ICD Registration info up front, we can call ICDRegistrationInfoReady() directly. + CurrentCommissioner().ICDRegistrationInfoReady(); +} + +void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) +{ + char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; + + chip::Encoding::BytesToHex(mICDSymmetricKey.Value().data(), mICDSymmetricKey.Value().size(), icdSymmetricKeyHex, + sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); + + // TODO: Persist symmetric key. + + ChipLogProgress(chipTool, + "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 + " / Monitored Subject: " ChipLogFormatX64 " / Symmetric Key: %s", + ChipLogValueX64(nodeId), ChipLogValueX64(mICDCheckInNodeId.Value()), + ChipLogValueX64(mICDMonitoredSubject.Value()), icdSymmetricKeyHex); +} + void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & nodeData) { // Ignore nodes with closed commissioning window diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 19d4a50471ed95..089467d4042dde 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -65,6 +65,13 @@ class PairingCommand : public CHIPCommand, "Bypass the attestation verifier. If not provided or false, the attestation verifier is not bypassed." " If true, the commissioning will continue in case of attestation verification failure."); AddArgument("case-auth-tags", 1, UINT32_MAX, &mCASEAuthTags, "The CATs to be encoded in the NOC sent to the commissionee"); + AddArgument("skip-icd-registration", 0, 1, &mSkipICDRegistration, + "Skip registering for check-ins from ICDs during commissioning. Default: false"); + AddArgument("icd-check-in-nodeid", 0, UINT64_MAX, &mICDCheckInNodeId, + "The check-in node id for the ICD, default: node id of the commissioner."); + AddArgument("icd-monitored-subject", 0, UINT64_MAX, &mICDMonitoredSubject, + "The monitored subject of the ICD, default: The node id used for icd-check-in-nodeid."); + AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated."); switch (networkType) { @@ -188,6 +195,8 @@ class PairingCommand : public CHIPCommand, void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; + void OnICDRegistrationInfoRequired() override; + void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; /////////// DeviceDiscoveryDelegate Interface ///////// void OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & nodeData) override; @@ -222,12 +231,17 @@ class PairingCommand : public CHIPCommand, chip::Optional mBypassAttestationVerifier; chip::Optional> mCASEAuthTags; chip::Optional mCountryCode; + chip::Optional mSkipICDRegistration; + chip::Optional mICDCheckInNodeId; + chip::Optional mICDSymmetricKey; + chip::Optional mICDMonitoredSubject; chip::app::DataModel::List mTimeZoneList; TypedComplexArgument> mComplex_TimeZones; chip::app::DataModel::List mDSTOffsetList; TypedComplexArgument> mComplex_DSTOffsets; + uint16_t mRemotePort; uint16_t mDiscriminator; uint32_t mSetupPINCode; @@ -239,6 +253,8 @@ class PairingCommand : public CHIPCommand, uint64_t mDiscoveryFilterCode; char * mDiscoveryFilterInstanceName; + uint8_t mRandomGeneratedICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; + // For unpair chip::Platform::UniquePtr mCurrentFabricRemover; chip::Callback::Callback mCurrentFabricRemoveCallback; diff --git a/examples/darwin-framework-tool/templates/tests/ciTests.json b/examples/darwin-framework-tool/templates/tests/ciTests.json index 78fefe41895084..ccec8bf6b985ef 100644 --- a/examples/darwin-framework-tool/templates/tests/ciTests.json +++ b/examples/darwin-framework-tool/templates/tests/ciTests.json @@ -67,6 +67,8 @@ "Disabled because darwin-framework-tool does not handle substraction in parameters", "Test_TC_S_2_3", "TestScenesMultiFabric", - "TestScenesFabricSceneInfo" + "TestScenesFabricSceneInfo", + "#30759: Darwin chip-tool does not support ICD registration during commissioning", + "TestIcdManagementCluster" ] } diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index 110dd542a7f78b..6e52020cb9a9ee 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -175,6 +175,7 @@ def _GetChipReplUnsupportedTests() -> Set[str]: "Test_TC_ACE_1_6.yaml", # Test fails only in chip-repl: Refer--> https://github.com/project-chip/connectedhomeip/pull/27910#issuecomment-1632485584 "Test_TC_IDM_1_2.yaml", # chip-repl does not support AnyCommands (19/07/2023) "TestGroupKeyManagementCluster.yaml", # chip-repl does not support EqualityCommands (2023-08-04) + "TestIcdManagementCluster.yaml", # TODO(#30430): add ICD registration support in chip-repl "Test_TC_S_2_2.yaml", # chip-repl does not support EqualityCommands pseudo-cluster "Test_TC_MOD_3_1.yaml", # chip-repl does not support EqualityCommands pseudo-cluster "Test_TC_MOD_3_2.yaml", # chip-repl does not support EqualityCommands pseudo-cluster diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml index d23c06e96ed208..4f4cbf00a4dd27 100644 --- a/src/app/tests/suites/TestIcdManagementCluster.yaml +++ b/src/app/tests/suites/TestIcdManagementCluster.yaml @@ -20,6 +20,14 @@ config: endpoint: 0 tests: + - label: "Read the commissioner node ID" + cluster: "CommissionerCommands" + command: "GetCommissionerNodeId" + response: + values: + - name: "nodeId" + saveAs: commissionerNodeId + - label: "Wait for the commissioned device to be retrieved" cluster: "DelayCommands" command: "WaitForCommissionee" @@ -94,11 +102,25 @@ tests: response: error: NOT_FOUND - - label: "Read RegisteredClients" + # chip-tool will register itself with the ICD during the tests. + - label: "Read RegisteredClients For Registration During Commissioning" command: "readAttribute" attribute: "RegisteredClients" response: - value: [] + value: + [ + { + CheckInNodeID: commissionerNodeId, + MonitoredSubject: commissionerNodeId, + }, + ] + + - label: "Unregister Client Registered During Commissioning" + command: "UnregisterClient" + arguments: + values: + - name: "CheckInNodeID" + value: commissionerNodeId - label: "Register 1.0 (key too short)" command: "RegisterClient" diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 075c5eeb243b23..93247c3298b2da 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include #include @@ -65,6 +67,32 @@ static bool IsUnsafeSpan(const Optional & maybeUnsafeSpan, const Optio return maybeUnsafeSpan.Value().data() != knownSafeSpan.Value().data(); } +CHIP_ERROR AutoCommissioner::VerifyICDRegistrationInfo(const CommissioningParameters & params) +{ + ChipLogProgress(Controller, "Checking ICD registration parameters"); + if (!params.GetICDSymmetricKey().HasValue()) + { + ChipLogError(Controller, "Missing ICD symmetric key!"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (params.GetICDSymmetricKey().Value().size() != sizeof(mICDSymmetricKey)) + { + ChipLogError(Controller, "Invalid ICD symmetric key length!"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (!params.GetICDCheckInNodeId().HasValue()) + { + ChipLogError(Controller, "Missing ICD check-in node id!"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (!params.GetICDMonitoredSubject().HasValue()) + { + ChipLogError(Controller, "Missing ICD monitored subject!"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; +} + CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParameters & params) { // Make sure any members that point to buffers that we are not pointing to @@ -90,6 +118,7 @@ CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParam IsUnsafeSpan(params.GetPAI(), mParams.GetPAI()) || IsUnsafeSpan(params.GetDAC(), mParams.GetDAC()) || IsUnsafeSpan(params.GetTimeZone(), mParams.GetTimeZone()) || IsUnsafeSpan(params.GetDSTOffsets(), mParams.GetDSTOffsets()) || + IsUnsafeSpan(params.GetICDSymmetricKey(), mParams.GetICDSymmetricKey()) || (params.GetDefaultNTP().HasValue() && !params.GetDefaultNTP().Value().IsNull() && params.GetDefaultNTP().Value().Value().data() != mDefaultNtp)); @@ -229,6 +258,17 @@ CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParam } } + if (params.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore && params.GetICDSymmetricKey().HasValue()) + { + ReturnErrorOnFailure(VerifyICDRegistrationInfo(params)); + + // The values must be valid now. + memcpy(mICDSymmetricKey, params.GetICDSymmetricKey().Value().data(), params.GetICDSymmetricKey().Value().size()); + mParams.SetICDSymmetricKey(ByteSpan(mICDSymmetricKey)); + mParams.SetICDCheckInNodeId(params.GetICDCheckInNodeId().Value()); + mParams.SetICDMonitoredSubject(params.GetICDMonitoredSubject().Value()); + } + return CHIP_NO_ERROR; } @@ -367,6 +407,17 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio return GetNextCommissioningStageInternal(CommissioningStage::kConfigureTrustedTimeSource, lastErr); } case CommissioningStage::kConfigureTrustedTimeSource: + if (mNeedIcdRegistration) + { + return CommissioningStage::kICDGetRegistrationInfo; + } + return GetNextCommissioningStageInternal(CommissioningStage::kICDSendStayActive, lastErr); + case CommissioningStage::kICDGetRegistrationInfo: + return CommissioningStage::kICDRegistration; + case CommissioningStage::kICDRegistration: + // TODO(#24259): StayActiveRequest is not supported by server. We may want to SendStayActive after OpDiscovery. + return CommissioningStage::kICDSendStayActive; + case CommissioningStage::kICDSendStayActive: // TODO(cecille): device attestation casues operational cert provisioning to happen, This should be a separate stage. // For thread and wifi, this should go to network setup then enable. For on-network we can skip right to finding the // operational network because the provisioning of certificates will trigger the device to start operational advertising. @@ -709,10 +760,10 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore) { - if (commissioningInfo.isIcd) + if (commissioningInfo.isIcd && commissioningInfo.checkInProtocolSupport) { - mNeedIcdRegistraion = true; - ChipLogDetail(Controller, "AutoCommissioner: Device is ICD"); + mNeedIcdRegistration = true; + ChipLogDetail(Controller, "AutoCommissioner: ICD supports the check-in protocol."); } } break; @@ -776,6 +827,15 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio // storing the returned certs, so just return here without triggering the next stage. return NOCChainGenerated(report.Get().noc, report.Get().icac, report.Get().rcac, report.Get().ipk, report.Get().adminSubject); + case CommissioningStage::kICDGetRegistrationInfo: + // Noting to od. The ICD registation info is handled elsewhere. + break; + case CommissioningStage::kICDRegistration: + // Noting to od. DevicePairingDelegate will handle this. + break; + case CommissioningStage::kICDSendStayActive: + // Nothing to do. + break; case CommissioningStage::kFindOperational: mOperationalDeviceProxy = report.Get().operationalProxy; break; diff --git a/src/controller/AutoCommissioner.h b/src/controller/AutoCommissioner.h index f86ebead1d011a..e311b72d190b86 100644 --- a/src/controller/AutoCommissioner.h +++ b/src/controller/AutoCommissioner.h @@ -74,6 +74,8 @@ class AutoCommissioner : public CommissioningDelegate EndpointId GetEndpoint(const CommissioningStage & stage) const; CommissioningStage GetNextCommissioningStageInternal(CommissioningStage currentStage, CHIP_ERROR & lastErr); + CHIP_ERROR VerifyICDRegistrationInfo(const CommissioningParameters & params); + // Helper function to determine whether next stage should be kWiFiNetworkSetup, // kThreadNetworkSetup or kCleanup, depending whether network information has // been provided that matches the thread/wifi endpoint of the target. @@ -120,7 +122,7 @@ class AutoCommissioner : public CommissioningDelegate ReadCommissioningInfo mDeviceCommissioningInfo; bool mNeedsDST = false; - bool mNeedIcdRegistraion = false; + bool mNeedIcdRegistration = false; // TODO: Why were the nonces statically allocated, but the certs dynamically allocated? uint8_t * mDAC = nullptr; @@ -136,6 +138,8 @@ class AutoCommissioner : public CommissioningDelegate uint8_t mAttestationElements[Credentials::kMaxRspLen]; uint16_t mAttestationSignatureLen = 0; uint8_t mAttestationSignature[Crypto::kMax_ECDSA_Signature_Length]; + + uint8_t mICDSymmetricKey[Crypto::kAES_CCM128_Key_Length]; }; } // namespace Controller } // namespace chip diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 28d3cf38040674..1713564d589ff4 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1173,6 +1173,25 @@ void DeviceCommissioner::OnFailedToExtendedArmFailSafeDeviceAttestation(void * c commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL, report); } +void DeviceCommissioner::OnICDManagementRegisterClientResponse( + void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data) +{ + DeviceCommissioner * commissioner = static_cast(context); + + CommissioningDelegate::CommissioningReport report; + auto pairingDelegate = commissioner->GetPairingDelegate(); + auto deviceBeingCommissioned = commissioner->mDeviceBeingCommissioned; + if (pairingDelegate != nullptr && deviceBeingCommissioned != nullptr) + { + pairingDelegate->OnICDRegistrationComplete(deviceBeingCommissioned->GetDeviceId(), data.ICDCounter); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR, report); + } + else + { + commissioner->CommissioningStageComplete(CHIP_ERROR_INCORRECT_STATE, report); + } +} + bool DeviceCommissioner::ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout, Optional commandTimeout, OnExtendFailsafeSuccess onSuccess, OnExtendFailsafeFailure onFailure) @@ -2362,6 +2381,16 @@ CHIP_ERROR DeviceCommissioner::NetworkCredentialsReady() return CHIP_NO_ERROR; } +CHIP_ERROR DeviceCommissioner::ICDRegistrationInfoReady() +{ + ReturnErrorCodeIf(mCommissioningStage != CommissioningStage::kICDGetRegistrationInfo, CHIP_ERROR_INCORRECT_STATE); + + // need to advance to next step + CommissioningStageComplete(CHIP_NO_ERROR); + + return CHIP_NO_ERROR; +} + void DeviceCommissioner::OnNetworkConfigResponse(void * context, const NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data) { @@ -3007,6 +3036,41 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio } } break; + case CommissioningStage::kICDGetRegistrationInfo: { + GetPairingDelegate()->OnICDRegistrationInfoRequired(); + return; + } + break; + case CommissioningStage::kICDRegistration: { + IcdManagement::Commands::RegisterClient::Type request; + + if (!(params.GetICDCheckInNodeId().HasValue() && params.GetICDMonitoredSubject().HasValue() && + params.GetICDSymmetricKey().HasValue())) + { + ChipLogError(Controller, "No ICD Registration information provided!"); + CommissioningStageComplete(CHIP_ERROR_INCORRECT_STATE); + return; + } + + request.checkInNodeID = params.GetICDCheckInNodeId().Value(); + request.monitoredSubject = params.GetICDMonitoredSubject().Value(); + request.key = params.GetICDSymmetricKey().Value(); + + CHIP_ERROR err = SendCommand(proxy, request, OnICDManagementRegisterClientResponse, OnBasicFailure, endpoint, timeout); + if (err != CHIP_NO_ERROR) + { + // We won't get any async callbacks here, so just complete our stage. + ChipLogError(Controller, "Failed to send IcdManagement.RegisterClient command: %" CHIP_ERROR_FORMAT, err.Format()); + CommissioningStageComplete(err); + return; + } + } + break; + case CommissioningStage::kICDSendStayActive: { + // TODO(#24259): Send StayActiveRequest once server supports this. + CommissioningStageComplete(CHIP_NO_ERROR); + } + break; case CommissioningStage::kFindOperational: { // If there is an error, CommissioningStageComplete will be called from OnDeviceConnectionFailureFn. auto scopedPeerId = GetPeerScopedId(proxy->GetDeviceId()); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 2919096977f1ac..e013b6a9da1590 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -610,6 +610,22 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, */ CHIP_ERROR NetworkCredentialsReady(); + /** + * @brief + * This function is called by the DevicePairingDelegate to indicate that ICD registration info (ICDSymmetricKey, + * ICDCheckInNodeId and ICDMonitoredSubject) have been set on the CommissioningParameters of the CommissioningDelegate + * using CommissioningDelegate.SetCommissioningParameters(). As a result, commissioning can advance to the next stage. + * + * The DevicePairingDelegate may call this method from the OnICDRegistrationInfoRequired callback, or it may call this + * method after obtaining required parameters for ICD registration using asyncronous methods (like RPC call etc). + * + * When the ICD Registration completes, OnICDRegistrationComplete will be called. + * + * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state + * (kICDGetRegistrationInfo). + */ + CHIP_ERROR ICDRegistrationInfoReady(); + /** * @brief * This function returns the current CommissioningStage for this commissioner. @@ -870,6 +886,9 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data); static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error); + static void OnICDManagementRegisterClientResponse( + void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data); + /** * @brief * This function processes the CSR sent by the device. diff --git a/src/controller/CommissioningDelegate.cpp b/src/controller/CommissioningDelegate.cpp index e19727be9e510b..74f6d3c95ef06d 100644 --- a/src/controller/CommissioningDelegate.cpp +++ b/src/controller/CommissioningDelegate.cpp @@ -109,6 +109,18 @@ const char * StageToString(CommissioningStage stage) return "ConfigureTrustedTimeSource"; break; + case kICDGetRegistrationInfo: + return "ICDGetRegistrationInfo"; + break; + + case kICDRegistration: + return "ICDRegistration"; + break; + + case kICDSendStayActive: + return "ICDSendStayActive"; + break; + case kWiFiNetworkSetup: return "WiFiNetworkSetup"; break; diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 2919a026701bd0..9a7b4ebe0970ea 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -52,6 +52,9 @@ enum CommissioningStage : uint8_t kSendTrustedRootCert, ///< Send AddTrustedRootCertificate (0x3E:11) command to the device kSendNOC, ///< Send AddNOC (0x3E:6) command to the device kConfigureTrustedTimeSource, ///< Configure a trusted time source if one is required and available (must be done after SendNOC) + kICDGetRegistrationInfo, ///< Waiting for the higher layer to provide ICD registraion informations. + kICDRegistration, ///< Register for ICD management + kICDSendStayActive, ///< Send Keep Alive to ICD kWiFiNetworkSetup, ///< Send AddOrUpdateWiFiNetwork (0x31:2) command to the device kThreadNetworkSetup, ///< Send AddOrUpdateThreadNetwork (0x31:3) command to the device kFailsafeBeforeWiFiEnable, ///< Extend the fail-safe before doing kWiFiNetworkEnable @@ -517,6 +520,27 @@ class CommissioningParameters return *this; } + Optional GetICDCheckInNodeId() const { return mICDCheckInNodeId; } + CommissioningParameters & SetICDCheckInNodeId(NodeId icdCheckInNodeId) + { + mICDCheckInNodeId = MakeOptional(icdCheckInNodeId); + return *this; + } + + Optional GetICDMonitoredSubject() const { return mICDMonitoredSubject; } + CommissioningParameters & SetICDMonitoredSubject(uint64_t icdMonitoredSubject) + { + mICDMonitoredSubject = MakeOptional(icdMonitoredSubject); + return *this; + } + + Optional GetICDSymmetricKey() const { return mICDSymmetricKey; } + CommissioningParameters & SetICDSymmetricKey(ByteSpan icdSymmetricKey) + { + mICDSymmetricKey = MakeOptional(icdSymmetricKey); + return *this; + } + // Clear all members that depend on some sort of external buffer. Can be // used to make sure that we are not holding any dangling pointers. void ClearExternalBufferDependentValues() @@ -538,6 +562,7 @@ class CommissioningParameters mTimeZone.ClearValue(); mDSTOffsets.ClearValue(); mDefaultNTP.ClearValue(); + mICDSymmetricKey.ClearValue(); } private: @@ -578,6 +603,11 @@ class CommissioningParameters Optional mAttemptWiFiNetworkScan; Optional mAttemptThreadNetworkScan; // This automatically gets set to false when a ThreadOperationalDataset is set Optional mSkipCommissioningComplete; + + Optional mICDCheckInNodeId; + Optional mICDMonitoredSubject; + Optional mICDSymmetricKey; + ICDRegistrationStrategy mICDRegistrationStrategy = ICDRegistrationStrategy::kIgnore; bool mCheckForMatchingFabric = false; }; diff --git a/src/controller/DevicePairingDelegate.h b/src/controller/DevicePairingDelegate.h index 80d6296d52109c..31a906485fd904 100644 --- a/src/controller/DevicePairingDelegate.h +++ b/src/controller/DevicePairingDelegate.h @@ -114,6 +114,29 @@ class DLL_EXPORT DevicePairingDelegate * in order to resume the commissioning process. */ virtual void OnScanNetworksFailure(CHIP_ERROR error) {} + + /** + * @brief + * Called when the ICD registration information (ICD symmetric key, check-in node ID and monitored subject) is required. + * + * The DeviceCommissioner will be waiting in the kICDGetRegistrationInfo step and not advancing the commissioning process. + * + * The implementation should set the ICD registration info on the CommissioningParameters of the CommissioningDelegate + * using CommissioningDelegate.SetCommissioningParameters(), and then call DeviceCommissioner.ICDRegistrationInfoReady() + * in order to resume the commissioning process. + * + * The implementation may set the credentials before start commissioning, and call ICDRegistrationInfoReady() directly. + */ + virtual void OnICDRegistrationInfoRequired() {} + + /** + * @bried + * Called when the registration flow for the ICD completes. + * + * @param[in] icdNodeId The node id of the ICD. + * @param[in] icdCounter The ICD Counter received from the device. + */ + virtual void OnICDRegistrationComplete(NodeId icdNodeId, uint32_t icdCounter) {} }; } // namespace Controller 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 1ef76098ee8244..ca169c4b2c1e33 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -109,7 +109,6 @@ class TestList : public Command { printf("Test_TC_DGGEN_1_1\n"); printf("Test_TC_GRPKEY_1_1\n"); printf("Test_TC_GRPKEY_2_2\n"); - printf("TestIcdManagementCluster\n"); printf("Test_TC_ICDM_1_1\n"); printf("Test_TC_I_1_1\n"); printf("Test_TC_I_2_1\n"); @@ -55518,1025 +55517,6 @@ class Test_TC_GRPKEY_2_2 : public TestCommandBridge { } }; -class TestIcdManagementCluster : public TestCommandBridge { -public: - // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced - TestIcdManagementCluster() - : TestCommandBridge("TestIcdManagementCluster") - , mTestIndex(0) - { - AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); - AddArgument("cluster", &mCluster); - AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); - AddArgument("timeout", 0, UINT16_MAX, &mTimeout); - } - // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) - - ~TestIcdManagementCluster() - { - } - - /////////// TestCommand Interface ///////// - void NextTest() override - { - CHIP_ERROR err = CHIP_NO_ERROR; - - if (0 == mTestIndex) { - ChipLogProgress(chipTool, " **** Test Start: TestIcdManagementCluster\n"); - } - - if (mTestCount == mTestIndex) { - ChipLogProgress(chipTool, " **** Test Complete: TestIcdManagementCluster\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\n"); - err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); - break; - case 1: - ChipLogProgress(chipTool, " ***** Test Step 1 : Read Feature Map\n"); - err = TestReadFeatureMap_1(); - break; - case 2: - ChipLogProgress(chipTool, " ***** Test Step 2 : Read IdleModeDuration\n"); - err = TestReadIdleModeDuration_2(); - break; - case 3: - ChipLogProgress(chipTool, " ***** Test Step 3 : Read ActiveModeDuration\n"); - err = TestReadActiveModeDuration_3(); - break; - case 4: - ChipLogProgress(chipTool, " ***** Test Step 4 : Read ActiveModeThreshold\n"); - err = TestReadActiveModeThreshold_4(); - break; - case 5: - ChipLogProgress(chipTool, " ***** Test Step 5 : Read ICDCounter\n"); - err = TestReadICDCounter_5(); - break; - case 6: - ChipLogProgress(chipTool, " ***** Test Step 6 : Read ClientsSupportedPerFabric\n"); - err = TestReadClientsSupportedPerFabric_6(); - break; - case 7: - ChipLogProgress(chipTool, " ***** Test Step 7 : Unregister 1.0\n"); - err = TestUnregister10_7(); - break; - case 8: - ChipLogProgress(chipTool, " ***** Test Step 8 : Unregister 2.0\n"); - err = TestUnregister20_8(); - break; - case 9: - ChipLogProgress(chipTool, " ***** Test Step 9 : Unregister 3.0\n"); - err = TestUnregister30_9(); - break; - case 10: - ChipLogProgress(chipTool, " ***** Test Step 10 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_10(); - break; - case 11: - ChipLogProgress(chipTool, " ***** Test Step 11 : Register 1.0 (key too short)\n"); - err = TestRegister10KeyTooShort_11(); - break; - case 12: - ChipLogProgress(chipTool, " ***** Test Step 12 : Register 1.0 (key too long)\n"); - err = TestRegister10KeyTooLong_12(); - break; - case 13: - ChipLogProgress(chipTool, " ***** Test Step 13 : Register 1.1\n"); - err = TestRegister11_13(); - break; - case 14: - ChipLogProgress(chipTool, " ***** Test Step 14 : Register 2.1\n"); - err = TestRegister21_14(); - break; - case 15: - ChipLogProgress(chipTool, " ***** Test Step 15 : Register 3.1\n"); - err = TestRegister31_15(); - break; - case 16: - ChipLogProgress(chipTool, " ***** Test Step 16 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_16(); - break; - case 17: - ChipLogProgress(chipTool, " ***** Test Step 17 : Register 1.1 (update)\n"); - err = TestRegister11Update_17(); - break; - case 18: - ChipLogProgress(chipTool, " ***** Test Step 18 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_18(); - break; - case 19: - ChipLogProgress(chipTool, " ***** Test Step 19 : Register 2.2 (wrong verification key)\n"); - err = TestRegister22WrongVerificationKey_19(); - break; - case 20: - ChipLogProgress(chipTool, " ***** Test Step 20 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_20(); - break; - case 21: - ChipLogProgress(chipTool, " ***** Test Step 21 : Unregister 1.1 (wrong key)\n"); - err = TestUnregister11WrongKey_21(); - break; - case 22: - ChipLogProgress(chipTool, " ***** Test Step 22 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_22(); - break; - case 23: - ChipLogProgress(chipTool, " ***** Test Step 23 : Unregister 2.1\n"); - err = TestUnregister21_23(); - break; - case 24: - ChipLogProgress(chipTool, " ***** Test Step 24 : Read RegisteredClients\n"); - err = TestReadRegisteredClients_24(); - break; - case 25: - ChipLogProgress(chipTool, " ***** Test Step 25 : Unregister 1.3\n"); - err = TestUnregister13_25(); - break; - case 26: - ChipLogProgress(chipTool, " ***** Test Step 26 : Unregister 2.2\n"); - err = TestUnregister22_26(); - 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), EMBER_ZCL_STATUS_NOT_FOUND)); - break; - case 8: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); - break; - case 9: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); - break; - case 10: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 11: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_CONSTRAINT_ERROR)); - break; - case 12: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_CONSTRAINT_ERROR)); - break; - case 13: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 14: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 15: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_RESOURCE_EXHAUSTED)); - break; - case 16: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 17: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 18: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 19: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 20: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 21: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 22: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 23: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 24: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); - break; - case 25: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); - break; - case 26: - VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); - 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 = 27; - - chip::Optional mNodeId; - chip::Optional mCluster; - chip::Optional mEndpoint; - chip::Optional mTimeout; - - CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() - { - - chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; - value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; - return WaitForCommissionee("alpha", value); - } - - CHIP_ERROR TestReadFeatureMap_1() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read Feature Map: Error: %@", err); - } else { - NSLog(@"Read Feature Map: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("FeatureMap", actualValue, 7UL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadIdleModeDuration_2() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeIdleModeDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read IdleModeDuration: Error: %@", err); - } else { - NSLog(@"Read IdleModeDuration: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("IdleModeDuration", actualValue, 3600UL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadActiveModeDuration_3() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeActiveModeDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read ActiveModeDuration: Error: %@", err); - } else { - NSLog(@"Read ActiveModeDuration: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("ActiveModeDuration", actualValue, 10000UL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadActiveModeThreshold_4() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeActiveModeThresholdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read ActiveModeThreshold: Error: %@", err); - } else { - NSLog(@"Read ActiveModeThreshold: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("ActiveModeThreshold", actualValue, 1000U)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadICDCounter_5() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeICDCounterWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read ICDCounter: Error: %@", err); - } else { - NSLog(@"Read ICDCounter: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("ICDCounter", "int32u", "int32u")); - VerifyOrReturn(CheckConstraintMinValue("ICDCounter", [value unsignedIntValue], 0UL)); - VerifyOrReturn(CheckConstraintMaxValue("ICDCounter", [value unsignedIntValue], 4294967295UL)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadClientsSupportedPerFabric_6() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - [cluster readAttributeClientsSupportedPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read ClientsSupportedPerFabric: Error: %@", err); - } else { - NSLog(@"Read ClientsSupportedPerFabric: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("ClientsSupportedPerFabric", actualValue, 2U)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister10_7() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 1.0: Error: %@", err); - } else { - NSLog(@"Unregister 1.0: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_NOT_FOUND)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister20_8() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:102ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 2.0: Error: %@", err); - } else { - NSLog(@"Unregister 2.0: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_NOT_FOUND)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister30_9() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:102ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 3.0: Error: %@", err); - } else { - NSLog(@"Unregister 3.0: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_NOT_FOUND)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_10() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(0))); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister10KeyTooShort_11() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:1001ULL]; - params.key = - [[NSData alloc] initWithBytes:"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036" length:15]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 1.0 (key too short): Error: %@", err); - } else { - NSLog(@"Register 1.0 (key too short): Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_CONSTRAINT_ERROR)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister10KeyTooLong_12() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:1001ULL]; - params.key = - [[NSData alloc] initWithBytes:"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\377" length:17]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 1.0 (key too long): Error: %@", err); - } else { - NSLog(@"Register 1.0 (key too long): Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_CONSTRAINT_ERROR)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister11_13() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:1001ULL]; - params.key = - [[NSData alloc] initWithBytes:"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" length:16]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 1.1: Error: %@", err); - } else { - NSLog(@"Register 1.1: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("ICDCounter", "int32u", "int32u")); - VerifyOrReturn(CheckConstraintMinValue("ICDCounter", [values.icdCounter unsignedIntValue], 0UL)); - VerifyOrReturn(CheckConstraintMaxValue("ICDCounter", [values.icdCounter unsignedIntValue], 4294967295UL)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister21_14() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:201ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:2001ULL]; - params.key = - [[NSData alloc] initWithBytes:" !\042#$%&'()*+,-./" length:16]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 2.1: Error: %@", err); - } else { - NSLog(@"Register 2.1: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("ICDCounter", "int32u", "int32u")); - VerifyOrReturn(CheckConstraintMinValue("ICDCounter", [values.icdCounter unsignedIntValue], 0UL)); - VerifyOrReturn(CheckConstraintMaxValue("ICDCounter", [values.icdCounter unsignedIntValue], 4294967295UL)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister31_15() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:301ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:3001ULL]; - params.key = - [[NSData alloc] initWithBytes:"0123456789:;<=>?" length:16]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 3.1: Error: %@", err); - } else { - NSLog(@"Register 3.1: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_RESOURCE_EXHAUSTED)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_16() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(2))); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).checkInNodeID, 101ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).monitoredSubject, 1001ULL)); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).checkInNodeID, 201ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).monitoredSubject, 2001ULL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister11Update_17() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:1002ULL]; - params.key = - [[NSData alloc] initWithBytes:"\001\021!1AQaq\201\221\241\261\301\321\341\361" length:16]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 1.1 (update): Error: %@", err); - } else { - NSLog(@"Register 1.1 (update): Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("ICDCounter", "int32u", "int32u")); - VerifyOrReturn(CheckConstraintMinValue("ICDCounter", [values.icdCounter unsignedIntValue], 0UL)); - VerifyOrReturn(CheckConstraintMaxValue("ICDCounter", [values.icdCounter unsignedIntValue], 4294967295UL)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_18() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(2))); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).checkInNodeID, 101ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).monitoredSubject, 1002ULL)); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).checkInNodeID, 201ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).monitoredSubject, 2001ULL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestRegister22WrongVerificationKey_19() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterRegisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:201ULL]; - params.monitoredSubject = - [NSNumber numberWithUnsignedLongLong:2002ULL]; - params.key = - [[NSData alloc] initWithBytes:"\002\022\0422BRbr\202\222\242\262\302\322\342/" length:16]; - params.verificationKey = - [[NSData alloc] initWithBytes:" !\042#$%&'()*+,-//" length:16]; - [cluster registerClientWithParams:params completion: - ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Register 2.2 (wrong verification key): Error: %@", err); - } else { - NSLog(@"Register 2.2 (wrong verification key): Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - VerifyOrReturn(CheckConstraintType("ICDCounter", "int32u", "int32u")); - VerifyOrReturn(CheckConstraintMinValue("ICDCounter", [values.icdCounter unsignedIntValue], 0UL)); - VerifyOrReturn(CheckConstraintMaxValue("ICDCounter", [values.icdCounter unsignedIntValue], 4294967295UL)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_20() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(2))); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).checkInNodeID, 101ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).monitoredSubject, 1002ULL)); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).checkInNodeID, 201ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[1]).monitoredSubject, 2002ULL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister11WrongKey_21() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - params.verificationKey = - [[NSData alloc] initWithBytes:"\001!!1AQaq\201\221\241\261\301\321\341\361" length:16]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 1.1 (wrong key): Error: %@", err); - } else { - NSLog(@"Unregister 1.1 (wrong key): Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_22() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(1))); - VerifyOrReturn(CheckValue("CheckInNodeID", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).checkInNodeID, 201ULL)); - VerifyOrReturn(CheckValue("MonitoredSubject", ((MTRICDManagementClusterMonitoringRegistrationStruct *) actualValue[0]).monitoredSubject, 2002ULL)); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister21_23() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:201ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 2.1: Error: %@", err); - } else { - NSLog(@"Unregister 2.1: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestReadRegisteredClients_24() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRReadParams alloc] init]; - params.filterByFabric = true; - [cluster readAttributeRegisteredClientsWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Read RegisteredClients: Error: %@", err); - } else { - NSLog(@"Read RegisteredClients: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - - { - id actualValue = value; - VerifyOrReturn(CheckValue("RegisteredClients", [actualValue count], static_cast(0))); - } - - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister13_25() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:101ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 1.3: Error: %@", err); - } else { - NSLog(@"Unregister 1.3: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_NOT_FOUND)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } - - CHIP_ERROR TestUnregister22_26() - { - - MTRBaseDevice * device = GetDevice("alpha"); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(0) queue:mCallbackQueue]; - VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); - - __auto_type * params = [[MTRICDManagementClusterUnregisterClientParams alloc] init]; - params.checkInNodeID = - [NSNumber numberWithUnsignedLongLong:102ULL]; - [cluster unregisterClientWithParams:params completion: - ^(NSError * _Nullable err) { - if (err != nil) { - NSLog(@"Unregister 2.2: Error: %@", err); - } else { - NSLog(@"Unregister 2.2: Success"); - } - - VerifyOrReturn(CheckValue("status", err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code : EMBER_ZCL_STATUS_FAILURE) : 0, EMBER_ZCL_STATUS_NOT_FOUND)); - NextTest(); - }]; - - return CHIP_NO_ERROR; - } -}; - class Test_TC_ICDM_1_1 : public TestCommandBridge { public: // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced @@ -194805,7 +193785,6 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), - make_unique(), make_unique(), make_unique(), make_unique(),