From 070023171aec56a6a2b832e3fd49944204b788a3 Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:12:59 -0400 Subject: [PATCH] [ICD] Add ClientType support to the ICDManager and ICD Management cluster (#33811) * update icdm xml * generated files * Add clientType to the ICDMonitoring table * Add client type buisness logic to ICDM cluster * Add client type logic to the ICDManager * finish clean up * make ClientType arg mandatory * regen --------- Co-authored-by: yunhanw --- .../commands/clusters/ClusterCommand.h | 7 +- .../chip-tool/commands/icd/ICDCommand.cpp | 24 ++++--- .../commands/pairing/PairingCommand.cpp | 7 +- .../commands/pairing/PairingCommand.h | 3 + .../nxp/zap-lit/contact-sensor-app.matter | 7 ++ .../nxp/zap-sit/contact-sensor-app.matter | 7 ++ .../commands/pairing/PairingCommand.cpp | 7 +- .../commands/pairing/PairingCommand.h | 3 + .../light-switch-app.matter | 7 ++ .../light-switch-app/qpg/zap/switch.matter | 7 ++ .../lit-icd-common/lit-icd-server-app.matter | 7 ++ examples/lock-app/lock-common/lock-app.matter | 7 ++ examples/lock-app/qpg/zap/lock.matter | 7 ++ .../smoke-co-alarm-app.matter | 7 ++ examples/window-app/common/window-app.matter | 7 ++ .../icd-management-server.cpp | 7 ++ .../icd-management-server.h | 2 - .../icd/client/DefaultICDClientStorage.cpp | 5 ++ src/app/icd/client/DefaultICDClientStorage.h | 9 +-- src/app/icd/client/ICDClientInfo.h | 13 ++-- src/app/icd/server/BUILD.gn | 1 + src/app/icd/server/ICDCheckInSender.h | 2 +- src/app/icd/server/ICDManager.cpp | 14 ++++ src/app/icd/server/ICDManager.h | 1 - src/app/icd/server/ICDMonitoringTable.cpp | 9 +++ src/app/icd/server/ICDMonitoringTable.h | 18 ++--- src/app/icd/server/tests/TestICDManager.cpp | 2 + .../server/tests/TestICDMonitoringTable.cpp | 10 +++ .../suites/TestIcdManagementCluster.yaml | 67 +++++++++++++++++-- .../certification/Test_TC_ICDM_3_4.yaml | 3 + .../chip/icd-management-cluster.xml | 14 +++- src/controller/AutoCommissioner.cpp | 6 ++ src/controller/CommissioningDelegate.h | 8 +++ .../data_model/controller-clusters.matter | 7 ++ .../java/AndroidDeviceControllerWrapper.cpp | 14 ++++ .../chip/devicecontroller/ChipClusters.java | 10 ++- .../chip/devicecontroller/ChipStructs.java | 15 +++++ .../devicecontroller/ClusterIDMapping.java | 2 +- .../devicecontroller/ClusterInfoMapping.java | 6 ++ ...mentClusterMonitoringRegistrationStruct.kt | 6 ++ .../cluster/clusters/IcdManagementCluster.kt | 4 ++ ...mentClusterMonitoringRegistrationStruct.kt | 6 ++ .../devicecontroller/ICDRegistrationInfo.java | 12 ++++ .../CHIPAttributeTLVValueDecoder.cpp | 17 +++-- ...Controller-ScriptDevicePairingDelegate.cpp | 1 + .../python/chip/clusters/CHIPClusters.py | 1 + .../python/chip/clusters/Objects.py | 13 ++++ .../MTRAttributeTLVValueDecoder.mm | 1 + .../CHIP/zap-generated/MTRBaseClusters.h | 5 ++ .../zap-generated/MTRCommandPayloadsObjc.h | 2 + .../zap-generated/MTRCommandPayloadsObjc.mm | 8 ++- .../CHIP/zap-generated/MTRStructsObjc.h | 1 + .../CHIP/zap-generated/MTRStructsObjc.mm | 5 +- src/lib/support/JniReferences.cpp | 13 ++++ src/lib/support/JniReferences.h | 5 ++ src/python_testing/TC_ICDM_3_1.py | 14 ++-- .../zap-generated/cluster-enums-check.h | 12 ++++ .../app-common/zap-generated/cluster-enums.h | 12 ++++ .../zap-generated/cluster-objects.cpp | 13 ++++ .../zap-generated/cluster-objects.h | 5 ++ .../zap-generated/cluster/Commands.h | 1 + .../cluster/ComplexArgumentParser.cpp | 7 ++ .../cluster/logging/DataModelLogger.cpp | 8 +++ .../zap-generated/cluster/Commands.h | 6 ++ 64 files changed, 478 insertions(+), 59 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ClusterCommand.h b/examples/chip-tool/commands/clusters/ClusterCommand.h index ac141fb012e259..bf5c61fd02bd3f 100644 --- a/examples/chip-tool/commands/clusters/ClusterCommand.h +++ b/examples/chip-tool/commands/clusters/ClusterCommand.h @@ -21,6 +21,7 @@ #include "DataModelLogger.h" #include "ModelCommand.h" #include +#include class ClusterCommand : public InteractionModelCommands, public ModelCommand, public chip::app::CommandSender::Callback { @@ -70,6 +71,7 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub ReturnErrorOnFailure(InteractionModelCommands::SendCommand(device, endpointId, clusterId, commandId, value)); mScopedNodeId = chip::ScopedNodeId(value.checkInNodeID, device->GetSecureSession().Value()->GetFabricIndex()); mMonitoredSubject = value.monitoredSubject; + mClientType = value.clientType; memcpy(mICDSymmetricKey, value.key.data(), value.key.size()); return CHIP_NO_ERROR; } @@ -148,6 +150,7 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub clientInfo.peer_node = mScopedNodeId; clientInfo.monitored_subject = mMonitoredSubject; clientInfo.start_icd_counter = value.ICDCounter; + clientInfo.client_type = mClientType; StoreICDEntryWithKey(clientInfo, chip::ByteSpan(mICDSymmetricKey)); } @@ -258,8 +261,10 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub chip::ClusterId mClusterId; chip::CommandId mCommandId; chip::ScopedNodeId mScopedNodeId; - uint64_t mMonitoredSubject = static_cast(0); + uint64_t mMonitoredSubject = static_cast(0); + chip::app::Clusters::IcdManagement::ClientTypeEnum mClientType = chip::app::Clusters::IcdManagement::ClientTypeEnum::kPermanent; uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; + CHIP_ERROR mError = CHIP_NO_ERROR; CustomArgument mPayload; }; diff --git a/examples/chip-tool/commands/icd/ICDCommand.cpp b/examples/chip-tool/commands/icd/ICDCommand.cpp index 505e6adfbfea3d..3f7bfb328d5273 100644 --- a/examples/chip-tool/commands/icd/ICDCommand.cpp +++ b/examples/chip-tool/commands/icd/ICDCommand.cpp @@ -21,6 +21,7 @@ #include #include #include +#include using namespace ::chip; using namespace ::chip::app; @@ -36,31 +37,32 @@ CHIP_ERROR ICDListCommand::RunCommand() return CHIP_ERROR_NO_MEMORY; } app::DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iter); - fprintf(stderr, " +-----------------------------------------------------------------------------+\n"); - fprintf(stderr, " | %-75s |\n", "Known ICDs:"); - fprintf(stderr, " +-----------------------------------------------------------------------------+\n"); - fprintf(stderr, " | %20s | %15s | %15s | %16s |\n", "Fabric Index:Node ID", "Start Counter", "Counter Offset", - "MonitoredSubject"); + fprintf(stderr, " +------------------------------------------------------------------------------------------+\n"); + fprintf(stderr, " | %-88s |\n", "Known ICDs:"); + fprintf(stderr, " +------------------------------------------------------------------------------------------+\n"); + fprintf(stderr, " | %20s | %15s | %15s | %16s | %10s |\n", "Fabric Index:Node ID", "Start Counter", "Counter Offset", + "MonitoredSubject", "ClientType"); while (iter->Next(info)) { - fprintf(stderr, " +-----------------------------------------------------------------------------+\n"); - fprintf(stderr, " | %3" PRIu32 ":" ChipLogFormatX64 " | %15" PRIu32 " | %15" PRIu32 " | " ChipLogFormatX64 " |\n", + fprintf(stderr, " +------------------------------------------------------------------------------------------+\n"); + fprintf(stderr, " | %3" PRIu32 ":" ChipLogFormatX64 " | %15" PRIu32 " | %15" PRIu32 " | " ChipLogFormatX64 " | %10u |\n", static_cast(info.peer_node.GetFabricIndex()), ChipLogValueX64(info.peer_node.GetNodeId()), - info.start_icd_counter, info.offset, ChipLogValueX64(info.monitored_subject)); + info.start_icd_counter, info.offset, ChipLogValueX64(info.monitored_subject), + static_cast(info.client_type)); static_assert(std::is_same::value, "The following BytesToHex can copy/encode the key bytes from sharedKey to hexadecimal format, which only " "works for RawKeySessionKeystore"); Encoding::BytesToHex(info.aes_key_handle.As(), Crypto::kAES_CCM128_Key_Length, icdAesKeyHex, sizeof(icdAesKeyHex), chip::Encoding::HexFlags::kNullTerminate); - fprintf(stderr, " | aes key: %60s |\n", icdAesKeyHex); + fprintf(stderr, " | aes key: %60s |\n", icdAesKeyHex); Encoding::BytesToHex(info.hmac_key_handle.As(), Crypto::kHMAC_CCM128_Key_Length, icdHmacKeyHex, sizeof(icdHmacKeyHex), chip::Encoding::HexFlags::kNullTerminate); - fprintf(stderr, " | hmac key: %60s |\n", icdHmacKeyHex); + fprintf(stderr, " | hmac key: %60s |\n", icdHmacKeyHex); } - fprintf(stderr, " +-----------------------------------------------------------------------------+\n"); + fprintf(stderr, " +------------------------------------------------------------------------------------------+\n"); SetCommandExitStatus(CHIP_NO_ERROR); return CHIP_NO_ERROR; } diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 7bddfa3d08039c..35ce2ba1cc7aaa 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -157,6 +157,10 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() { mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value()); } + if (!mICDClientType.HasValue()) + { + mICDClientType.SetValue(app::Clusters::IcdManagement::ClientTypeEnum::kPermanent); + } // These Optionals must have values now. // The commissioner will verify these values. params.SetICDSymmetricKey(mICDSymmetricKey.Value()); @@ -166,6 +170,7 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() } params.SetICDCheckInNodeId(mICDCheckInNodeId.Value()); params.SetICDMonitoredSubject(mICDMonitoredSubject.Value()); + params.SetICDClientType(mICDClientType.Value()); } return params; @@ -459,7 +464,7 @@ void PairingCommand::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icd sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); app::ICDClientInfo clientInfo; - clientInfo.peer_node = nodeId; + clientInfo.peer_node = chip::ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex()); clientInfo.monitored_subject = mICDMonitoredSubject.Value(); clientInfo.start_icd_counter = icdCounter; diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index facb0f2403536b..0cf4e1de2de713 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -74,6 +74,8 @@ class PairingCommand : public CHIPCommand, "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-client-type", 0, 1, &mICDClientType, + "The ClientType of the client registering, default: Permanent client - 0"); AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated."); AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec, "If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds"); @@ -245,6 +247,7 @@ class PairingCommand : public CHIPCommand, chip::Optional mICDCheckInNodeId; chip::Optional mICDSymmetricKey; chip::Optional mICDMonitoredSubject; + chip::Optional mICDClientType; chip::Optional mICDStayActiveDurationMsec; chip::app::DataModel::List mTimeZoneList; TypedComplexArgument> diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index d64a06cf2c7b6e..9bffee1c83dce2 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -1315,6 +1315,11 @@ cluster BooleanState = 69 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1349,6 +1354,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1373,6 +1379,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index d0861d55518c69..70cae9e994c4fd 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -1315,6 +1315,11 @@ cluster BooleanState = 69 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1349,6 +1354,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1373,6 +1379,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 8a261b01a8865b..521325a796dce0 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -157,6 +157,10 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() { mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value()); } + if (!mICDClientType.HasValue()) + { + mICDClientType.SetValue(app::Clusters::IcdManagement::ClientTypeEnum::kPermanent); + } // These Optionals must have values now. // The commissioner will verify these values. params.SetICDSymmetricKey(mICDSymmetricKey.Value()); @@ -166,6 +170,7 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() } params.SetICDCheckInNodeId(mICDCheckInNodeId.Value()); params.SetICDMonitoredSubject(mICDMonitoredSubject.Value()); + params.SetICDClientType(mICDClientType.Value()); } return params; @@ -459,7 +464,7 @@ void PairingCommand::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icd sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); app::ICDClientInfo clientInfo; - clientInfo.peer_node = nodeId; + clientInfo.peer_node = chip::ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex()); clientInfo.monitored_subject = mICDMonitoredSubject.Value(); clientInfo.start_icd_counter = icdCounter; diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.h b/examples/fabric-admin/commands/pairing/PairingCommand.h index fbd33440f5bb14..647f2c37fc78b2 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.h +++ b/examples/fabric-admin/commands/pairing/PairingCommand.h @@ -84,6 +84,8 @@ class PairingCommand : public CHIPCommand, "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-client-type", 0, 1, &mICDClientType, + "The ClientType of the client registering, default: Permanent client - 0"); AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated."); AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec, "If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds"); @@ -258,6 +260,7 @@ class PairingCommand : public CHIPCommand, chip::Optional mCountryCode; chip::Optional mICDRegistration; chip::Optional mICDCheckInNodeId; + chip::Optional mICDClientType; chip::Optional mICDSymmetricKey; chip::Optional mICDMonitoredSubject; chip::Optional mICDStayActiveDurationMsec; diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index c4f73e4b338685..1380e672e747b2 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -1939,6 +1939,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1973,6 +1978,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1997,6 +2003,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index d105fdea187f0a..f42b1f07744809 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -1736,6 +1736,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1770,6 +1775,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1794,6 +1800,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index 9d260248736c0c..79f26232c3a727 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -1413,6 +1413,11 @@ cluster BooleanState = 69 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1447,6 +1452,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1471,6 +1477,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 5c21291397494c..a484b095516dc6 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -1756,6 +1756,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1790,6 +1795,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1814,6 +1820,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index 589eb097561c77..a8628316139252 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -1412,6 +1412,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1446,6 +1451,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1470,6 +1476,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index ea86a446d156eb..9ed425b817255d 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -1732,6 +1732,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1766,6 +1771,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1790,6 +1796,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index 1a5a56ca4e3aba..f39cb7187446bc 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -1830,6 +1830,11 @@ cluster UserLabel = 65 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -1864,6 +1869,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -1888,6 +1894,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index f6ab59d9f2efb0..e4ead150a1fd79 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -202,6 +202,7 @@ CHIP_ERROR IcdManagementAttributeAccess::ReadRegisteredClients(EndpointId endpoi Structs::MonitoringRegistrationStruct::Type s{ .checkInNodeID = e.checkInNodeID, .monitoredSubject = e.monitoredSubject, + .clientType = e.clientType, .fabricIndex = e.fabricIndex }; ReturnErrorOnFailure(subEncoder.Encode(s)); } @@ -252,10 +253,14 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); NodeId nodeId = commandData.checkInNodeID; uint64_t monitoredSubject = commandData.monitoredSubject; + ClientTypeEnum clientType = commandData.clientType; ByteSpan key = commandData.key; Optional verificationKey = commandData.verificationKey; bool isClientAdmin = false; + // Check if ClientType is valid + VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, InteractionModel::Status::ConstraintError); + // Check if client is admin VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); @@ -291,6 +296,8 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co // Save entry.checkInNodeID = nodeId; entry.monitoredSubject = monitoredSubject; + entry.clientType = clientType; + if (entry.keyHandleValid) { entry.DeleteKey(); diff --git a/src/app/clusters/icd-management-server/icd-management-server.h b/src/app/clusters/icd-management-server/icd-management-server.h index 5c6b838fa9b527..38fc1b7ee6d7d0 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.h +++ b/src/app/clusters/icd-management-server/icd-management-server.h @@ -34,8 +34,6 @@ #include #endif // CHIP_CONFIG_ENABLE_ICD_CIP -using chip::Protocols::InteractionModel::Status; - namespace chip { namespace Crypto { using SymmetricKeystore = SessionKeystore; diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index 73e7b5f5c1fdf9..7582e8fd580c40 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -274,6 +274,10 @@ CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector(), hmacBuf.data(), sizeof(Crypto::Symmetric128BitsKeyByteArray)); + // ClientType + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kClientType))); + ReturnErrorOnFailure(reader.Get(clientInfo.client_type)); + ReturnErrorOnFailure(reader.ExitContainer(ICDClientInfoType)); clientInfoVector.push_back(clientInfo); } @@ -327,6 +331,7 @@ CHIP_ERROR DefaultICDClientStorage::SerializeToTlv(TLV::TLVWriter & writer, cons ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kAesKeyHandle), aesBuf)); ByteSpan hmacBuf(clientInfo.hmac_key_handle.As()); ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle), hmacBuf)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kClientType), clientInfo.client_type)); ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType)); } return writer.EndContainer(arrayType); diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h index c2a95fd2a1064b..c3c4560e1d04ce 100644 --- a/src/app/icd/client/DefaultICDClientStorage.h +++ b/src/app/icd/client/DefaultICDClientStorage.h @@ -130,6 +130,7 @@ class DefaultICDClientStorage : public ICDClientStorage kMonitoredSubject = 5, kAesKeyHandle = 6, kHmacKeyHandle = 7, + kClientType = 8, }; enum class CounterTag : uint8_t @@ -156,10 +157,10 @@ class DefaultICDClientStorage : public ICDClientStorage static constexpr size_t MaxICDClientInfoSize() { // All the fields added together - return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t) /*start_icd_counter*/, - sizeof(uint32_t) /*offset*/, sizeof(uint64_t) /*monitored_subject*/, - sizeof(Crypto::Symmetric128BitsKeyByteArray) /*aes_key_handle*/, - sizeof(Crypto::Symmetric128BitsKeyByteArray) /*hmac_key_handle*/); + return TLV::EstimateStructOverhead( + sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t) /*start_icd_counter*/, sizeof(uint32_t) /*offset*/, + sizeof(uint64_t) /*monitored_subject*/, sizeof(Crypto::Symmetric128BitsKeyByteArray) /*aes_key_handle*/, + sizeof(Crypto::Symmetric128BitsKeyByteArray) /*hmac_key_handle*/, sizeof(uint8_t) /*client_type*/); } static constexpr size_t MaxICDCounterSize() diff --git a/src/app/icd/client/ICDClientInfo.h b/src/app/icd/client/ICDClientInfo.h index 5a20b1990744bd..45aabf2f977866 100644 --- a/src/app/icd/client/ICDClientInfo.h +++ b/src/app/icd/client/ICDClientInfo.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -30,11 +31,12 @@ namespace app { struct ICDClientInfo { ScopedNodeId peer_node; - uint32_t start_icd_counter = 0; - uint32_t offset = 0; - uint64_t monitored_subject = static_cast(0); - Crypto::Aes128KeyHandle aes_key_handle = Crypto::Aes128KeyHandle(); - Crypto::Hmac128KeyHandle hmac_key_handle = Crypto::Hmac128KeyHandle(); + uint32_t start_icd_counter = 0; + uint32_t offset = 0; + Clusters::IcdManagement::ClientTypeEnum client_type = Clusters::IcdManagement::ClientTypeEnum::kPermanent; + uint64_t monitored_subject = static_cast(0); + Crypto::Aes128KeyHandle aes_key_handle = Crypto::Aes128KeyHandle(); + Crypto::Hmac128KeyHandle hmac_key_handle = Crypto::Hmac128KeyHandle(); ICDClientInfo() {} ICDClientInfo(const ICDClientInfo & other) { *this = other; } @@ -44,6 +46,7 @@ struct ICDClientInfo peer_node = other.peer_node; start_icd_counter = other.start_icd_counter; offset = other.offset; + client_type = other.client_type; monitored_subject = other.monitored_subject; ByteSpan aes_buf(other.aes_key_handle.As()); memcpy(aes_key_handle.AsMutable(), aes_buf.data(), diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn index c100cc7d041e84..89c39c203a7c16 100644 --- a/src/app/icd/server/BUILD.gn +++ b/src/app/icd/server/BUILD.gn @@ -83,6 +83,7 @@ source_set("manager") { "${chip_root}/src/app:subscription-info-provider", "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/credentials:credentials", + "${chip_root}/src/lib/address_resolve:address_resolve", "${chip_root}/src/messaging", ] diff --git a/src/app/icd/server/ICDCheckInSender.h b/src/app/icd/server/ICDCheckInSender.h index b681bec149f667..ea562666acfc4d 100644 --- a/src/app/icd/server/ICDCheckInSender.h +++ b/src/app/icd/server/ICDCheckInSender.h @@ -32,7 +32,7 @@ class ICDCheckInSender : public AddressResolve::NodeListener { public: ICDCheckInSender(Messaging::ExchangeManager * exchangeManager); - ~ICDCheckInSender(){}; + ~ICDCheckInSender() = default; CHIP_ERROR RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable, uint32_t counter); diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp index 2b4ccb2be8af4e..ee55b0b0f9b23b 100644 --- a/src/app/icd/server/ICDManager.cpp +++ b/src/app/icd/server/ICDManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,13 @@ void ICDManager::SendCheckInMsgs() continue; } + if (entry.clientType == ClientTypeEnum::kEphemeral) + { + // If the registered client is ephemeral, do not send a Check-In message + // continue to next entry + continue; + } + if (!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject)) { continue; @@ -248,6 +256,12 @@ bool ICDManager::CheckInMessagesWouldBeSent(const std::function -#include #include #include #include diff --git a/src/app/icd/server/ICDMonitoringTable.cpp b/src/app/icd/server/ICDMonitoringTable.cpp index 57e6fa265821f1..8148a7fe33b237 100644 --- a/src/app/icd/server/ICDMonitoringTable.cpp +++ b/src/app/icd/server/ICDMonitoringTable.cpp @@ -27,6 +27,7 @@ enum class Fields : uint8_t kMonitoredSubject = 2, kAesKeyHandle = 3, kHmacKeyHandle = 4, + kClientType = 5, }; CHIP_ERROR ICDMonitoringEntry::UpdateKey(StorageKeyName & skey) @@ -49,6 +50,8 @@ CHIP_ERROR ICDMonitoringEntry::Serialize(TLV::TLVWriter & writer) const ByteSpan hmacKeybuf(hmacKeyHandle.As()); ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kHmacKeyHandle), hmacKeybuf)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kClientType), clientType)); + ReturnErrorOnFailure(writer.EndContainer(outer)); return CHIP_NO_ERROR; } @@ -106,6 +109,9 @@ CHIP_ERROR ICDMonitoringEntry::Deserialize(TLV::TLVReader & reader) sizeof(Crypto::Symmetric128BitsKeyByteArray)); } break; + case to_underlying(Fields::kClientType): + ReturnErrorOnFailure(reader.Get(clientType)); + break; default: break; } @@ -122,6 +128,7 @@ void ICDMonitoringEntry::Clear() this->checkInNodeID = kUndefinedNodeId; this->monitoredSubject = kUndefinedNodeId; this->keyHandleValid = false; + this->clientType = app::Clusters::IcdManagement::ClientTypeEnum::kPermanent; } CHIP_ERROR ICDMonitoringEntry::SetKey(ByteSpan keyData) @@ -210,6 +217,7 @@ ICDMonitoringEntry & ICDMonitoringEntry::operator=(const ICDMonitoringEntry & ic fabricIndex = icdMonitoringEntry.fabricIndex; checkInNodeID = icdMonitoringEntry.checkInNodeID; monitoredSubject = icdMonitoringEntry.monitoredSubject; + clientType = icdMonitoringEntry.clientType; index = icdMonitoringEntry.index; keyHandleValid = icdMonitoringEntry.keyHandleValid; symmetricKeystore = icdMonitoringEntry.symmetricKeystore; @@ -257,6 +265,7 @@ CHIP_ERROR ICDMonitoringTable::Set(uint16_t index, const ICDMonitoringEntry & en ICDMonitoringEntry e(this->mFabric, index); e.checkInNodeID = entry.checkInNodeID; e.monitoredSubject = entry.monitoredSubject; + e.clientType = entry.clientType; e.index = index; memcpy(e.aesKeyHandle.AsMutable(), diff --git a/src/app/icd/server/ICDMonitoringTable.h b/src/app/icd/server/ICDMonitoringTable.h index e996d0c757cc23..942c56fda45e71 100644 --- a/src/app/icd/server/ICDMonitoringTable.h +++ b/src/app/icd/server/ICDMonitoringTable.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -101,14 +102,15 @@ struct ICDMonitoringEntry : public PersistentData */ bool IsKeyEquivalent(ByteSpan keyData); - chip::FabricIndex fabricIndex = kUndefinedFabricIndex; - chip::NodeId checkInNodeID = kUndefinedNodeId; - uint64_t monitoredSubject = static_cast(0); - Crypto::Aes128KeyHandle aesKeyHandle = Crypto::Aes128KeyHandle(); - Crypto::Hmac128KeyHandle hmacKeyHandle = Crypto::Hmac128KeyHandle(); - bool keyHandleValid = false; - uint16_t index = 0; - Crypto::SymmetricKeystore * symmetricKeystore = nullptr; + chip::FabricIndex fabricIndex = kUndefinedFabricIndex; + chip::NodeId checkInNodeID = kUndefinedNodeId; + uint64_t monitoredSubject = static_cast(0); + app::Clusters::IcdManagement::ClientTypeEnum clientType = app::Clusters::IcdManagement::ClientTypeEnum::kPermanent; + Crypto::Aes128KeyHandle aesKeyHandle = Crypto::Aes128KeyHandle(); + Crypto::Hmac128KeyHandle hmacKeyHandle = Crypto::Hmac128KeyHandle(); + bool keyHandleValid = false; + uint16_t index = 0; + Crypto::SymmetricKeystore * symmetricKeystore = nullptr; }; /** diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp index 45e781685e6d31..0b3c1a459441dd 100644 --- a/src/app/icd/server/tests/TestICDManager.cpp +++ b/src/app/icd/server/tests/TestICDManager.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ using namespace chip; using namespace chip::Test; using namespace chip::app; +using namespace chip::AddressResolve; using namespace chip::System; using namespace chip::System::Clock; using namespace chip::System::Clock::Literals; diff --git a/src/app/icd/server/tests/TestICDMonitoringTable.cpp b/src/app/icd/server/tests/TestICDMonitoringTable.cpp index ef1e5b32468b7a..423bc1506b36fb 100644 --- a/src/app/icd/server/tests/TestICDMonitoringTable.cpp +++ b/src/app/icd/server/tests/TestICDMonitoringTable.cpp @@ -20,10 +20,12 @@ #include #include #include +#include #include #include using namespace chip; +using namespace chip::app::Clusters::IcdManagement; using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; @@ -73,6 +75,7 @@ TEST(TestICDMonitoringTable, TestEntryAssignationOverload) entry.checkInNodeID = 34; entry.monitoredSubject = 32; + entry.clientType = ClientTypeEnum::kEphemeral; // Entry should be valid now EXPECT_TRUE(entry.IsValid()); @@ -88,6 +91,7 @@ TEST(TestICDMonitoringTable, TestEntryAssignationOverload) EXPECT_EQ(entry.fabricIndex, entry2.fabricIndex); EXPECT_EQ(entry.checkInNodeID, entry2.checkInNodeID); EXPECT_EQ(entry.monitoredSubject, entry2.monitoredSubject); + EXPECT_EQ(entry.clientType, entry2.clientType); EXPECT_TRUE(entry2.IsKeyEquivalent(ByteSpan(kKeyBuffer1a))); } @@ -130,6 +134,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) ICDMonitoringEntry entry1(&keystore); entry1.checkInNodeID = kClientNodeId11; entry1.monitoredSubject = kClientNodeId12; + entry1.clientType = ClientTypeEnum::kPermanent; EXPECT_EQ(CHIP_NO_ERROR, entry1.SetKey(ByteSpan(kKeyBuffer1a))); EXPECT_EQ(CHIP_NO_ERROR, saving.Set(0, entry1)); @@ -137,6 +142,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) ICDMonitoringEntry entry2(&keystore); entry2.checkInNodeID = kClientNodeId12; entry2.monitoredSubject = kClientNodeId11; + entry2.clientType = ClientTypeEnum::kEphemeral; EXPECT_EQ(CHIP_NO_ERROR, entry2.SetKey(ByteSpan(kKeyBuffer2a))); EXPECT_EQ(CHIP_NO_ERROR, saving.Set(1, entry2)); @@ -152,6 +158,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex); EXPECT_EQ(kClientNodeId11, entry.checkInNodeID); EXPECT_EQ(kClientNodeId12, entry.monitoredSubject); + EXPECT_EQ(ClientTypeEnum::kPermanent, entry.clientType); EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1a))); EXPECT_EQ(memcmp(entry1.hmacKeyHandle.As(), entry.hmacKeyHandle.As(), sizeof(Crypto::Symmetric128BitsKeyByteArray)), @@ -162,6 +169,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex); EXPECT_EQ(kClientNodeId12, entry.checkInNodeID); EXPECT_EQ(kClientNodeId11, entry.monitoredSubject); + EXPECT_EQ(ClientTypeEnum::kEphemeral, entry.clientType); EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer2a))); EXPECT_EQ(memcmp(entry2.hmacKeyHandle.As(), entry.hmacKeyHandle.As(), sizeof(Crypto::Symmetric128BitsKeyByteArray)), @@ -185,6 +193,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex); EXPECT_EQ(kClientNodeId12, entry.checkInNodeID); EXPECT_EQ(kClientNodeId11, entry.monitoredSubject); + EXPECT_EQ(ClientTypeEnum::kEphemeral, entry.clientType); EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer2a))); EXPECT_EQ(memcmp(entry2.hmacKeyHandle.As(), entry.hmacKeyHandle.As(), sizeof(Crypto::Symmetric128BitsKeyByteArray)), @@ -195,6 +204,7 @@ TEST(TestICDMonitoringTable, TestSaveAndLoadRegistrationValue) EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex); EXPECT_EQ(kClientNodeId13, entry.checkInNodeID); EXPECT_EQ(kClientNodeId11, entry.monitoredSubject); + EXPECT_EQ(ClientTypeEnum::kPermanent, entry.clientType); EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1b))); EXPECT_EQ(memcmp(entry4.hmacKeyHandle.As(), entry.hmacKeyHandle.As(), sizeof(Crypto::Symmetric128BitsKeyByteArray)), diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml index a3196835915b52..68e358385b8e21 100644 --- a/src/app/tests/suites/TestIcdManagementCluster.yaml +++ b/src/app/tests/suites/TestIcdManagementCluster.yaml @@ -195,6 +195,8 @@ tests: value: 1001 - name: "Key" value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" + - name: "ClientType" + value: ClientTypeEnum.Permanent response: error: CONSTRAINT_ERROR @@ -208,10 +210,12 @@ tests: value: 1001 - name: "Key" value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\xff" + - name: "ClientType" + value: ClientTypeEnum.Permanent response: error: CONSTRAINT_ERROR - - label: "Register 1.1" + - label: "Register 1.1 - Invalid ClientType" command: "RegisterClient" arguments: values: @@ -221,6 +225,23 @@ tests: value: 1001 - name: "Key" value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + - name: "ClientType" + value: ClientTypeEnum.UnknownEnumValue + response: + error: CONSTRAINT_ERROR + + - label: "Register 1.2" + command: "RegisterClient" + arguments: + values: + - name: "CheckInNodeID" + value: 101 + - name: "MonitoredSubject" + value: 1001 + - name: "Key" + value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + - name: "ClientType" + value: ClientTypeEnum.Permanent response: values: - name: "ICDCounter" @@ -240,6 +261,8 @@ tests: - name: "Key" value: "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" + - name: "ClientType" + value: ClientTypeEnum.Ephemeral response: values: - name: "ICDCounter" @@ -258,6 +281,8 @@ tests: value: 3001 - name: "Key" value: "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" + - name: "ClientType" + value: ClientTypeEnum.Permanent response: error: RESOURCE_EXHAUSTED @@ -267,8 +292,16 @@ tests: response: value: [ - { CheckInNodeID: 101, MonitoredSubject: 1001 }, - { CheckInNodeID: 201, MonitoredSubject: 2001 }, + { + CheckInNodeID: 101, + MonitoredSubject: 1001, + ClientType: ClientTypeEnum.Permanent, + }, + { + CheckInNodeID: 201, + MonitoredSubject: 2001, + ClientType: ClientTypeEnum.Ephemeral, + }, ] - label: "Register 1.1 (update)" @@ -281,6 +314,8 @@ tests: value: 1002 - name: "Key" value: "\x01\x11\x21\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xe1\xf1" + - name: "ClientType" + value: ClientTypeEnum.Ephemeral response: values: - name: "ICDCounter" @@ -295,8 +330,16 @@ tests: response: value: [ - { CheckInNodeID: 101, MonitoredSubject: 1002 }, - { CheckInNodeID: 201, MonitoredSubject: 2001 }, + { + CheckInNodeID: 101, + MonitoredSubject: 1002, + ClientType: ClientTypeEnum.Ephemeral, + }, + { + CheckInNodeID: 201, + MonitoredSubject: 2001, + ClientType: ClientTypeEnum.Ephemeral, + }, ] - label: "Register 2.2 (wrong verification key)" @@ -312,6 +355,8 @@ tests: - name: "VerificationKey" value: "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2f\x2f" + - name: "ClientType" + value: ClientTypeEnum.Permanent response: values: - name: "ICDCounter" @@ -326,8 +371,16 @@ tests: response: value: [ - { CheckInNodeID: 101, MonitoredSubject: 1002 }, - { CheckInNodeID: 201, MonitoredSubject: 2002 }, + { + CheckInNodeID: 101, + MonitoredSubject: 1002, + ClientType: ClientTypeEnum.Ephemeral, + }, + { + CheckInNodeID: 201, + MonitoredSubject: 2002, + ClientType: ClientTypeEnum.Permanent, + }, ] - label: "Unregister 1.1 (wrong key)" diff --git a/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml b/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml index 7bbcb729489eef..a4eb232b98e157 100644 --- a/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml +++ b/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml @@ -128,6 +128,9 @@ tests: value: MonitorSubID1 - name: "Key" value: Key1 + # Adding input for the test to pass for now - Full test script needs to be updated + - name: "ClientType" + value: ClientTypeEnum.Permanent response: values: - name: "ICDCounter" diff --git a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml index 0269b8f0f3dcad..c1e2805de8bf15 100644 --- a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml @@ -39,17 +39,24 @@ limitations under the License. + + + + + + + - - - + + + @@ -113,6 +120,7 @@ limitations under the License. + diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index d6bc9f5c79fcac..8232292479ff3f 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -91,6 +91,11 @@ CHIP_ERROR AutoCommissioner::VerifyICDRegistrationInfo(const CommissioningParame ChipLogError(Controller, "Missing ICD monitored subject!"); return CHIP_ERROR_INVALID_ARGUMENT; } + if (!params.GetICDClientType().HasValue()) + { + ChipLogError(Controller, "Missing ICD Client Type!"); + return CHIP_ERROR_INVALID_ARGUMENT; + } return CHIP_NO_ERROR; } @@ -270,6 +275,7 @@ CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParam mParams.SetICDSymmetricKey(ByteSpan(mICDSymmetricKey)); mParams.SetICDCheckInNodeId(params.GetICDCheckInNodeId().Value()); mParams.SetICDMonitoredSubject(params.GetICDMonitoredSubject().Value()); + mParams.SetICDClientType(params.GetICDClientType().Value()); } return CHIP_NO_ERROR; diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 99f00f109d4ff0..7a96939cf49434 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -558,6 +558,13 @@ class CommissioningParameters return *this; } + Optional GetICDClientType() const { return mICDClientType; } + CommissioningParameters & SetICDClientType(app::Clusters::IcdManagement::ClientTypeEnum icdClientType) + { + mICDClientType = MakeOptional(icdClientType); + return *this; + } + Optional GetICDStayActiveDurationMsec() const { return mICDStayActiveDurationMsec; } CommissioningParameters & SetICDStayActiveDurationMsec(uint32_t stayActiveDurationMsec) { @@ -632,6 +639,7 @@ class CommissioningParameters Optional mICDCheckInNodeId; Optional mICDMonitoredSubject; Optional mICDSymmetricKey; + Optional mICDClientType; Optional mICDStayActiveDurationMsec; ICDRegistrationStrategy mICDRegistrationStrategy = ICDRegistrationStrategy::kIgnore; bool mCheckForMatchingFabric = false; diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index cb858ffdcd8802..a8567d591b1f7a 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2672,6 +2672,11 @@ cluster BooleanState = 69 { cluster IcdManagement = 70 { revision 2; + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + enum OperatingModeEnum : enum8 { kSIT = 0; kLIT = 1; @@ -2706,6 +2711,7 @@ cluster IcdManagement = 70 { fabric_scoped struct MonitoringRegistrationStruct { fabric_sensitive node_id checkInNodeID = 1; fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; fabric_idx fabricIndex = 254; } @@ -2730,6 +2736,7 @@ cluster IcdManagement = 70 { int64u monitoredSubject = 1; octet_string<16> key = 2; optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; } response struct RegisterClientResponse = 1 { diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 87f53735bcf617..af5d220295a983 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -526,6 +526,12 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Contro VerifyOrReturnError(err == CHIP_NO_ERROR, err); jbyteArray jSymmetricKey = static_cast(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod)); + jmethodID getClientTypeMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getClientType", "()Ljava/lang/Integer;", + &getClientTypeMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jobject jClientType = env->CallObjectMethod(icdRegistrationInfo, getClientTypeMethod); + chip::NodeId checkInNodeId = chip::kUndefinedNodeId; if (jCheckInNodeId != nullptr) { @@ -556,6 +562,14 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Contro } params.SetICDSymmetricKey(chip::ByteSpan(mICDSymmetricKey)); + chip::app::Clusters::IcdManagement::ClientTypeEnum clientType = chip::app::Clusters::IcdManagement::ClientTypeEnum::kPermanent; + if (jClientType != nullptr) + { + clientType = static_cast( + chip::JniReferences::GetInstance().IntegerToPrimitive(jClientType)); + } + params.SetICDClientType(clientType); + return err; } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 80491515bc57d3..4b762e1ef39f37 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -18618,11 +18618,11 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional verificationKey) { - registerClient(callback, checkInNodeID, monitoredSubject, key, verificationKey, 0); + public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional verificationKey, Integer clientType) { + registerClient(callback, checkInNodeID, monitoredSubject, key, verificationKey, clientType, 0); } - public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional verificationKey, int timedInvokeTimeoutMs) { + public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional verificationKey, Integer clientType, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); @@ -18642,6 +18642,10 @@ public void registerClient(RegisterClientResponseCallback callback, Long checkIn BaseTLVType verificationKeytlvValue = verificationKey.map((nonOptionalverificationKey) -> new ByteArrayType(nonOptionalverificationKey)).orElse(new EmptyType()); elements.add(new StructElement(verificationKeyFieldID, verificationKeytlvValue)); + final long clientTypeFieldID = 4L; + BaseTLVType clientTypetlvValue = new UIntType(clientType); + elements.add(new StructElement(clientTypeFieldID, clientTypetlvValue)); + StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @Override diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index c22d3593b9e87e..f78eaf9c83cd10 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -3483,18 +3483,22 @@ public String toString() { public static class IcdManagementClusterMonitoringRegistrationStruct { public Long checkInNodeID; public Long monitoredSubject; + public Integer clientType; public Integer fabricIndex; private static final long CHECK_IN_NODE_I_D_ID = 1L; private static final long MONITORED_SUBJECT_ID = 2L; + private static final long CLIENT_TYPE_ID = 4L; private static final long FABRIC_INDEX_ID = 254L; public IcdManagementClusterMonitoringRegistrationStruct( Long checkInNodeID, Long monitoredSubject, + Integer clientType, Integer fabricIndex ) { this.checkInNodeID = checkInNodeID; this.monitoredSubject = monitoredSubject; + this.clientType = clientType; this.fabricIndex = fabricIndex; } @@ -3502,6 +3506,7 @@ public StructType encodeTlv() { ArrayList values = new ArrayList<>(); values.add(new StructElement(CHECK_IN_NODE_I_D_ID, new UIntType(checkInNodeID))); values.add(new StructElement(MONITORED_SUBJECT_ID, new UIntType(monitoredSubject))); + values.add(new StructElement(CLIENT_TYPE_ID, new UIntType(clientType))); values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); return new StructType(values); @@ -3513,6 +3518,7 @@ public static IcdManagementClusterMonitoringRegistrationStruct decodeTlv(BaseTLV } Long checkInNodeID = null; Long monitoredSubject = null; + Integer clientType = null; Integer fabricIndex = null; for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == CHECK_IN_NODE_I_D_ID) { @@ -3525,6 +3531,11 @@ public static IcdManagementClusterMonitoringRegistrationStruct decodeTlv(BaseTLV UIntType castingValue = element.value(UIntType.class); monitoredSubject = castingValue.value(Long.class); } + } else if (element.contextTagNum() == CLIENT_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + clientType = castingValue.value(Integer.class); + } } else if (element.contextTagNum() == FABRIC_INDEX_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); @@ -3535,6 +3546,7 @@ public static IcdManagementClusterMonitoringRegistrationStruct decodeTlv(BaseTLV return new IcdManagementClusterMonitoringRegistrationStruct( checkInNodeID, monitoredSubject, + clientType, fabricIndex ); } @@ -3549,6 +3561,9 @@ public String toString() { output.append("\tmonitoredSubject: "); output.append(monitoredSubject); output.append("\n"); + output.append("\tclientType: "); + output.append(clientType); + output.append("\n"); output.append("\tfabricIndex: "); output.append(fabricIndex); output.append("\n"); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 06f9941b772c21..cc2cb937c66cad 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -5859,7 +5859,7 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }public enum RegisterClientCommandField {CheckInNodeID(0),MonitoredSubject(1),Key(2),VerificationKey(3),; + }public enum RegisterClientCommandField {CheckInNodeID(0),MonitoredSubject(1),Key(2),VerificationKey(3),ClientType(4),; private final int id; RegisterClientCommandField(int id) { this.id = id; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index f4830c334b842f..2573b42c0184f7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -23986,6 +23986,9 @@ public Map> getCommandMap() { CommandParameterInfo icdManagementregisterClientverificationKeyCommandParameterInfo = new CommandParameterInfo("verificationKey", Optional.class, byte[].class); icdManagementregisterClientCommandParams.put("verificationKey",icdManagementregisterClientverificationKeyCommandParameterInfo); + + CommandParameterInfo icdManagementregisterClientclientTypeCommandParameterInfo = new CommandParameterInfo("clientType", Integer.class, Integer.class); + icdManagementregisterClientCommandParams.put("clientType",icdManagementregisterClientclientTypeCommandParameterInfo); InteractionInfo icdManagementregisterClientInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.IcdManagementCluster) cluster) @@ -24002,6 +24005,9 @@ public Map> getCommandMap() { , (Optional) commandArguments.get("verificationKey") + , (Integer) + commandArguments.get("clientType") + ); }, () -> new DelegatedIcdManagementClusterRegisterClientResponseCallback(), diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt index 8c8a7dcc410261..fd60e6d6da4328 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt @@ -25,12 +25,14 @@ import matter.tlv.TlvWriter class IcdManagementClusterMonitoringRegistrationStruct( val checkInNodeID: ULong, val monitoredSubject: ULong, + val clientType: UInt, val fabricIndex: UInt, ) { override fun toString(): String = buildString { append("IcdManagementClusterMonitoringRegistrationStruct {\n") append("\tcheckInNodeID : $checkInNodeID\n") append("\tmonitoredSubject : $monitoredSubject\n") + append("\tclientType : $clientType\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") } @@ -40,6 +42,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( startStructure(tlvTag) put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D), checkInNodeID) put(ContextSpecificTag(TAG_MONITORED_SUBJECT), monitoredSubject) + put(ContextSpecificTag(TAG_CLIENT_TYPE), clientType) put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() } @@ -48,6 +51,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( companion object { private const val TAG_CHECK_IN_NODE_I_D = 1 private const val TAG_MONITORED_SUBJECT = 2 + private const val TAG_CLIENT_TYPE = 4 private const val TAG_FABRIC_INDEX = 254 fun fromTlv( @@ -57,6 +61,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( tlvReader.enterStructure(tlvTag) val checkInNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D)) val monitoredSubject = tlvReader.getULong(ContextSpecificTag(TAG_MONITORED_SUBJECT)) + val clientType = tlvReader.getUInt(ContextSpecificTag(TAG_CLIENT_TYPE)) val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) tlvReader.exitContainer() @@ -64,6 +69,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( return IcdManagementClusterMonitoringRegistrationStruct( checkInNodeID, monitoredSubject, + clientType, fabricIndex, ) } diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt index fd77e38a6f48fa..ddc206eeb28aad 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt @@ -107,6 +107,7 @@ class IcdManagementCluster( monitoredSubject: ULong, key: ByteArray, verificationKey: ByteArray?, + clientType: UByte, timedInvokeTimeout: Duration? = null, ): RegisterClientResponse { val commandId: UInt = 0u @@ -127,6 +128,9 @@ class IcdManagementCluster( verificationKey?.let { tlvWriter.put(ContextSpecificTag(TAG_VERIFICATION_KEY_REQ), verificationKey) } + + val TAG_CLIENT_TYPE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_CLIENT_TYPE_REQ), clientType) tlvWriter.endStructure() val request: InvokeRequest = diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt index f9866aa93f9ce5..fbf95fd9f40918 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt @@ -25,12 +25,14 @@ import matter.tlv.TlvWriter class IcdManagementClusterMonitoringRegistrationStruct( val checkInNodeID: ULong, val monitoredSubject: ULong, + val clientType: UByte, val fabricIndex: UByte, ) { override fun toString(): String = buildString { append("IcdManagementClusterMonitoringRegistrationStruct {\n") append("\tcheckInNodeID : $checkInNodeID\n") append("\tmonitoredSubject : $monitoredSubject\n") + append("\tclientType : $clientType\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") } @@ -40,6 +42,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( startStructure(tlvTag) put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D), checkInNodeID) put(ContextSpecificTag(TAG_MONITORED_SUBJECT), monitoredSubject) + put(ContextSpecificTag(TAG_CLIENT_TYPE), clientType) put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() } @@ -48,6 +51,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( companion object { private const val TAG_CHECK_IN_NODE_I_D = 1 private const val TAG_MONITORED_SUBJECT = 2 + private const val TAG_CLIENT_TYPE = 4 private const val TAG_FABRIC_INDEX = 254 fun fromTlv( @@ -57,6 +61,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( tlvReader.enterStructure(tlvTag) val checkInNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D)) val monitoredSubject = tlvReader.getULong(ContextSpecificTag(TAG_MONITORED_SUBJECT)) + val clientType = tlvReader.getUByte(ContextSpecificTag(TAG_CLIENT_TYPE)) val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) tlvReader.exitContainer() @@ -64,6 +69,7 @@ class IcdManagementClusterMonitoringRegistrationStruct( return IcdManagementClusterMonitoringRegistrationStruct( checkInNodeID, monitoredSubject, + clientType, fabricIndex, ) } diff --git a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java index be978fae28fee6..417d147238c526 100644 --- a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java +++ b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java @@ -24,11 +24,13 @@ public class ICDRegistrationInfo { @Nullable private final Long checkInNodeId; @Nullable private final Long monitoredSubject; @Nullable private final byte[] symmetricKey; + @Nullable private final Integer clientType; private ICDRegistrationInfo(Builder builder) { this.checkInNodeId = builder.checkInNodeId; this.monitoredSubject = builder.monitoredSubject; this.symmetricKey = builder.symmetricKey; + this.clientType = builder.clientType; } /** Returns the check in node ID. */ @@ -46,6 +48,10 @@ public byte[] getSymmetricKey() { return symmetricKey; } + public Integer getClientType() { + return clientType; + } + public static Builder newBuilder() { return new Builder(); } @@ -55,6 +61,7 @@ public static class Builder { @Nullable private Long checkInNodeId = null; @Nullable private Long monitoredSubject = null; @Nullable private byte[] symmetricKey = null; + @Nullable private Integer clientType = null; private Builder() {} @@ -81,6 +88,11 @@ public Builder setSymmetricKey(byte[] symmetricKey) { return this; } + public Builder setClientType(Integer clientType) { + this.clientType = clientType; + return this; + } + public ICDRegistrationInfo build() { return new ICDRegistrationInfo(this); } diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 7cdabec93f43ca..4cebe9ea5a1829 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -12306,6 +12306,13 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR chip::JniReferences::GetInstance().CreateBoxedObject( newElement_0_monitoredSubjectClassName.c_str(), newElement_0_monitoredSubjectCtorSignature.c_str(), jninewElement_0_monitoredSubject, newElement_0_monitoredSubject); + jobject newElement_0_clientType; + std::string newElement_0_clientTypeClassName = "java/lang/Integer"; + std::string newElement_0_clientTypeCtorSignature = "(I)V"; + jint jninewElement_0_clientType = static_cast(entry_0.clientType); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_clientTypeClassName.c_str(), + newElement_0_clientTypeCtorSignature.c_str(), + jninewElement_0_clientType, newElement_0_clientType); jobject newElement_0_fabricIndex; std::string newElement_0_fabricIndexClassName = "java/lang/Integer"; std::string newElement_0_fabricIndexCtorSignature = "(I)V"; @@ -12325,9 +12332,10 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } jmethodID monitoringRegistrationStructStructCtor_1; - err = chip::JniReferences::GetInstance().FindMethod(env, monitoringRegistrationStructStructClass_1, "", - "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;)V", - &monitoringRegistrationStructStructCtor_1); + err = chip::JniReferences::GetInstance().FindMethod( + env, monitoringRegistrationStructStructClass_1, "", + "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;)V", + &monitoringRegistrationStructStructCtor_1); if (err != CHIP_NO_ERROR || monitoringRegistrationStructStructCtor_1 == nullptr) { ChipLogError(Zcl, "Could not find ChipStructs$IcdManagementClusterMonitoringRegistrationStruct constructor"); @@ -12335,7 +12343,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } newElement_0 = env->NewObject(monitoringRegistrationStructStructClass_1, monitoringRegistrationStructStructCtor_1, - newElement_0_checkInNodeID, newElement_0_monitoredSubject, newElement_0_fabricIndex); + newElement_0_checkInNodeID, newElement_0_monitoredSubject, newElement_0_clientType, + newElement_0_fabricIndex); chip::JniReferences::GetInstance().AddToList(value, newElement_0); } return value; diff --git a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp index c979e0d9cd77a3..c04481a45a11ea 100644 --- a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp +++ b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp @@ -191,6 +191,7 @@ void ScriptDevicePairingDelegate::OnICDRegistrationComplete(ScopedNodeId nodeId, clientInfo.peer_node = nodeId; clientInfo.monitored_subject = sCommissioningParameters.GetICDMonitoredSubject().Value(); clientInfo.start_icd_counter = icdCounter; + clientInfo.client_type = sCommissioningParameters.GetICDClientType().Value(); CHIP_ERROR err = sICDClientStorage.SetKey(clientInfo, ByteSpan(sICDSymmetricKey)); if (err == CHIP_NO_ERROR) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 773fe342105443..37ead8e634611a 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -4064,6 +4064,7 @@ class ChipClusters: "monitoredSubject": "int", "key": "bytes", "verificationKey": "bytes", + "clientType": "int", }, }, 0x00000002: { diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 43917192955506..4c17fd99af2d21 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -14187,6 +14187,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: clusterRevision: 'uint' = None class Enums: + class ClientTypeEnum(MatterIntEnum): + kPermanent = 0x00 + kEphemeral = 0x01 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 2, + class OperatingModeEnum(MatterIntEnum): kSit = 0x00 kLit = 0x01 @@ -14230,11 +14239,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="checkInNodeID", Tag=1, Type=uint), ClusterObjectFieldDescriptor(Label="monitoredSubject", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="clientType", Tag=4, Type=IcdManagement.Enums.ClientTypeEnum), ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) checkInNodeID: 'uint' = 0 monitoredSubject: 'uint' = 0 + clientType: 'IcdManagement.Enums.ClientTypeEnum' = 0 fabricIndex: 'uint' = 0 class Commands: @@ -14253,12 +14264,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="monitoredSubject", Tag=1, Type=uint), ClusterObjectFieldDescriptor(Label="key", Tag=2, Type=bytes), ClusterObjectFieldDescriptor(Label="verificationKey", Tag=3, Type=typing.Optional[bytes]), + ClusterObjectFieldDescriptor(Label="clientType", Tag=4, Type=IcdManagement.Enums.ClientTypeEnum), ]) checkInNodeID: 'uint' = 0 monitoredSubject: 'uint' = 0 key: 'bytes' = b"" verificationKey: 'typing.Optional[bytes]' = None + clientType: 'IcdManagement.Enums.ClientTypeEnum' = 0 @dataclass class RegisterClientResponse(ClusterCommand): diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 02ce62e1c2f0dc..1feae62ea18928 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -5040,6 +5040,7 @@ static id _Nullable DecodeAttributeValueForICDManagementCluster(AttributeId aAtt newElement_0 = [MTRICDManagementClusterMonitoringRegistrationStruct new]; newElement_0.checkInNodeID = [NSNumber numberWithUnsignedLongLong:entry_0.checkInNodeID]; newElement_0.monitoredSubject = [NSNumber numberWithUnsignedLongLong:entry_0.monitoredSubject]; + newElement_0.clientType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.clientType)]; newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex]; [array_0 addObject:newElement_0]; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index a481ad0f37f8a4..1513b8c0f54540 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -17756,6 +17756,11 @@ typedef NS_OPTIONS(uint32_t, MTRGroupKeyManagementFeature) { MTRGroupKeyManagementFeatureCacheAndSync MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint8_t, MTRICDManagementClientType) { + MTRICDManagementClientTypePermanent MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRICDManagementClientTypeEphemeral MTR_PROVISIONALLY_AVAILABLE = 0x01, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRICDManagementOperatingMode) { MTRICDManagementOperatingModeSIT MTR_PROVISIONALLY_AVAILABLE = 0x00, MTRICDManagementOperatingModeLIT MTR_PROVISIONALLY_AVAILABLE = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 4e74aa8828a718..d95ac77034ce61 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -3618,6 +3618,8 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSData * _Nonnull key MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSData * _Nullable verificationKey MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull clientType MTR_PROVISIONALLY_AVAILABLE; /** * Controls whether the command is a timed command (using Timed Invoke). * diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 1dd6753fa889ed..08b00b6e4555f0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -9524,6 +9524,8 @@ - (instancetype)init _key = [NSData data]; _verificationKey = nil; + + _clientType = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -9538,6 +9540,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; other.monitoredSubject = self.monitoredSubject; other.key = self.key; other.verificationKey = self.verificationKey; + other.clientType = self.clientType; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -9546,7 +9549,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; key:%@; verificationKey:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, [_key base64EncodedStringWithOptions:0], [_verificationKey base64EncodedStringWithOptions:0]]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; key:%@; verificationKey:%@; clientType:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, [_key base64EncodedStringWithOptions:0], [_verificationKey base64EncodedStringWithOptions:0], _clientType]; return descriptionString; } @@ -9573,6 +9576,9 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader definedValue_0 = AsByteSpan(self.verificationKey); } } + { + encodableStruct.clientType = static_cast>(self.clientType.unsignedCharValue); + } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 2d5da93d9df2f5..8ea03ce1fd2a9d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -762,6 +762,7 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRICDManagementClusterMonitoringRegistrationStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull checkInNodeID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull monitoredSubject MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull clientType MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 559789940c7fb9..1ff604e5469e36 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -2774,6 +2774,8 @@ - (instancetype)init _monitoredSubject = @(0); + _clientType = @(0); + _fabricIndex = @(0); } return self; @@ -2785,6 +2787,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.checkInNodeID = self.checkInNodeID; other.monitoredSubject = self.monitoredSubject; + other.clientType = self.clientType; other.fabricIndex = self.fabricIndex; return other; @@ -2792,7 +2795,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, _fabricIndex]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; clientType:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, _clientType, _fabricIndex]; return descriptionString; } diff --git a/src/lib/support/JniReferences.cpp b/src/lib/support/JniReferences.cpp index 6b8bb005305417..021f13c2fb0fb2 100644 --- a/src/lib/support/JniReferences.cpp +++ b/src/lib/support/JniReferences.cpp @@ -392,6 +392,19 @@ jdouble JniReferences::DoubleToPrimitive(jobject boxedDouble) return env->CallDoubleMethod(boxedDouble, valueMethod); } +jshort JniReferences::ShortToPrimitive(jobject boxedShort) +{ + JNIEnv * env = GetEnvForCurrentThread(); + VerifyOrReturnValue(env != nullptr, 0, ChipLogError(Support, "env cannot be nullptr")); + jclass boxedTypeCls = nullptr; + CHIP_ERROR err = chip::JniReferences::GetInstance().GetLocalClassRef(env, "java/lang/Short", boxedTypeCls); + VerifyOrReturnValue(err == CHIP_NO_ERROR, 0, + ChipLogError(Support, "ShortToPrimitive failed due to %" CHIP_ERROR_FORMAT, err.Format())); + + jmethodID valueMethod = env->GetMethodID(boxedTypeCls, "shortValue", "()S"); + return env->CallShortMethod(boxedShort, valueMethod); +} + CHIP_ERROR JniReferences::CallSubscriptionEstablished(jobject javaCallback, long subscriptionId) { CHIP_ERROR err = CHIP_NO_ERROR; diff --git a/src/lib/support/JniReferences.h b/src/lib/support/JniReferences.h index 5cea905dc00776..a9a3e29ebcb845 100644 --- a/src/lib/support/JniReferences.h +++ b/src/lib/support/JniReferences.h @@ -177,6 +177,11 @@ class JniReferences */ jdouble DoubleToPrimitive(jobject boxedObject); + /** + * Get a primitive jshort from the Java boxed type Short, using shortValue(). + */ + jshort ShortToPrimitive(jobject boxedShort); + CHIP_ERROR CreateArrayList(jobject & outList); CHIP_ERROR AddToList(jobject list, jobject objectToAdd); diff --git a/src/python_testing/TC_ICDM_3_1.py b/src/python_testing/TC_ICDM_3_1.py index b504035f52d86f..f5a37cd763c7af 100644 --- a/src/python_testing/TC_ICDM_3_1.py +++ b/src/python_testing/TC_ICDM_3_1.py @@ -38,6 +38,7 @@ cluster = Clusters.Objects.IcdManagement commands = cluster.Commands monitoredRegistration = cluster.Structs.MonitoringRegistrationStruct +clientTypeEnum = cluster.Enums.ClientTypeEnum # Step 2 Registration entry @@ -141,7 +142,7 @@ async def test_TC_ICDM_3_1(self): self.step(2) if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): try: - response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key)) + response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key, clientType=clientTypeEnum.kEphemeral)) except InteractionModelError as e: asserts.assert_equal( e.status, Status.Success, "Unexpected error returned") @@ -164,6 +165,8 @@ async def test_TC_ICDM_3_1(self): registeredClients[0].checkInNodeID, kStep2CheckInNodeId, "The read attribute does not match the registered value.") asserts.assert_equal( registeredClients[0].monitoredSubject, kStep2MonitoredSubjectStep2, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].clientType, clientTypeEnum.kEphemeral, "The read attribute does not match the registered value.") self.step(4) if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): @@ -174,12 +177,13 @@ async def test_TC_ICDM_3_1(self): newClients.append({ "checkInNodeID": i + 1, "monitoredSubject": i + 1, - "key": os.urandom(16) + "key": os.urandom(16), + "clientType": clientTypeEnum.kPermanent }) for client in newClients: try: - response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client["checkInNodeID"], monitoredSubject=client["monitoredSubject"], key=client["key"])) + response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client["checkInNodeID"], monitoredSubject=client["monitoredSubject"], key=client["key"], clientType=client["clientType"])) except InteractionModelError as e: asserts.assert_equal( e.status, Status.Success, "Unexpected error returned") @@ -203,11 +207,13 @@ async def test_TC_ICDM_3_1(self): client.checkInNodeID, expectedClient["checkInNodeID"], "The read attribute does not match the registered value.") asserts.assert_equal( client.monitoredSubject, expectedClient["monitoredSubject"], "The read attribute does not match the registered value.") + asserts.assert_equal( + client.clientType, expectedClient["clientType"], "The read attribute does not match the registered value.") self.step(6) if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): try: - response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16))) + response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16), clientType=clientTypeEnum.kPermanent)) except InteractionModelError as e: asserts.assert_equal( e.status, Status.ResourceExhausted, "Unexpected error returned") diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index e53404d7b32737..7e52fd09a2c13c 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -1328,6 +1328,18 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(GroupKeyManagement::Gro } } +static auto __attribute__((unused)) EnsureKnownEnumValue(IcdManagement::ClientTypeEnum val) +{ + using EnumType = IcdManagement::ClientTypeEnum; + switch (val) + { + case EnumType::kPermanent: + case EnumType::kEphemeral: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} static auto __attribute__((unused)) EnsureKnownEnumValue(IcdManagement::OperatingModeEnum val) { using EnumType = IcdManagement::OperatingModeEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 27601f4e651c63..a7c433848df662 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -1601,6 +1601,18 @@ namespace BooleanState {} // namespace BooleanState namespace IcdManagement { +// Enum for ClientTypeEnum +enum class ClientTypeEnum : uint8_t +{ + kPermanent = 0x00, + kEphemeral = 0x01, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 2, +}; + // Enum for OperatingModeEnum enum class OperatingModeEnum : uint8_t { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 289909746b0640..54bcec37353ef1 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -9622,6 +9622,10 @@ CHIP_ERROR Type::DoEncode(TLV::TLVWriter & aWriter, TLV::Tag aTag, const Optiona { encoder.Encode(to_underlying(Fields::kMonitoredSubject), monitoredSubject); } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kClientType), clientType); + } if (aAccessingFabricIndex.HasValue()) { encoder.Encode(to_underlying(Fields::kFabricIndex), fabricIndex); @@ -9652,6 +9656,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, monitoredSubject); } + else if (__context_tag == to_underlying(Fields::kClientType)) + { + err = DataModel::Decode(reader, clientType); + } else if (__context_tag == to_underlying(Fields::kFabricIndex)) { err = DataModel::Decode(reader, fabricIndex); @@ -9676,6 +9684,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const encoder.Encode(to_underlying(Fields::kMonitoredSubject), monitoredSubject); encoder.Encode(to_underlying(Fields::kKey), key); encoder.Encode(to_underlying(Fields::kVerificationKey), verificationKey); + encoder.Encode(to_underlying(Fields::kClientType), clientType); return encoder.Finalize(); } @@ -9709,6 +9718,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, verificationKey); } + else if (__context_tag == to_underlying(Fields::kClientType)) + { + err = DataModel::Decode(reader, clientType); + } else { } diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index d396989d0a6edf..84f19b11e4f105 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -13130,6 +13130,7 @@ enum class Fields : uint8_t { kCheckInNodeID = 1, kMonitoredSubject = 2, + kClientType = 4, kFabricIndex = 254, }; @@ -13138,6 +13139,7 @@ struct Type public: chip::NodeId checkInNodeID = static_cast(0); uint64_t monitoredSubject = static_cast(0); + ClientTypeEnum clientType = static_cast(0); chip::FabricIndex fabricIndex = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -13198,6 +13200,7 @@ enum class Fields : uint8_t kMonitoredSubject = 1, kKey = 2, kVerificationKey = 3, + kClientType = 4, }; struct Type @@ -13211,6 +13214,7 @@ struct Type uint64_t monitoredSubject = static_cast(0); chip::ByteSpan key; Optional verificationKey; + ClientTypeEnum clientType = static_cast(0); CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -13229,6 +13233,7 @@ struct DecodableType uint64_t monitoredSubject = static_cast(0); chip::ByteSpan key; Optional verificationKey; + ClientTypeEnum clientType = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace RegisterClient diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index a9658c4a1ace4f..2cdd59a303bb63 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -4242,6 +4242,7 @@ class IcdManagementRegisterClient : public ClusterCommand AddArgument("MonitoredSubject", 0, UINT64_MAX, &mRequest.monitoredSubject); AddArgument("Key", &mRequest.key); AddArgument("VerificationKey", &mRequest.verificationKey); + AddArgument("ClientType", 0, UINT8_MAX, &mRequest.clientType); ClusterCommand::AddArguments(); } diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 6c7da78177ff10..6a73b61ce13720 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -2066,6 +2066,8 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, value.isMember("checkInNodeID"))); ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.monitoredSubject", "monitoredSubject", value.isMember("monitoredSubject"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.clientType", "clientType", + value.isMember("clientType"))); char labelWithMember[kMaxLabelLength]; snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "checkInNodeID"); @@ -2076,6 +2078,10 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.monitoredSubject, value["monitoredSubject"])); valueCopy.removeMember("monitoredSubject"); + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "clientType"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.clientType, value["clientType"])); + valueCopy.removeMember("clientType"); + if (value.isMember("fabricIndex")) { snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex"); @@ -2090,6 +2096,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::IcdManagement::Structs { ComplexArgumentParser::Finalize(request.checkInNodeID); ComplexArgumentParser::Finalize(request.monitoredSubject); + ComplexArgumentParser::Finalize(request.clientType); ComplexArgumentParser::Finalize(request.fabricIndex); } diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 1f8be3d7029a79..a9d3f942abcd7c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -1878,6 +1878,14 @@ DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = LogValue("ClientType", indent + 1, value.clientType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ClientType'"); + return err; + } + } { CHIP_ERROR err = LogValue("FabricIndex", indent + 1, value.fabricIndex); if (err != CHIP_NO_ERROR) diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 2bea6e6b3fff8a..dfac8e499e1449 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -47524,6 +47524,9 @@ class IcdManagementRegisterClient : public ClusterCommand { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL AddArgument("VerificationKey", &mRequest.verificationKey); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ClientType", 0, UINT8_MAX, &mRequest.clientType); #endif // MTR_ENABLE_PROVISIONAL ClusterCommand::AddArguments(); } @@ -47554,6 +47557,9 @@ class IcdManagementRegisterClient : public ClusterCommand { } else { params.verificationKey = nil; } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.clientType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.clientType)]; #endif // MTR_ENABLE_PROVISIONAL uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount;