LCOV - code coverage report
Current view: top level - app - TimedHandler.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 40 51 78.4 %
Date: 2024-02-15 08:20:41 Functions: 3 3 100.0 %

          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/InteractionModelEngine.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           5 : CHIP_ERROR TimedHandler::OnMessageReceived(Messaging::ExchangeContext * aExchangeContext, const PayloadHeader & aPayloadHeader,
      32             :                                            System::PacketBufferHandle && aPayload)
      33             : {
      34             :     using namespace Protocols::InteractionModel;
      35             : 
      36           5 :     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           5 :     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           3 :         VerifyOrDie(aPayloadHeader.HasMessageType(MsgType::TimedRequest));
      50           3 :         mState         = State::kReceivedTimedAction;
      51           3 :         CHIP_ERROR err = HandleTimedRequestAction(aExchangeContext, aPayloadHeader, std::move(aPayload));
      52           3 :         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           3 :         return err;
      59             :     }
      60             : 
      61           2 :     if (mState == State::kExpectingFollowingAction)
      62             :     {
      63           2 :         System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp();
      64           2 :         ChipLogDetail(DataManagement,
      65             :                       "Timed following action arrived at 0x" ChipLogFormatX64 ": handler %p exchange " ChipLogFormatExchange,
      66             :                       ChipLogValueX64(now.count()), this, ChipLogValueExchange(aExchangeContext));
      67           2 :         if (now > mTimeLimit)
      68             :         {
      69             :             // Time is up.  Spec says to send UNSUPPORTED_ACCESS.
      70           1 :             ChipLogError(DataManagement, "Timeout expired: handler %p exchange " ChipLogFormatExchange, this,
      71             :                          ChipLogValueExchange(aExchangeContext));
      72           2 :             return StatusResponse::Send(Status::UnsupportedAccess, aExchangeContext, /* aExpectResponse = */ false);
      73             :         }
      74             : 
      75           1 :         if (aPayloadHeader.HasMessageType(MsgType::InvokeCommandRequest))
      76             :         {
      77           1 :             auto * imEngine = InteractionModelEngine::GetInstance();
      78           1 :             ChipLogDetail(DataManagement, "Handing timed invoke to IM engine: handler %p exchange " ChipLogFormatExchange, this,
      79             :                           ChipLogValueExchange(aExchangeContext));
      80           1 :             imEngine->OnTimedInvoke(this, aExchangeContext, aPayloadHeader, std::move(aPayload));
      81           1 :             return CHIP_NO_ERROR;
      82             :         }
      83             : 
      84           0 :         if (aPayloadHeader.HasMessageType(MsgType::WriteRequest))
      85             :         {
      86           0 :             auto * imEngine = InteractionModelEngine::GetInstance();
      87           0 :             ChipLogDetail(DataManagement, "Handing timed write to IM engine: handler %p exchange " ChipLogFormatExchange, this,
      88             :                           ChipLogValueExchange(aExchangeContext));
      89           0 :             imEngine->OnTimedWrite(this, aExchangeContext, aPayloadHeader, std::move(aPayload));
      90           0 :             return CHIP_NO_ERROR;
      91             :         }
      92             :     }
      93             : 
      94             :     // Not an expected message.  Send an error response.  The exchange will
      95             :     // close when we return.
      96           0 :     ChipLogError(DataManagement, "Unexpected unknown message in tiemd interaction: handler %p exchange " ChipLogFormatExchange,
      97             :                  this, ChipLogValueExchange(aExchangeContext));
      98             : 
      99           0 :     return StatusResponse::Send(Status::InvalidAction, aExchangeContext, /* aExpectResponse = */ false);
     100             : }
     101             : 
     102           1 : void TimedHandler::OnExchangeClosing(Messaging::ExchangeContext *)
     103             : {
     104           1 :     InteractionModelEngine::GetInstance()->OnTimedInteractionFailed(this);
     105           1 : }
     106             : 
     107           3 : CHIP_ERROR TimedHandler::HandleTimedRequestAction(Messaging::ExchangeContext * aExchangeContext,
     108             :                                                   const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload)
     109             : {
     110             :     using namespace Protocols::InteractionModel;
     111             : 
     112           3 :     System::PacketBufferTLVReader reader;
     113           3 :     reader.Init(std::move(aPayload));
     114           3 :     TimedRequestMessage::Parser parser;
     115           3 :     ReturnErrorOnFailure(parser.Init(reader));
     116             : 
     117             : #if CHIP_CONFIG_IM_PRETTY_PRINT
     118           3 :     parser.PrettyPrint();
     119             : #endif
     120             : 
     121             :     uint16_t timeoutMs;
     122           3 :     ReturnErrorOnFailure(parser.GetTimeoutMs(&timeoutMs));
     123           3 :     ReturnErrorOnFailure(parser.ExitContainer());
     124             : 
     125           3 :     ChipLogDetail(DataManagement, "Got Timed Request with timeout %u: handler %p exchange " ChipLogFormatExchange, timeoutMs, this,
     126             :                   ChipLogValueExchange(aExchangeContext));
     127             :     // Use at least our default IM timeout, because if we close our exchange as
     128             :     // soon as we know the delay has passed we won't be able to send the
     129             :     // UNSUPPORTED_ACCESS status code the spec tells us to send (and in fact
     130             :     // will send nothing and the other side will have to time out to realize
     131             :     // it's missed its window).
     132           3 :     auto delay = System::Clock::Milliseconds32(timeoutMs);
     133           3 :     aExchangeContext->SetResponseTimeout(
     134           6 :         std::max(delay, aExchangeContext->GetSessionHandle()->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime)));
     135           3 :     ReturnErrorOnFailure(StatusResponse::Send(Status::Success, aExchangeContext, /* aExpectResponse = */ true));
     136             : 
     137             :     // Now just wait for the client.
     138           3 :     mState     = State::kExpectingFollowingAction;
     139           3 :     mTimeLimit = System::SystemClock().GetMonotonicTimestamp() + delay;
     140           3 :     ChipLogDetail(DataManagement, "Timed Request time limit 0x" ChipLogFormatX64 ": handler %p exchange " ChipLogFormatExchange,
     141             :                   ChipLogValueX64(mTimeLimit.count()), this, ChipLogValueExchange(aExchangeContext));
     142           3 :     return CHIP_NO_ERROR;
     143           3 : }
     144             : 
     145             : } // namespace app
     146             : } // namespace chip

Generated by: LCOV version 1.14