LCOV - code coverage report
Current view: top level - app - CommandResponseSender.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 20 31 64.5 %
Date: 2024-02-15 08:20:41 Functions: 11 15 73.3 %

          Line data    Source code
       1             : /*
       2             :  *    Copyright (c) 2024 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             : #pragma once
      19             : 
      20             : #include <app/StatusResponse.h>
      21             : #include <messaging/ExchangeHolder.h>
      22             : #include <system/SystemPacketBuffer.h>
      23             : 
      24             : namespace chip {
      25             : namespace app {
      26             : 
      27             : typedef void (*OnResponseSenderDone)(void * context);
      28             : class CommandHandler;
      29             : 
      30             : /**
      31             :  * Class manages the process of sending `InvokeResponseMessage`(s) back to the initial requester.
      32             :  */
      33             : class CommandResponseSender : public Messaging::ExchangeDelegate
      34             : {
      35             : public:
      36          49 :     CommandResponseSender() : mExchangeCtx(*this) {}
      37             : 
      38             :     CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
      39             :                                  System::PacketBufferHandle && payload) override;
      40             : 
      41             :     void OnResponseTimeout(Messaging::ExchangeContext * ec) override;
      42             : 
      43             :     /**
      44             :      * Gets the inner exchange context object, without ownership.
      45             :      *
      46             :      * WARNING: This is dangerous, since it is directly interacting with the
      47             :      *          exchange being managed automatically by mExchangeCtx and
      48             :      *          if not done carefully, may end up with use-after-free errors.
      49             :      *
      50             :      * @return The inner exchange context, might be nullptr if no
      51             :      *         exchange context has been assigned or the context
      52             :      *         has been released.
      53             :      */
      54             :     Messaging::ExchangeContext * GetExchangeContext() const { return mExchangeCtx.Get(); }
      55             : 
      56             :     /**
      57             :      * @brief Flush acks right now, typically done when processing a slow command
      58             :      */
      59             :     void FlushAcksRightNow()
      60             :     {
      61             :         VerifyOrReturn(mExchangeCtx);
      62             :         auto * msgContext = mExchangeCtx->GetReliableMessageContext();
      63             :         VerifyOrReturn(msgContext != nullptr);
      64             :         msgContext->FlushAcks();
      65             :     }
      66             : 
      67             :     /**
      68             :      * Gets subject descriptor of the exchange.
      69             :      *
      70             :      * WARNING: This method should only be called when the caller is certain the
      71             :      * session has not been evicted.
      72             :      */
      73          81 :     Access::SubjectDescriptor GetSubjectDescriptor() const
      74             :     {
      75          81 :         VerifyOrDie(mExchangeCtx);
      76          81 :         return mExchangeCtx->GetSessionHandle()->GetSubjectDescriptor();
      77             :     }
      78             : 
      79          27 :     bool HasSessionHandle() { return mExchangeCtx && mExchangeCtx->HasSessionHandle(); }
      80             : 
      81           0 :     FabricIndex GetAccessingFabricIndex() const
      82             :     {
      83           0 :         VerifyOrDie(mExchangeCtx);
      84           0 :         return mExchangeCtx->GetSessionHandle()->GetFabricIndex();
      85             :     }
      86             : 
      87          15 :     void SetExchangeContext(Messaging::ExchangeContext * ec) { mExchangeCtx.Grab(ec); }
      88             : 
      89          31 :     void WillSendMessage() { mExchangeCtx->WillSendMessage(); }
      90             : 
      91          38 :     bool IsForGroup()
      92             :     {
      93          38 :         VerifyOrDie(mExchangeCtx);
      94          38 :         return mExchangeCtx->IsGroupExchangeContext();
      95             :     }
      96             : 
      97          56 :     bool HasExchangeContext() { return mExchangeCtx.Get() != nullptr; }
      98             : 
      99           0 :     GroupId GetGroupId()
     100             :     {
     101           0 :         VerifyOrDie(mExchangeCtx);
     102           0 :         return mExchangeCtx->GetSessionHandle()->AsIncomingGroupSession()->GetGroupId();
     103             :     }
     104             : 
     105             :     /**
     106             :      * @brief Initiates the sending of InvokeResponses previously queued using AddInvokeResponseToSend.
     107             :      *
     108             :      * Upon failure, the caller is responsible for closing the exchange appropriately, potentially
     109             :      * by calling `SendStatusResponse`.
     110             :      */
     111             :     CHIP_ERROR StartSendingCommandResponses();
     112             : 
     113           3 :     void SendStatusResponse(Protocols::InteractionModel::Status aStatus)
     114             :     {
     115           3 :         StatusResponse::Send(aStatus, mExchangeCtx.Get(), /*aExpectResponse = */ false);
     116           3 :     }
     117             : 
     118          31 :     bool AwaitingStatusResponse() { return mState == State::AwaitingStatusResponse; }
     119             : 
     120          38 :     void AddInvokeResponseToSend(System::PacketBufferHandle && aPacket)
     121             :     {
     122          38 :         VerifyOrDie(mState == State::ReadyForInvokeResponses);
     123          38 :         mChunks.AddToEnd(std::move(aPacket));
     124          38 :     }
     125             : 
     126             :     /**
     127             :      * @brief Called to indicate that response was dropped
     128             :      */
     129           0 :     void ResponseDropped() { mReportResponseDropped = true; }
     130             : 
     131             :     /**
     132             :      * @brief Registers a callback to be invoked when CommandResponseSender has finished sending responses.
     133             :      */
     134           0 :     void RegisterOnResponseSenderDoneCallback(Callback::Callback<OnResponseSenderDone> * aResponseSenderDoneCallback)
     135             :     {
     136           0 :         VerifyOrDie(!mCloseCalled);
     137           0 :         mResponseSenderDoneCallback = aResponseSenderDoneCallback;
     138           0 :     }
     139             : 
     140             : private:
     141             :     enum class State : uint8_t
     142             :     {
     143             :         ReadyForInvokeResponses, ///< Accepting InvokeResponses to send back to requester.
     144             :         AwaitingStatusResponse,  ///< Awaiting status response from requester, after sending InvokeResponse.
     145             :         AllInvokeResponsesSent,  ///< All InvokeResponses have been sent out.
     146             :     };
     147             : 
     148             :     void MoveToState(const State aTargetState);
     149             :     const char * GetStateStr() const;
     150             : 
     151             :     CHIP_ERROR SendCommandResponse();
     152          83 :     bool HasMoreToSend() { return !mChunks.IsNull() || mReportResponseDropped; }
     153             :     void Close();
     154             : 
     155             :     // A list of InvokeResponseMessages to be sent out by CommandResponseSender.
     156             :     System::PacketBufferHandle mChunks;
     157             : 
     158             :     chip::Callback::Callback<OnResponseSenderDone> * mResponseSenderDoneCallback = nullptr;
     159             :     Messaging::ExchangeHolder mExchangeCtx;
     160             :     State mState = State::ReadyForInvokeResponses;
     161             : 
     162             :     bool mCloseCalled           = false;
     163             :     bool mReportResponseDropped = false;
     164             : };
     165             : 
     166             : } // namespace app
     167             : } // namespace chip

Generated by: LCOV version 1.14