From d809f32b012263b3981617d96c87cbad7a21df70 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Tue, 5 Dec 2023 07:21:48 -0800 Subject: [PATCH] [ICD] Store UserActiveModeTriggerHint and instruction into ICD storage (#30770) * Store UserActiveModeTriggerBitmap and instruction into ICD storage * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../icd/client/DefaultICDClientStorage.cpp | 32 +++++++++++++++++-- src/app/icd/client/DefaultICDClientStorage.h | 17 ++++++---- src/app/icd/client/ICDClientInfo.h | 30 ++++++++++++----- src/app/tests/TestDefaultICDClientStorage.cpp | 16 +++++++--- 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index add4923e16f5fb..503e042cd4af43 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -258,8 +258,27 @@ CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector(strlen(clientInfo.user_active_mode_trigger_instruction)))); + } + ByteSpan buf(clientInfo.shared_key.As()); ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kSharedKey), buf)); ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType)); diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h index 3637221df0c7f1..f9af7d35eca687 100644 --- a/src/app/icd/client/DefaultICDClientStorage.h +++ b/src/app/icd/client/DefaultICDClientStorage.h @@ -67,12 +67,14 @@ class DefaultICDClientStorage : public ICDClientStorage protected: enum class ClientInfoTag : uint8_t { - kPeerNodeId = 1, - kFabricIndex = 2, - kStartICDCounter = 3, - kOffset = 4, - kMonitoredSubject = 5, - kSharedKey = 6 + kPeerNodeId = 1, + kFabricIndex = 2, + kStartICDCounter = 3, + kOffset = 4, + kMonitoredSubject = 5, + kUserActiveModeTriggerHint = 6, + kUserActiveModeTriggerInstruction = 7, + kSharedKey = 8 }; enum class CounterTag : uint8_t @@ -100,7 +102,8 @@ class DefaultICDClientStorage : public ICDClientStorage { // All the fields added together return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t), sizeof(uint32_t), - sizeof(uint64_t), sizeof(Crypto::Symmetric128BitsKeyByteArray)); + sizeof(uint64_t), sizeof(uint32_t), kUserActiveModeTriggerInstructionSize, + sizeof(Crypto::Symmetric128BitsKeyByteArray)); } static constexpr size_t MaxICDCounterSize() diff --git a/src/app/icd/client/ICDClientInfo.h b/src/app/icd/client/ICDClientInfo.h index f7863b61798148..08ad26712f87b0 100644 --- a/src/app/icd/client/ICDClientInfo.h +++ b/src/app/icd/client/ICDClientInfo.h @@ -24,26 +24,40 @@ #include #include +namespace { +constexpr size_t kUserActiveModeTriggerInstructionSize = 128; +} // namespace + namespace chip { 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 shared_key = Crypto::Aes128KeyHandle(); + uint32_t start_icd_counter = 0; + uint32_t offset = 0; + uint64_t monitored_subject = static_cast(0); + uint32_t user_active_mode_trigger_hint = 0; + char user_active_mode_trigger_instruction[kUserActiveModeTriggerInstructionSize] = { 0 }; + bool has_instruction = false; + Crypto::Aes128KeyHandle shared_key = Crypto::Aes128KeyHandle(); ICDClientInfo() {} ICDClientInfo(const ICDClientInfo & other) { *this = other; } ICDClientInfo & operator=(const ICDClientInfo & other) { - peer_node = other.peer_node; - start_icd_counter = other.start_icd_counter; - offset = other.offset; - monitored_subject = other.monitored_subject; + peer_node = other.peer_node; + start_icd_counter = other.start_icd_counter; + offset = other.offset; + monitored_subject = other.monitored_subject; + user_active_mode_trigger_hint = other.user_active_mode_trigger_hint; + if (other.has_instruction) + { + memcpy(user_active_mode_trigger_instruction, other.user_active_mode_trigger_instruction, + kUserActiveModeTriggerInstructionSize); + } + has_instruction = other.has_instruction; ByteSpan buf(other.shared_key.As()); memcpy(shared_key.AsMutable(), buf.data(), sizeof(Crypto::Symmetric128BitsKeyByteArray)); diff --git a/src/app/tests/TestDefaultICDClientStorage.cpp b/src/app/tests/TestDefaultICDClientStorage.cpp index 399f7689aee2ef..7d05a1bfc28373 100644 --- a/src/app/tests/TestDefaultICDClientStorage.cpp +++ b/src/app/tests/TestDefaultICDClientStorage.cpp @@ -70,11 +70,16 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) // Write some ClientInfos and see the counts are correct ICDClientInfo clientInfo1; clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId); + char val[5] = "test"; ICDClientInfo clientInfo2; - clientInfo2.peer_node = ScopedNodeId(nodeId2, fabricId); + clientInfo2.peer_node = ScopedNodeId(nodeId2, fabricId); + clientInfo2.user_active_mode_trigger_hint = 1; + memcpy(clientInfo2.user_active_mode_trigger_instruction, val, sizeof(val)); + clientInfo2.has_instruction = true; ICDClientInfo clientInfo3; - clientInfo3.peer_node = ScopedNodeId(nodeId1, fabricId); - err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); + clientInfo3.peer_node = ScopedNodeId(nodeId1, fabricId); + clientInfo3.user_active_mode_trigger_hint = 2; + err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo1); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -97,9 +102,12 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) ICDClientInfo clientInfo; NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId2); + NL_TEST_ASSERT(apSuite, clientInfo.has_instruction); + NL_TEST_ASSERT(apSuite, strcmp(clientInfo.user_active_mode_trigger_instruction, val) == 0); NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId1); - + NL_TEST_ASSERT(apSuite, clientInfo.user_active_mode_trigger_hint == 2); + NL_TEST_ASSERT(apSuite, !clientInfo.has_instruction); iterator->Release(); // Delete all and verify iterator counts 0