Matter SDK Coverage Report
Current view: top level - app - TimedHandler.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 87.8 % 49 43
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 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              : #include "TimedHandler.h"
      20              : #include <app/InteractionModelTimeout.h>
      21              : #include <app/MessageDef/TimedRequestMessage.h>
      22              : #include <app/StatusResponse.h>
      23              : #include <lib/core/TLV.h>
      24              : #include <lib/support/logging/CHIPLogging.h>
      25              : #include <system/SystemClock.h>
      26              : #include <system/TLVPacketBufferBackingStore.h>
      27              : 
      28              : namespace chip {
      29              : namespace app {
      30              : 
      31            9 : CHIP_ERROR TimedHandler::OnMessageReceived(Messaging::ExchangeContext * aExchangeContext, const PayloadHeader & aPayloadHeader,
      32              :                                            System::PacketBufferHandle && aPayload)
      33              : {
      34              :     using namespace Protocols::InteractionModel;
      35              : 
      36            9 :     if (aExchangeContext->IsGroupExchangeContext())
      37              :     {
      38              :         // Timed interactions are always supposed to be unicast.  Nothing else
      39              :         // to do here; exchange will close and we'll free ourselves.
      40            0 :         ChipLogError(DataManagement, "Dropping Timed Request on group exchange " ChipLogFormatExchange,
      41              :                      ChipLogValueExchange(aExchangeContext));
      42            0 :         return CHIP_NO_ERROR;
      43              :     }
      44              : 
      45            9 :     if (mState == State::kExpectingTimedAction)
      46              :     {
      47              :         // We were just created; our caller should have done this only if it's
      48              :         // dealing with a Timed Request message.
      49            5 :         VerifyOrDie(aPayloadHeader.HasMessageType(MsgType::TimedRequest));
      50            5 :         mState         = State::kReceivedTimedAction;
      51            5 :         CHIP_ERROR err = HandleTimedRequestAction(aExchangeContext, aPayloadHeader, std::move(aPayload));
      52            5 :         if (err != CHIP_NO_ERROR)
      53              :         {
      54            0 :             ChipLogError(DataManagement, "Failed to parse Timed Request action: handler %p exchange " ChipLogFormatExchange, this,
      55              :                          ChipLogValueExchange(aExchangeContext));
      56            0 :             StatusResponse::Send(Status::InvalidAction, aExchangeContext, /* aExpectResponse = */ false);
      57              :         }
      58            5 :         return err;
      59              :     }
      60              : 
      61            4 :     if (mState == State::kExpectingFollowingAction)
      62              :     {
      63            4 :         System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp();
      64            4 :         ChipLogDetail(DataManagement,
      65              :                       "Timed following action arrived at 0x" ChipLogFormatX64 ": handler %p exchange " ChipLogFormatExchange,
      66              :                       ChipLogValueX64(now.count()), this, ChipLogValueExchange(aExchangeContext));
      67            4 :         if (now > mTimeLimit)
      68              :         {
      69            2 :             ChipLogError(DataManagement, "Timeout expired: handler %p exchange " ChipLogFormatExchange, this,
      70              :                          ChipLogValueExchange(aExchangeContext));
      71            4 :             return StatusResponse::Send(Status::Timeout, aExchangeContext, /* aExpectResponse = */ false);
      72              :         }
      73              : 
      74            2 :         if (aPayloadHeader.HasMessageType(MsgType::InvokeCommandRequest))
      75              :         {
      76            1 :             ChipLogDetail(DataManagement, "Handing timed invoke to IM engine: handler %p exchange " ChipLogFormatExchange, this,
      77              :                           ChipLogValueExchange(aExchangeContext));
      78            1 :             mDelegate->OnTimedInvoke(this, aExchangeContext, aPayloadHeader, std::move(aPayload));
      79            1 :             return CHIP_NO_ERROR;
      80              :         }
      81              : 
      82            1 :         if (aPayloadHeader.HasMessageType(MsgType::WriteRequest))
      83              :         {
      84            1 :             ChipLogDetail(DataManagement, "Handing timed write to IM engine: handler %p exchange " ChipLogFormatExchange, this,
      85              :                           ChipLogValueExchange(aExchangeContext));
      86            1 :             mDelegate->OnTimedWrite(this, aExchangeContext, aPayloadHeader, std::move(aPayload));
      87            1 :             return CHIP_NO_ERROR;
      88              :         }
      89              :     }
      90              : 
      91              :     // Not an expected message.  Send an error response.  The exchange will
      92              :     // close when we return.
      93            0 :     ChipLogError(DataManagement, "Unexpected unknown message in tiemd interaction: handler %p exchange " ChipLogFormatExchange,
      94              :                  this, ChipLogValueExchange(aExchangeContext));
      95              : 
      96            0 :     return StatusResponse::Send(Status::InvalidAction, aExchangeContext, /* aExpectResponse = */ false);
      97              : }
      98              : 
      99            2 : void TimedHandler::OnExchangeClosing(Messaging::ExchangeContext *)
     100              : {
     101            2 :     mDelegate->OnTimedInteractionFailed(this);
     102            2 : }
     103              : 
     104            5 : CHIP_ERROR TimedHandler::HandleTimedRequestAction(Messaging::ExchangeContext * aExchangeContext,
     105              :                                                   const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload)
     106              : {
     107              :     using namespace Protocols::InteractionModel;
     108              : 
     109            5 :     System::PacketBufferTLVReader reader;
     110            5 :     reader.Init(std::move(aPayload));
     111            5 :     TimedRequestMessage::Parser parser;
     112            5 :     ReturnErrorOnFailure(parser.Init(reader));
     113              : 
     114              : #if CHIP_CONFIG_IM_PRETTY_PRINT
     115            5 :     parser.PrettyPrint();
     116              : #endif
     117              : 
     118              :     uint16_t timeoutMs;
     119            5 :     ReturnErrorOnFailure(parser.GetTimeoutMs(&timeoutMs));
     120            5 :     ReturnErrorOnFailure(parser.ExitContainer());
     121              : 
     122            5 :     ChipLogDetail(DataManagement, "Got Timed Request with timeout %u: handler %p exchange " ChipLogFormatExchange, timeoutMs, this,
     123              :                   ChipLogValueExchange(aExchangeContext));
     124              :     // Use at least our default IM timeout, because if we close our exchange as
     125              :     // soon as we know the delay has passed we won't be able to send the
     126              :     // UNSUPPORTED_ACCESS status code the spec tells us to send (and in fact
     127              :     // will send nothing and the other side will have to time out to realize
     128              :     // it's missed its window).
     129            5 :     auto delay = System::Clock::Milliseconds32(timeoutMs);
     130            5 :     aExchangeContext->SetResponseTimeout(
     131           10 :         std::max(delay, aExchangeContext->GetSessionHandle()->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime)));
     132            5 :     ReturnErrorOnFailure(StatusResponse::Send(Status::Success, aExchangeContext, /* aExpectResponse = */ true));
     133              : 
     134              :     // Now just wait for the client.
     135            5 :     mState     = State::kExpectingFollowingAction;
     136            5 :     mTimeLimit = System::SystemClock().GetMonotonicTimestamp() + delay;
     137            5 :     ChipLogDetail(DataManagement, "Timed Request time limit 0x" ChipLogFormatX64 ": handler %p exchange " ChipLogFormatExchange,
     138              :                   ChipLogValueX64(mTimeLimit.count()), this, ChipLogValueExchange(aExchangeContext));
     139            5 :     return CHIP_NO_ERROR;
     140            5 : }
     141              : 
     142              : } // namespace app
     143              : } // namespace chip
        

Generated by: LCOV version 2.0-1