Matter SDK Coverage Report
Current view: top level - app/icd/client - DefaultICDClientStorage.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 93.3 % 299 279
Test Date: 2026-04-27 19:52:19 Functions: 95.7 % 23 22

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2023 Project CHIP Authors
       3              :  *    All rights reserved.
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #include <app/icd/client/DefaultICDClientStorage.h>
      19              : #include <iterator>
      20              : #include <lib/core/Global.h>
      21              : #include <lib/support/Base64.h>
      22              : #include <lib/support/CodeUtils.h>
      23              : #include <lib/support/DefaultStorageKeyAllocator.h>
      24              : #include <lib/support/SafeInt.h>
      25              : #include <lib/support/logging/CHIPLogging.h>
      26              : #include <limits>
      27              : 
      28              : namespace {
      29              : // FabricIndex is uint8_t, the tlv size with anonymous tag is 1(control bytes) + 1(value) = 2
      30              : constexpr size_t kFabricIndexTlvSize = 2;
      31              : 
      32              : // The array itself has a control byte and an end-of-array marker.
      33              : constexpr size_t kArrayOverHead  = 2;
      34              : constexpr size_t kFabricIndexMax = 255;
      35              : 
      36              : constexpr size_t kMaxFabricListTlvLength = kFabricIndexTlvSize * kFabricIndexMax + kArrayOverHead;
      37              : static_assert(kMaxFabricListTlvLength <= std::numeric_limits<uint16_t>::max(), "Expected size for fabric list TLV is too large!");
      38              : } // namespace
      39              : 
      40              : namespace chip {
      41              : namespace app {
      42           13 : CHIP_ERROR DefaultICDClientStorage::UpdateFabricList(FabricIndex fabricIndex)
      43              : {
      44           17 :     for (auto & fabric_idx : mFabricList)
      45              :     {
      46            4 :         if (fabric_idx == fabricIndex)
      47              :         {
      48            0 :             return CHIP_NO_ERROR;
      49              :         }
      50              :     }
      51              : 
      52           13 :     mFabricList.push_back(fabricIndex);
      53              : 
      54           13 :     return StoreFabricList();
      55              : }
      56              : 
      57           16 : CHIP_ERROR DefaultICDClientStorage::StoreFabricList()
      58              : {
      59           16 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
      60           16 :     size_t counter = mFabricList.size();
      61           16 :     size_t total   = kFabricIndexTlvSize * counter + kArrayOverHead;
      62           16 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
      63           16 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
      64              : 
      65              :     TLV::TLVType arrayType;
      66           16 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType));
      67           36 :     for (auto & fabric_idx : mFabricList)
      68              :     {
      69           20 :         ReturnErrorOnFailure(writer.Put(TLV::AnonymousTag(), fabric_idx));
      70              :     }
      71           16 :     ReturnErrorOnFailure(writer.EndContainer(arrayType));
      72              : 
      73           16 :     const auto len = writer.GetLengthWritten();
      74           16 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
      75              : 
      76           16 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
      77           32 :     return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(),
      78           16 :                                               static_cast<uint16_t>(len));
      79           16 : }
      80              : 
      81            8 : CHIP_ERROR DefaultICDClientStorage::LoadFabricList()
      82              : {
      83            8 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
      84            8 :     VerifyOrReturnError(backingBuffer.Calloc(kMaxFabricListTlvLength), CHIP_ERROR_NO_MEMORY);
      85            8 :     uint16_t length = kMaxFabricListTlvLength;
      86            8 :     ReturnErrorOnFailure(
      87              :         mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), length));
      88              : 
      89            0 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
      90            0 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag()));
      91              :     TLV::TLVType arrayType;
      92            0 :     ReturnErrorOnFailure(reader.EnterContainer(arrayType));
      93              : 
      94            0 :     while ((reader.Next(TLV::kTLVType_UnsignedInteger, TLV::AnonymousTag())) == CHIP_NO_ERROR)
      95              :     {
      96              :         FabricIndex fabricIndex;
      97            0 :         ReturnErrorOnFailure(reader.Get(fabricIndex));
      98            0 :         mFabricList.push_back(fabricIndex);
      99              :     }
     100              : 
     101            0 :     ReturnErrorOnFailure(reader.ExitContainer(arrayType));
     102            0 :     return reader.VerifyEndOfContainer();
     103            8 : }
     104              : 
     105           29 : DefaultICDClientStorage::ICDClientInfoIteratorImpl::ICDClientInfoIteratorImpl(DefaultICDClientStorage & manager) : mManager(manager)
     106              : {
     107           29 :     mFabricListIndex = 0;
     108           29 :     mClientInfoIndex = 0;
     109           29 :     mClientInfoVector.clear();
     110           29 : }
     111              : 
     112            9 : size_t DefaultICDClientStorage::ICDClientInfoIteratorImpl::Count()
     113              : {
     114            9 :     size_t total = 0;
     115           21 :     for (auto & fabric_idx : mManager.mFabricList)
     116              :     {
     117           12 :         size_t count          = 0;
     118           12 :         size_t clientInfoSize = 0;
     119           24 :         if (mManager.LoadCounter(fabric_idx, count, clientInfoSize) != CHIP_NO_ERROR)
     120              :         {
     121            0 :             return 0;
     122              :         };
     123              :         IgnoreUnusedVariable(clientInfoSize);
     124           12 :         total += count;
     125              :     }
     126              : 
     127            9 :     return total;
     128              : }
     129              : 
     130           35 : bool DefaultICDClientStorage::ICDClientInfoIteratorImpl::Next(ICDClientInfo & item)
     131              : {
     132           45 :     for (; mFabricListIndex < mManager.mFabricList.size(); mFabricListIndex++)
     133              :     {
     134           38 :         if (mClientInfoVector.size() == 0)
     135              :         {
     136           29 :             size_t clientInfoSize = 0;
     137           58 :             if (mManager.Load(mManager.mFabricList[mFabricListIndex], mClientInfoVector, clientInfoSize) != CHIP_NO_ERROR)
     138              :             {
     139            0 :                 continue;
     140              :             }
     141              :             IgnoreUnusedVariable(clientInfoSize);
     142              :         }
     143           38 :         if (mClientInfoIndex < mClientInfoVector.size())
     144              :         {
     145           28 :             item = mClientInfoVector[mClientInfoIndex];
     146           28 :             mClientInfoIndex++;
     147           28 :             return true;
     148              :         }
     149           10 :         mClientInfoIndex = 0;
     150           10 :         mClientInfoVector.clear();
     151              :     }
     152              : 
     153            7 :     return false;
     154              : }
     155              : 
     156           29 : void DefaultICDClientStorage::ICDClientInfoIteratorImpl::Release()
     157              : {
     158           29 :     mManager.mICDClientInfoIterators.ReleaseObject(this);
     159           29 : }
     160              : 
     161            8 : CHIP_ERROR DefaultICDClientStorage::Init(PersistentStorageDelegate * clientInfoStore, Crypto::SymmetricKeystore * keyStore)
     162              : {
     163            8 :     VerifyOrReturnError(clientInfoStore != nullptr && keyStore != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     164            8 :     VerifyOrReturnError(mpClientInfoStore == nullptr && mpKeyStore == nullptr, CHIP_ERROR_INCORRECT_STATE);
     165            8 :     mpClientInfoStore = clientInfoStore;
     166            8 :     mpKeyStore        = keyStore;
     167            8 :     CHIP_ERROR err    = LoadFabricList();
     168           16 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     169              :     {
     170            8 :         err = CHIP_NO_ERROR;
     171              :     }
     172            8 :     return err;
     173              : }
     174              : 
     175           29 : DefaultICDClientStorage::ICDClientInfoIterator * DefaultICDClientStorage::IterateICDClientInfo()
     176              : {
     177           29 :     return mICDClientInfoIterators.CreateObject(*this);
     178              : }
     179              : 
     180          103 : CHIP_ERROR DefaultICDClientStorage::LoadCounter(FabricIndex fabricIndex, size_t & count, size_t & clientInfoSize)
     181              : {
     182          103 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     183          103 :     size_t len = MaxICDCounterSize();
     184          103 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     185          103 :     VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY);
     186          103 :     uint16_t length = static_cast<uint16_t>(len);
     187              : 
     188          103 :     CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue(
     189          206 :         DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(), backingBuffer.Get(), length);
     190          206 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     191              :     {
     192           24 :         return CHIP_NO_ERROR;
     193              :     }
     194           79 :     ReturnErrorOnFailure(err);
     195              : 
     196           79 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
     197           79 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));
     198              :     TLV::TLVType structType;
     199           79 :     ReturnErrorOnFailure(reader.EnterContainer(structType));
     200           79 :     uint32_t tempCount = 0;
     201           79 :     ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kCount)));
     202           79 :     ReturnErrorOnFailure(reader.Get(tempCount));
     203           79 :     count = static_cast<size_t>(tempCount);
     204              : 
     205           79 :     uint32_t tempClientInfoSize = 0;
     206           79 :     ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kSize)));
     207           79 :     ReturnErrorOnFailure(reader.Get(tempClientInfoSize));
     208           79 :     clientInfoSize = static_cast<size_t>(tempClientInfoSize);
     209              : 
     210           79 :     ReturnErrorOnFailure(reader.ExitContainer(structType));
     211           79 :     return reader.VerifyEndOfContainer();
     212          103 : }
     213              : 
     214           61 : CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector<ICDClientInfo> & clientInfoVector,
     215              :                                          size_t & clientInfoSize)
     216              : {
     217           61 :     size_t count = 0;
     218           61 :     ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize));
     219           61 :     VerifyOrReturnError(count > 0, CHIP_NO_ERROR);
     220           46 :     size_t len = clientInfoSize * count + kArrayOverHead;
     221           46 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     222           46 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     223           46 :     VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY);
     224           46 :     uint16_t length = static_cast<uint16_t>(len);
     225           46 :     CHIP_ERROR err  = mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName(),
     226           46 :                                                          backingBuffer.Get(), length);
     227           92 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     228              :     {
     229            0 :         return CHIP_NO_ERROR;
     230              :     }
     231           46 :     ReturnErrorOnFailure(err);
     232              : 
     233           46 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
     234              : 
     235           46 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag()));
     236              :     TLV::TLVType arrayType;
     237           46 :     ReturnErrorOnFailure(reader.EnterContainer(arrayType));
     238              : 
     239          194 :     while ((err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())) == CHIP_NO_ERROR)
     240              :     {
     241           51 :         ICDClientInfo clientInfo;
     242              :         TLV::TLVType ICDClientInfoType;
     243              :         NodeId nodeId;
     244              :         NodeId checkInNodeId;
     245              :         FabricIndex fabric;
     246           51 :         ReturnErrorOnFailure(reader.EnterContainer(ICDClientInfoType));
     247              :         // Peer Node ID
     248           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kPeerNodeId)));
     249           51 :         ReturnErrorOnFailure(reader.Get(nodeId));
     250              : 
     251           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kCheckInNodeId)));
     252           51 :         ReturnErrorOnFailure(reader.Get(checkInNodeId));
     253              : 
     254              :         // Fabric Index
     255           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kFabricIndex)));
     256           51 :         ReturnErrorOnFailure(reader.Get(fabric));
     257              : 
     258           51 :         clientInfo.peer_node     = ScopedNodeId(nodeId, fabric);
     259           51 :         clientInfo.check_in_node = ScopedNodeId(checkInNodeId, fabric);
     260              : 
     261              :         // Start ICD Counter
     262           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kStartICDCounter)));
     263           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.start_icd_counter));
     264              : 
     265              :         // Offset
     266           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kOffset)));
     267           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.offset));
     268              : 
     269              :         // MonitoredSubject
     270           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kMonitoredSubject)));
     271           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.monitored_subject));
     272              : 
     273              :         // Aes key handle
     274           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kAesKeyHandle)));
     275           51 :         ByteSpan aesBuf;
     276           51 :         ReturnErrorOnFailure(reader.Get(aesBuf));
     277           51 :         VerifyOrReturnError(aesBuf.size() == Crypto::Aes128KeyHandle::Size(), CHIP_ERROR_INTERNAL);
     278           51 :         memcpy(clientInfo.aes_key_handle.OpaqueBytes().data(), aesBuf.data(), Crypto::Aes128KeyHandle::Size());
     279              : 
     280              :         // Hmac key handle
     281           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle)));
     282           51 :         ByteSpan hmacBuf;
     283           51 :         ReturnErrorOnFailure(reader.Get(hmacBuf));
     284           51 :         VerifyOrReturnError(hmacBuf.size() == Crypto::Hmac128KeyHandle::Size(), CHIP_ERROR_INTERNAL);
     285           51 :         memcpy(clientInfo.hmac_key_handle.OpaqueBytes().data(), hmacBuf.data(), Crypto::Hmac128KeyHandle::Size());
     286              : 
     287              :         // ClientType
     288           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kClientType)));
     289           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.client_type));
     290              : 
     291           51 :         ReturnErrorOnFailure(reader.ExitContainer(ICDClientInfoType));
     292           51 :         clientInfoVector.push_back(clientInfo);
     293           51 :     }
     294              : 
     295           92 :     if (err != CHIP_END_OF_TLV)
     296              :     {
     297            0 :         return err;
     298              :     }
     299              : 
     300           46 :     ReturnErrorOnFailure(reader.ExitContainer(arrayType));
     301           46 :     return reader.VerifyEndOfContainer();
     302           46 : }
     303              : 
     304           17 : CHIP_ERROR DefaultICDClientStorage::SetKey(ICDClientInfo & clientInfo, const ByteSpan keyData)
     305              : {
     306           17 :     VerifyOrReturnError(keyData.size() == sizeof(Crypto::Symmetric128BitsKeyByteArray), CHIP_ERROR_INVALID_ARGUMENT);
     307              : 
     308              :     Crypto::Symmetric128BitsKeyByteArray keyMaterial;
     309           17 :     memcpy(keyMaterial, keyData.data(), sizeof(Crypto::Symmetric128BitsKeyByteArray));
     310              : 
     311              :     // TODO : Update key lifetime once creaKey method supports it.
     312           17 :     ReturnErrorOnFailure(mpKeyStore->CreateKey(keyMaterial, clientInfo.aes_key_handle));
     313           17 :     CHIP_ERROR err = mpKeyStore->CreateKey(keyMaterial, clientInfo.hmac_key_handle);
     314           34 :     if (err != CHIP_NO_ERROR)
     315              :     {
     316            0 :         mpKeyStore->DestroyKey(clientInfo.aes_key_handle);
     317              :     }
     318           17 :     return err;
     319              : }
     320              : 
     321           13 : void DefaultICDClientStorage::RemoveKey(ICDClientInfo & clientInfo)
     322              : {
     323           13 :     mpKeyStore->DestroyKey(clientInfo.aes_key_handle);
     324           13 :     mpKeyStore->DestroyKey(clientInfo.hmac_key_handle);
     325           13 : }
     326              : 
     327           24 : CHIP_ERROR DefaultICDClientStorage::SerializeToTlv(TLV::TLVWriter & writer, const std::vector<ICDClientInfo> & clientInfoVector)
     328              : {
     329              :     TLV::TLVType arrayType;
     330           24 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType));
     331           50 :     for (auto & clientInfo : clientInfoVector)
     332              :     {
     333              :         TLV::TLVType ICDClientInfoContainerType;
     334           26 :         ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, ICDClientInfoContainerType));
     335           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kPeerNodeId), clientInfo.peer_node.GetNodeId()));
     336           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kCheckInNodeId), clientInfo.check_in_node.GetNodeId()));
     337           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kFabricIndex), clientInfo.peer_node.GetFabricIndex()));
     338           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kStartICDCounter), clientInfo.start_icd_counter));
     339           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kOffset), clientInfo.offset));
     340           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kMonitoredSubject), clientInfo.monitored_subject));
     341           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kAesKeyHandle), clientInfo.aes_key_handle.OpaqueBytes()));
     342           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle), clientInfo.hmac_key_handle.OpaqueBytes()));
     343           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kClientType), clientInfo.client_type));
     344           26 :         ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType));
     345              :     }
     346           24 :     return writer.EndContainer(arrayType);
     347              : }
     348              : 
     349           36 : bool DefaultICDClientStorage::FabricExists(FabricIndex fabricIndex)
     350              : {
     351           45 :     for (auto & fabric_idx : mFabricList)
     352              :     {
     353           41 :         if (fabric_idx == fabricIndex)
     354              :         {
     355           32 :             return true;
     356              :         }
     357              :     }
     358            4 :     return false;
     359              : }
     360              : 
     361           24 : CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo)
     362              : {
     363           24 :     VerifyOrReturnError(FabricExists(clientInfo.peer_node.GetFabricIndex()), CHIP_ERROR_INVALID_FABRIC_INDEX);
     364           21 :     std::vector<ICDClientInfo> clientInfoVector;
     365           21 :     size_t clientInfoSize = MaxICDClientInfoSize();
     366           21 :     ReturnErrorOnFailure(Load(clientInfo.peer_node.GetFabricIndex(), clientInfoVector, clientInfoSize));
     367              : 
     368           24 :     for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++)
     369              :     {
     370            9 :         if (clientInfo.peer_node.GetNodeId() == it->peer_node.GetNodeId())
     371              :         {
     372            6 :             ReturnErrorOnFailure(DecreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()));
     373            6 :             clientInfoVector.erase(it);
     374            6 :             break;
     375              :         }
     376              :     }
     377           21 :     clientInfoVector.push_back(clientInfo);
     378           21 :     size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead;
     379           21 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     380           21 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     381           21 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     382              : 
     383           21 :     ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector));
     384              : 
     385           21 :     const auto len = writer.GetLengthWritten();
     386           21 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     387              : 
     388           21 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     389           21 :     ReturnErrorOnFailure(mpClientInfoStore->SyncSetKeyValue(
     390              :         DefaultStorageKeyAllocator::ICDClientInfoKey(clientInfo.peer_node.GetFabricIndex()).KeyName(), backingBuffer.Get(),
     391              :         static_cast<uint16_t>(len)));
     392              : 
     393           21 :     ReturnErrorOnFailure(IncreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()));
     394           21 :     ChipLogProgress(ICD,
     395              :                     "Store ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId
     396              :                     " and checkin nodeId " ChipLogFormatScopedNodeId,
     397              :                     ChipLogValueScopedNodeId(clientInfo.peer_node), ChipLogValueScopedNodeId(clientInfo.check_in_node));
     398           21 :     return CHIP_NO_ERROR;
     399           21 : }
     400              : 
     401           21 : CHIP_ERROR DefaultICDClientStorage::IncreaseEntryCountForFabric(FabricIndex fabricIndex)
     402              : {
     403           21 :     return UpdateEntryCountForFabric(fabricIndex, /*increase*/ true);
     404              : }
     405              : 
     406            9 : CHIP_ERROR DefaultICDClientStorage::DecreaseEntryCountForFabric(FabricIndex fabricIndex)
     407              : {
     408            9 :     return UpdateEntryCountForFabric(fabricIndex, /*increase*/ false);
     409              : }
     410              : 
     411           30 : CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabricIndex, bool increase)
     412              : {
     413           30 :     size_t count          = 0;
     414           30 :     size_t clientInfoSize = MaxICDClientInfoSize();
     415           30 :     ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize));
     416           30 :     if (increase)
     417              :     {
     418           21 :         count++;
     419              :     }
     420              :     else
     421              :     {
     422            9 :         count--;
     423              :     }
     424              : 
     425           30 :     size_t total = MaxICDCounterSize();
     426           30 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     427           30 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     428           30 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     429              : 
     430              :     TLV::TLVType structType;
     431           30 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, structType));
     432           30 :     ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kCount), static_cast<uint32_t>(count)));
     433           30 :     ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kSize), static_cast<uint32_t>(clientInfoSize)));
     434           30 :     ReturnErrorOnFailure(writer.EndContainer(structType));
     435              : 
     436           30 :     const auto len = writer.GetLengthWritten();
     437           30 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     438           30 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     439              : 
     440           60 :     return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(),
     441           60 :                                               backingBuffer.Get(), static_cast<uint16_t>(len));
     442           30 : }
     443              : 
     444            4 : CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode)
     445              : {
     446            4 :     VerifyOrReturnError(FabricExists(peerNode.GetFabricIndex()), CHIP_NO_ERROR);
     447            4 :     size_t clientInfoSize = 0;
     448            4 :     std::vector<ICDClientInfo> clientInfoVector;
     449            4 :     ReturnErrorOnFailure(Load(peerNode.GetFabricIndex(), clientInfoVector, clientInfoSize));
     450            4 :     VerifyOrReturnError(clientInfoVector.size() > 0, CHIP_NO_ERROR);
     451              : 
     452            3 :     for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++)
     453              :     {
     454            3 :         if (peerNode.GetNodeId() == it->peer_node.GetNodeId())
     455              :         {
     456            3 :             RemoveKey(*it);
     457            3 :             it = clientInfoVector.erase(it);
     458            3 :             break;
     459              :         }
     460              :     }
     461              : 
     462            3 :     ReturnErrorOnFailure(
     463              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName()));
     464            3 :     size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead;
     465            3 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     466            3 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     467            3 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     468              : 
     469            3 :     ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector));
     470              : 
     471            3 :     const auto len = writer.GetLengthWritten();
     472            3 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     473              : 
     474            3 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     475            3 :     ReturnErrorOnFailure(
     476              :         mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName(),
     477              :                                            backingBuffer.Get(), static_cast<uint16_t>(len)));
     478              : 
     479            3 :     ReturnErrorOnFailure(DecreaseEntryCountForFabric(peerNode.GetFabricIndex()));
     480            3 :     ChipLogProgress(ICD, "Remove ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId,
     481              :                     ChipLogValueScopedNodeId(peerNode));
     482            3 :     return CHIP_NO_ERROR;
     483            4 : }
     484              : 
     485            8 : CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex)
     486              : {
     487            8 :     VerifyOrReturnError(FabricExists(fabricIndex), CHIP_NO_ERROR);
     488              : 
     489            7 :     size_t clientInfoSize = 0;
     490            7 :     std::vector<ICDClientInfo> clientInfoVector;
     491            7 :     ReturnErrorOnFailure(Load(fabricIndex, clientInfoVector, clientInfoSize));
     492              :     IgnoreUnusedVariable(clientInfoSize);
     493           16 :     for (auto & clientInfo : clientInfoVector)
     494              :     {
     495            9 :         RemoveKey(clientInfo);
     496              :     }
     497            7 :     ReturnErrorOnFailure(
     498              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName()));
     499            7 :     ReturnErrorOnFailure(
     500              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName()));
     501              : 
     502            8 :     for (auto fabric = mFabricList.begin(); fabric != mFabricList.end(); fabric++)
     503              :     {
     504            8 :         if (*fabric == fabricIndex)
     505              :         {
     506            7 :             mFabricList.erase(fabric);
     507            7 :             break;
     508              :         }
     509              :     }
     510              : 
     511            7 :     if (mFabricList.size() == 0)
     512              :     {
     513            4 :         return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName());
     514              :     }
     515              : 
     516            3 :     ReturnErrorOnFailure(StoreFabricList());
     517            3 :     ChipLogProgress(ICD, "Remove all ICD entries successfully for fabric index %u", fabricIndex);
     518            3 :     return CHIP_NO_ERROR;
     519            7 : }
     520              : 
     521           15 : CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo,
     522              :                                                           Protocols::SecureChannel::CounterType & counter)
     523              : {
     524              :     uint8_t appDataBuffer[kAppDataLength];
     525           15 :     MutableByteSpan appData(appDataBuffer);
     526           15 :     auto * iterator = IterateICDClientInfo();
     527           15 :     VerifyOrReturnError(iterator != nullptr, CHIP_ERROR_NO_MEMORY);
     528           20 :     while (iterator->Next(clientInfo))
     529              :     {
     530           16 :         CHIP_ERROR err = chip::Protocols::SecureChannel::CheckinMessage::ParseCheckinMessagePayload(
     531           16 :             clientInfo.aes_key_handle, clientInfo.hmac_key_handle, payload, counter, appData);
     532           32 :         if (CHIP_NO_ERROR == err)
     533              :         {
     534           11 :             iterator->Release();
     535           11 :             return CHIP_NO_ERROR;
     536              :         }
     537              :     }
     538            4 :     iterator->Release();
     539            4 :     return CHIP_ERROR_NOT_FOUND;
     540              : }
     541              : 
     542            0 : void DefaultICDClientStorage::Shutdown()
     543              : {
     544            0 :     mICDClientInfoIterators.ReleaseAll();
     545            0 :     mpClientInfoStore = nullptr;
     546            0 :     mpKeyStore        = nullptr;
     547            0 :     mFabricList.clear();
     548            0 : }
     549              : 
     550              : } // namespace app
     551              : } // namespace chip
        

Generated by: LCOV version 2.0-1