Matter SDK Coverage Report
Current view: top level - app/icd/client - CheckInHandler.cpp (source / functions) Coverage Total Hit
Test: SHA:e98a48c2e59f85a25417956e1d105721433aa5d1 Lines: 87.9 % 58 51
Test Date: 2026-01-09 16:53:50 Functions: 66.7 % 6 4

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2023 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file defines objects for a CHIP ICD handler which handles unsolicited check-in messages.
      22              :  *
      23              :  */
      24              : 
      25              : #include <app/AppConfig.h>
      26              : #include <app/InteractionModelEngine.h>
      27              : #include <app/InteractionModelTimeout.h>
      28              : #include <app/icd/client/CheckInHandler.h>
      29              : #include <app/icd/client/RefreshKeySender.h>
      30              : 
      31              : #include <cinttypes>
      32              : 
      33              : #include <lib/core/Global.h>
      34              : #include <lib/support/CodeUtils.h>
      35              : #include <messaging/Flags.h>
      36              : #include <protocols/Protocols.h>
      37              : 
      38              : #include <protocols/secure_channel/Constants.h>
      39              : 
      40              : using namespace chip::Protocols::SecureChannel;
      41              : 
      42              : namespace chip {
      43              : namespace app {
      44              : 
      45              : inline constexpr uint64_t kCheckInCounterMax = (1ULL << 32);
      46              : inline constexpr uint32_t kKeyRefreshLimit   = (1U << 31);
      47              : 
      48            1 : CheckInHandler::CheckInHandler() {}
      49              : 
      50            1 : CHIP_ERROR CheckInHandler::Init(Messaging::ExchangeManager * exchangeManager, ICDClientStorage * clientStorage,
      51              :                                 CheckInDelegate * delegate, InteractionModelEngine * engine)
      52              : {
      53            1 :     VerifyOrReturnError(exchangeManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      54            1 :     VerifyOrReturnError(clientStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      55            1 :     VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      56            1 :     VerifyOrReturnError(engine != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      57            1 :     VerifyOrReturnError(mpExchangeManager == nullptr, CHIP_ERROR_INCORRECT_STATE);
      58            1 :     VerifyOrReturnError(mpICDClientStorage == nullptr, CHIP_ERROR_INCORRECT_STATE);
      59            1 :     VerifyOrReturnError(mpCheckInDelegate == nullptr, CHIP_ERROR_INCORRECT_STATE);
      60            1 :     VerifyOrReturnError(mpImEngine == nullptr, CHIP_ERROR_INCORRECT_STATE);
      61              : 
      62            1 :     mpExchangeManager  = exchangeManager;
      63            1 :     mpICDClientStorage = clientStorage;
      64            1 :     mpCheckInDelegate  = delegate;
      65            1 :     mpImEngine         = engine;
      66            1 :     return mpExchangeManager->RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::ICD_CheckIn, this);
      67              : }
      68              : 
      69            1 : void CheckInHandler::Shutdown()
      70              : {
      71            1 :     mpICDClientStorage = nullptr;
      72            1 :     mpCheckInDelegate  = nullptr;
      73            1 :     if (mpExchangeManager)
      74              :     {
      75            1 :         TEMPORARY_RETURN_IGNORED mpExchangeManager->UnregisterUnsolicitedMessageHandlerForType(
      76              :             Protocols::SecureChannel::MsgType::ICD_CheckIn);
      77            1 :         mpExchangeManager = nullptr;
      78              :     }
      79            1 : }
      80              : 
      81            0 : CHIP_ERROR CheckInHandler::OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate)
      82              : {
      83              :     // Return error for wrong message type
      84            0 :     VerifyOrReturnError(payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::ICD_CheckIn),
      85              :                         CHIP_ERROR_INVALID_MESSAGE_TYPE);
      86              : 
      87            0 :     newDelegate = this;
      88            0 :     return CHIP_NO_ERROR;
      89              : }
      90              : 
      91            8 : CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
      92              :                                              System::PacketBufferHandle && payload)
      93              : {
      94              :     // If the message type is not ICD_CheckIn, return CHIP_NO_ERROR and exit
      95            8 :     VerifyOrReturnError(payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::ICD_CheckIn), CHIP_NO_ERROR);
      96              : 
      97            8 :     ByteSpan payloadByteSpan{ payload->Start(), payload->DataLength() };
      98            8 :     ICDClientInfo clientInfo;
      99            8 :     CounterType counter = 0;
     100              :     // If the check-in message processing fails, return CHIP_NO_ERROR and exit.
     101            8 :     CHIP_ERROR err = mpICDClientStorage->ProcessCheckInPayload(payloadByteSpan, clientInfo, counter);
     102           16 :     if (CHIP_NO_ERROR != err)
     103              :     {
     104            1 :         ChipLogError(ICD, "ProcessCheckInPayload failed: %" CHIP_ERROR_FORMAT, err.Format());
     105            1 :         return CHIP_NO_ERROR;
     106              :     }
     107            7 :     CounterType receivedCheckInCounterOffset = (counter - clientInfo.start_icd_counter) % kCheckInCounterMax;
     108              : 
     109              :     // Detect duplicate check-in messages and return CHIP_NO_ERROR on receiving a duplicate message
     110            7 :     if (receivedCheckInCounterOffset <= clientInfo.offset)
     111              :     {
     112            1 :         ChipLogError(ICD, "A duplicate check-in message was received and discarded");
     113            1 :         return CHIP_NO_ERROR;
     114              :     }
     115              : 
     116            6 :     clientInfo.offset = receivedCheckInCounterOffset;
     117            6 :     bool refreshKey   = (receivedCheckInCounterOffset > kKeyRefreshLimit);
     118              : 
     119            6 :     if (refreshKey)
     120              :     {
     121            1 :         ChipLogProgress(ICD, "Key Refresh is required");
     122            1 :         RefreshKeySender * refreshKeySender = mpCheckInDelegate->OnKeyRefreshNeeded(clientInfo, mpICDClientStorage);
     123            1 :         if (refreshKeySender == nullptr)
     124              :         {
     125            0 :             ChipLogError(ICD, "Key Refresh failed for node ID:" ChipLogFormatScopedNodeId,
     126              :                          ChipLogValueScopedNodeId(clientInfo.peer_node));
     127            0 :             return CHIP_NO_ERROR;
     128              :         }
     129            1 :         err = refreshKeySender->EstablishSessionToPeer();
     130            2 :         if (CHIP_NO_ERROR != err)
     131              :         {
     132            1 :             ChipLogError(ICD, "CASE session establishment failed with error : %" CHIP_ERROR_FORMAT, err.Format());
     133            1 :             mpCheckInDelegate->OnKeyRefreshDone(refreshKeySender, err);
     134            1 :             return CHIP_NO_ERROR;
     135              :         }
     136              :     }
     137              :     else
     138              :     {
     139            5 :         TEMPORARY_RETURN_IGNORED mpICDClientStorage->StoreEntry(clientInfo);
     140            5 :         mpCheckInDelegate->OnCheckInComplete(clientInfo);
     141              : #if CHIP_CONFIG_ENABLE_READ_CLIENT
     142            5 :         mpImEngine->OnActiveModeNotification(clientInfo.peer_node, clientInfo.monitored_subject);
     143              : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
     144              :     }
     145              : 
     146            5 :     return CHIP_NO_ERROR;
     147            8 : }
     148              : 
     149            0 : void CheckInHandler::OnResponseTimeout(Messaging::ExchangeContext * ec) {}
     150              : 
     151              : } // namespace app
     152              : } // namespace chip
        

Generated by: LCOV version 2.0-1