Matter SDK Coverage Report
Current view: top level - app - CommandHandlerImpl.h (source / functions) Coverage Total Hit
Test: SHA:1ac517d5414e3758d04b2b3ea364eb0de4816de2 Lines: 88.5 % 26 23
Test Date: 2026-02-04 08:12:58 Functions: 84.6 % 13 11

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2020-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              : #pragma once
      18              : 
      19              : #include <app/CommandHandler.h>
      20              : 
      21              : #include <app/CommandHandlerExchangeInterface.h>
      22              : #include <app/CommandHandlerInterface.h>
      23              : #include <app/CommandPathRegistry.h>
      24              : #include <app/MessageDef/InvokeRequestMessage.h>
      25              : #include <app/MessageDef/InvokeResponseMessage.h>
      26              : #include <app/data-model-provider/OperationTypes.h>
      27              : #include <lib/core/TLV.h>
      28              : #include <lib/core/TLVDebug.h>
      29              : #include <lib/support/BitFlags.h>
      30              : #include <lib/support/Scoped.h>
      31              : #include <messaging/ExchangeHolder.h>
      32              : #include <messaging/Flags.h>
      33              : #include <protocols/Protocols.h>
      34              : #include <protocols/interaction_model/Constants.h>
      35              : #include <protocols/interaction_model/StatusCode.h>
      36              : #include <system/SystemPacketBuffer.h>
      37              : #include <system/TLVPacketBufferBackingStore.h>
      38              : 
      39              : namespace chip {
      40              : namespace app {
      41              : 
      42              : class CommandHandlerImpl : public CommandHandler
      43              : {
      44              : public:
      45              :     class Callback
      46              :     {
      47              :     public:
      48          152 :         virtual ~Callback() = default;
      49              : 
      50              :         /*
      51              :          * Method that signals to a registered callback that this object
      52              :          * has completed doing useful work and is now safe for release/destruction.
      53              :          */
      54              :         virtual void OnDone(CommandHandlerImpl & apCommandObj) = 0;
      55              : 
      56              :         /**
      57              :          * Perform pre-validation that the command dispatch can be performed. In particular:
      58              :          *   - check command existence/validity
      59              :          *   - validate ACL
      60              :          *   - validate timed-invoke and fabric-scoped requirements
      61              :          *
      62              :          * Returns Status::Success if the command can be dispatched, otherwise it will
      63              :          * return the status to be forwarded to the client on failure.
      64              :          *
      65              :          * Possible error return codes:
      66              :          *   - UnsupportedEndpoint/UnsupportedCluster/UnsupportedCommand if the command path is invalid
      67              :          *   - NeedsTimedInteraction
      68              :          *   - UnsupportedAccess  (ACL failure or fabric scoped without a valid fabric index)
      69              :          *   - AccessRestricted
      70              :          */
      71              :         virtual Protocols::InteractionModel::Status ValidateCommandCanBeDispatched(const DataModel::InvokeRequest & request) = 0;
      72              : 
      73              :         /*
      74              :          * Upon processing of a CommandDataIB, this method is invoked to dispatch the command
      75              :          * to the right server-side handler provided by the application.
      76              :          */
      77              :         virtual void DispatchCommand(CommandHandlerImpl & apCommandObj, const ConcreteCommandPath & aCommandPath,
      78              :                                      TLV::TLVReader & apPayload) = 0;
      79              :     };
      80              : 
      81              :     struct InvokeResponseParameters
      82              :     {
      83           34 :         InvokeResponseParameters(const ConcreteCommandPath & aRequestCommandPath) : mRequestCommandPath(aRequestCommandPath) {}
      84              : 
      85           31 :         InvokeResponseParameters & SetStartOrEndDataStruct(bool aStartOrEndDataStruct)
      86              :         {
      87           31 :             mStartOrEndDataStruct = aStartOrEndDataStruct;
      88           31 :             return *this;
      89              :         }
      90              : 
      91              :         ConcreteCommandPath mRequestCommandPath;
      92              :         /**
      93              :          * Whether the method this is being provided to should start/end the TLV container for the CommandFields element
      94              :          * within CommandDataIB.
      95              :          */
      96              :         bool mStartOrEndDataStruct = true;
      97              :     };
      98              : 
      99              :     struct TestOnlyOverrides
     100              :     {
     101              :     public:
     102              :         CommandPathRegistry * commandPathRegistry          = nullptr;
     103              :         CommandHandlerExchangeInterface * commandResponder = nullptr;
     104              :     };
     105              : 
     106              :     /*
     107              :      * The callback passed in has to outlive this CommandHandler object.
     108              :      */
     109              :     CommandHandlerImpl(Callback * apCallback);
     110              : 
     111              :     /*
     112              :      * The destructor will also invalidate all Handles created for this CommandHandlerImpl.
     113              :      */
     114              :     virtual ~CommandHandlerImpl();
     115              : 
     116              :     /*
     117              :      * Constructor to override the number of supported paths per invoke and command responder.
     118              :      *
     119              :      * The callback and any pointers passed via TestOnlyOverrides must outlive this
     120              :      * CommandHandlerImpl object.
     121              :      *
     122              :      * For testing purposes.
     123              :      */
     124              :     CommandHandlerImpl(TestOnlyOverrides & aTestOverride, Callback * apCallback);
     125              : 
     126              :     /**************** CommandHandler interface implementation ***********************/
     127              : 
     128              :     using CommandHandler::AddResponseData;
     129              :     using CommandHandler::AddStatus;
     130              :     using CommandHandler::FallibleAddStatus;
     131              : 
     132              :     void FlushAcksRightAwayOnSlowCommand() override;
     133              : 
     134              :     CHIP_ERROR FallibleAddStatus(const ConcreteCommandPath & aRequestCommandPath,
     135              :                                  const Protocols::InteractionModel::ClusterStatusCode & aStatus,
     136              :                                  const char * context = nullptr) override;
     137              :     void AddStatus(const ConcreteCommandPath & aCommandPath, const Protocols::InteractionModel::ClusterStatusCode & aStatus,
     138              :                    const char * context = nullptr) override;
     139              : 
     140              :     CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId,
     141              :                                const DataModel::EncodableToTLV & aEncodable) override;
     142              :     void AddResponse(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId,
     143              :                      const DataModel::EncodableToTLV & aEncodable) override;
     144              : 
     145              :     Access::SubjectDescriptor GetSubjectDescriptor() const override;
     146              :     FabricIndex GetAccessingFabricIndex() const override;
     147              :     bool IsTimedInvoke() const override;
     148              :     Messaging::ExchangeContext * GetExchangeContext() const override;
     149              : 
     150              :     /**************** Implementation-specific logic ***********************/
     151              : 
     152              :     /*
     153              :      * Main entrypoint for this class to handle an InvokeRequestMessage.
     154              :      *
     155              :      * This function MAY call the registered OnDone callback before returning.
     156              :      * To prevent immediate OnDone invocation, callers can wrap their CommandHandlerImpl instance
     157              :      * within a CommandHandler::Handle.
     158              :      *
     159              :      * isTimedInvoke is true if and only if this is part of a Timed Invoke
     160              :      * transaction (i.e. was preceded by a Timed Request).  If we reach here,
     161              :      * the timer verification has already been done.
     162              :      *
     163              :      * commandResponder handles sending InvokeResponses, added by clusters, to the client. The
     164              :      * command responder object must outlive this CommandHandler object. It is only safe to
     165              :      * release after the caller of OnInvokeCommandRequest receives the OnDone callback.
     166              :      */
     167              :     Protocols::InteractionModel::Status OnInvokeCommandRequest(CommandHandlerExchangeInterface & commandResponder,
     168              :                                                                System::PacketBufferHandle && payload, bool isTimedInvoke);
     169              : 
     170              :     /**
     171              :      * Checks that all CommandDataIB within InvokeRequests satisfy the spec's general
     172              :      * constraints for CommandDataIB. Additionally checks that InvokeRequestMessage is
     173              :      * properly formatted.
     174              :      *
     175              :      * This also builds a registry to ensure that all commands can be responded
     176              :      * to with the data required as per spec.
     177              :      */
     178              :     CHIP_ERROR ValidateInvokeRequestMessageAndBuildRegistry(InvokeRequestMessage::Parser & invokeRequestMessage);
     179              : 
     180              :     /**
     181              :      * This adds a new CommandDataIB element into InvokeResponses for the associated
     182              :      * aRequestCommandPath. This adds up until the `CommandFields` element within
     183              :      * `CommandDataIB`.
     184              :      *
     185              :      * This call will fail if CommandHandler is already in the middle of building a
     186              :      * CommandStatusIB or CommandDataIB (i.e. something has called Prepare*, without
     187              :      * calling Finish*), or is already sending InvokeResponseMessage.
     188              :      *
     189              :      * Upon success, the caller is expected to call `FinishCommand` once they have added
     190              :      * all the fields into the CommandFields element of CommandDataIB.
     191              :      *
     192              :      * @param [in] aResponseCommandPath the concrete response path that we are sending to Requester.
     193              :      * @param [in] aPrepareParameters struct containing paramters needs for preparing a command. Data
     194              :      *             such as request path, and whether this method should start the CommandFields element within
     195              :      *             CommandDataIB.
     196              :      */
     197              :     CHIP_ERROR PrepareInvokeResponseCommand(const ConcreteCommandPath & aResponseCommandPath,
     198              :                                             const InvokeResponseParameters & aPrepareParameters);
     199              : 
     200              :     /**
     201              :      * Finishes the CommandDataIB element within the InvokeResponses.
     202              :      *
     203              :      * Caller must have first successfully called `PrepareInvokeResponseCommand`.
     204              :      *
     205              :      * @param [in] aEndDataStruct end the TLV container for the CommandFields element within
     206              :      *             CommandDataIB. This should match the boolean passed into Prepare*.
     207              :      *
     208              :      * @return CHIP_ERROR_INCORRECT_STATE
     209              :      *                      If device has not previously successfully called
     210              :      *                      `PrepareInvokeResponseCommand`.
     211              :      * @return CHIP_ERROR_BUFFER_TOO_SMALL
     212              :      *                      If writing the values needed to finish the InvokeReponseIB
     213              :      *                      with the current contents of the InvokeResponseMessage
     214              :      *                      would exceed the limit. When this error occurs, it is possible
     215              :      *                      we have already closed some of the IB Builders that were
     216              :      *                      previously started in `PrepareInvokeResponseCommand`.
     217              :      * @return CHIP_ERROR_NO_MEMORY
     218              :      *                      If TLVWriter attempted to allocate an output buffer failed due to
     219              :      *                      lack of memory.
     220              :      * @return other        Other TLVWriter related errors. Typically occurs if
     221              :      *                      `GetCommandDataIBTLVWriter()` was called and used incorrectly.
     222              :      */
     223              :     // TODO(#30453): We should be able to eliminate the chances of OOM issues with reserve.
     224              :     // This will be completed in a follow up PR.
     225              :     CHIP_ERROR FinishCommand(bool aEndDataStruct = true);
     226              : 
     227              :     TLV::TLVWriter * GetCommandDataIBTLVWriter();
     228              : 
     229              : #if CHIP_WITH_NLFAULTINJECTION
     230              : 
     231              :     enum class NlFaultInjectionType : uint8_t
     232              :     {
     233              :         SeparateResponseMessages,
     234              :         SeparateResponseMessagesAndInvertedResponseOrder,
     235              :         SkipSecondResponse
     236              :     };
     237              : 
     238              :     /**
     239              :      * @brief Sends InvokeResponseMessages with injected faults for certification testing.
     240              :      *
     241              :      * The Test Harness (TH) uses this to simulate various server response behaviors,
     242              :      * ensuring the Device Under Test (DUT) handles responses per specification.
     243              :      *
     244              :      * This function strictly validates the DUT's InvokeRequestMessage against the test plan.
     245              :      * If deviations occur, the TH terminates with a detailed error message.
     246              :      *
     247              :      * @param commandResponder commandResponder that will send the InvokeResponseMessages to the client.
     248              :      * @param payload Payload of the incoming InvokeRequestMessage from the client.
     249              :      * @param isTimedInvoke Indicates whether the interaction is timed.
     250              :      * @param faultType The specific type of fault to inject into the response.
     251              :      */
     252              :     // TODO(#30453): After refactoring CommandHandler for better unit testability, create a
     253              :     // unit test specifically for the fault injection behavior.
     254              :     void TestOnlyInvokeCommandRequestWithFaultsInjected(CommandHandlerExchangeInterface & commandResponder,
     255              :                                                         System::PacketBufferHandle && payload, bool isTimedInvoke,
     256              :                                                         NlFaultInjectionType faultType);
     257              : #endif // CHIP_WITH_NLFAULTINJECTION
     258              : 
     259              :     /**
     260              :      * Check whether the InvokeRequest we are handling is targeted to a group.
     261              :      */
     262          228 :     bool IsGroupRequest() { return mGroupRequest; }
     263              : 
     264              : protected:
     265              :     // Lifetime management for CommandHandler::Handle
     266              : 
     267              :     void IncrementHoldOff(Handle * apHandle) override;
     268              :     void DecrementHoldOff(Handle * apHandle) override;
     269              : 
     270              : private:
     271              :     friend class TestCommandInteraction;
     272              :     friend class CommandHandler::Handle;
     273              : 
     274              :     enum class State : uint8_t
     275              :     {
     276              :         Idle,                ///< Default state that the object starts out in, where no work has commenced
     277              :         NewResponseMessage,  ///< mInvokeResponseBuilder is ready, with no responses added.
     278              :         Preparing,           ///< We are prepaing the command or status header.
     279              :         AddingCommand,       ///< In the process of adding a command.
     280              :         AddedCommand,        ///< A command has been completely encoded and is awaiting transmission.
     281              :         DispatchResponses,   ///< The command response(s) are being dispatched.
     282              :         AwaitingDestruction, ///< The object has completed its work and is awaiting destruction by the application.
     283              :     };
     284              : 
     285              :     /**
     286              :      * @brief Best effort to add InvokeResponse to InvokeResponseMessage.
     287              :      *
     288              :      * Tries to add response using lambda. Upon failure to add response, attempts
     289              :      * to rollback the InvokeResponseMessage to a known good state. If failure is due
     290              :      * to insufficient space in the current InvokeResponseMessage:
     291              :      *  - Finalizes the current InvokeResponseMessage.
     292              :      *  - Allocates a new InvokeResponseMessage.
     293              :      *  - Reattempts to add the InvokeResponse to the new InvokeResponseMessage.
     294              :      *
     295              :      * @param [in] addResponseFunction A lambda function responsible for adding the
     296              :      *             response to the current InvokeResponseMessage.
     297              :      */
     298              :     template <typename Function>
     299           86 :     CHIP_ERROR TryAddingResponse(Function && addResponseFunction)
     300              :     {
     301              :         // Invalidate any existing rollback backups. The addResponseFunction is
     302              :         // expected to create a new backup during either PrepareInvokeResponseCommand
     303              :         // or PrepareStatus execution. Direct invocation of
     304              :         // CreateBackupForResponseRollback is avoided since the buffer used by
     305              :         // InvokeResponseMessage might not be allocated until a Prepare* function
     306              :         // is called.
     307           86 :         mRollbackBackupValid = false;
     308           86 :         CHIP_ERROR err       = addResponseFunction();
     309          172 :         if (err == CHIP_NO_ERROR)
     310              :         {
     311           81 :             return CHIP_NO_ERROR;
     312              :         }
     313              :         // The error value of RollbackResponse is not important if it fails, we prioritize
     314              :         // conveying the error generated by addResponseFunction to the caller.
     315           10 :         if (RollbackResponse() != CHIP_NO_ERROR)
     316              :         {
     317            0 :             return err;
     318              :         }
     319              :         // If we failed to add a command due to lack of space in the
     320              :         // packet, we will make another attempt to add the response using
     321              :         // an additional InvokeResponseMessage.
     322            8 :         if (mState != State::AddedCommand || err != CHIP_ERROR_NO_MEMORY)
     323              :         {
     324            2 :             return err;
     325              :         }
     326            3 :         ReturnErrorOnFailure(FinalizeInvokeResponseMessageAndPrepareNext());
     327            3 :         err = addResponseFunction();
     328            6 :         if (err != CHIP_NO_ERROR)
     329              :         {
     330              :             // The return value of RollbackResponse is ignored, as we prioritize
     331              :             // conveying the error generated by addResponseFunction to the
     332              :             // caller.
     333            0 :             TEMPORARY_RETURN_IGNORED RollbackResponse();
     334              :         }
     335            3 :         return err;
     336              :     }
     337              : 
     338              :     void MoveToState(const State aTargetState);
     339              :     const char * GetStateStr() const;
     340              : 
     341              :     /**
     342              :      * Create a backup to enable rolling back to the state prior to ResponseData encoding in the event of failure.
     343              :      */
     344              :     void CreateBackupForResponseRollback();
     345              : 
     346              :     /**
     347              :      * Rollback the state to before encoding the current ResponseData (before calling PrepareInvokeResponseCommand / PrepareStatus)
     348              :      *
     349              :      * Requires CreateBackupForResponseRollback to be called at the start of PrepareInvokeResponseCommand / PrepareStatus
     350              :      */
     351              :     CHIP_ERROR RollbackResponse();
     352              : 
     353              :     /*
     354              :      * This forcibly closes the exchange context if a valid one is pointed to. Such a situation does
     355              :      * not arise during normal message processing flows that all normally call Close() above. This can only
     356              :      * arise due to application-initiated destruction of the object when this object is handling receiving/sending
     357              :      * message payloads.
     358              :      */
     359              :     void Abort();
     360              : 
     361              :     /*
     362              :      * Allocates a packet buffer used for encoding an invoke response payload.
     363              :      *
     364              :      * This can be called multiple times safely, as it will only allocate the buffer once for the lifetime
     365              :      * of this object.
     366              :      */
     367              :     CHIP_ERROR AllocateBuffer();
     368              : 
     369              :     /**
     370              :      * This will add a new CommandStatusIB element into InvokeResponses. It will put the
     371              :      * aCommandPath into the CommandPath element within CommandStatusIB.
     372              :      *
     373              :      * This call will fail if CommandHandler is already in the middle of building a
     374              :      * CommandStatusIB or CommandDataIB (i.e. something has called Prepare*, without
     375              :      * calling Finish*), or is already sending InvokeResponseMessage.
     376              :      *
     377              :      * Upon success, the caller is expected to call `FinishStatus` once they have encoded
     378              :      * StatusIB.
     379              :      *
     380              :      * @param [in] aCommandPath the concrete path of the command we are responding to.
     381              :      */
     382              :     CHIP_ERROR PrepareStatus(const ConcreteCommandPath & aCommandPath);
     383              : 
     384              :     /**
     385              :      * Finishes the CommandStatusIB element within the InvokeResponses.
     386              :      *
     387              :      * Caller must have first successfully called `PrepareStatus`.
     388              :      */
     389              :     CHIP_ERROR FinishStatus();
     390              : 
     391              :     CHIP_ERROR PrepareInvokeResponseCommand(const CommandPathRegistryEntry & apCommandPathRegistryEntry,
     392              :                                             const ConcreteCommandPath & aCommandPath, bool aStartDataStruct);
     393              : 
     394           66 :     CHIP_ERROR FinalizeLastInvokeResponseMessage() { return FinalizeInvokeResponseMessage(/* aHasMoreChunks = */ false); }
     395              : 
     396              :     CHIP_ERROR FinalizeInvokeResponseMessageAndPrepareNext();
     397              : 
     398              :     CHIP_ERROR FinalizeInvokeResponseMessage(bool aHasMoreChunks);
     399              : 
     400              :     Protocols::InteractionModel::Status ProcessInvokeRequest(System::PacketBufferHandle && payload, bool isTimedInvoke);
     401              : 
     402              :     /**
     403              :      * Called internally to signal the completion of all work on this object, gracefully close the
     404              :      * exchange (by calling into the base class) and finally, signal to a registerd callback that it's
     405              :      * safe to release this object.
     406              :      */
     407              :     void Close();
     408              : 
     409              :     /**
     410              :      * ProcessCommandDataIB is only called when a unicast invoke command request is received
     411              :      * It requires the endpointId in its command path to be able to dispatch the command
     412              :      */
     413              :     Protocols::InteractionModel::Status ProcessCommandDataIB(CommandDataIB::Parser & aCommandElement);
     414              : 
     415              :     /**
     416              :      * ProcessGroupCommandDataIB is only called when a group invoke command request is received
     417              :      * It doesn't need the endpointId in it's command path since it uses the GroupId in message metadata to find it
     418              :      */
     419              :     Protocols::InteractionModel::Status ProcessGroupCommandDataIB(CommandDataIB::Parser & aCommandElement);
     420              : 
     421              :     CHIP_ERROR TryAddStatusInternal(const ConcreteCommandPath & aCommandPath, const StatusIB & aStatus);
     422              : 
     423              :     CHIP_ERROR AddStatusInternal(const ConcreteCommandPath & aCommandPath, const StatusIB & aStatus);
     424              : 
     425              :     /**
     426              :      * If this function fails, it may leave our TLV buffer in an inconsistent state.
     427              :      * Callers should snapshot as needed before calling this function, and roll back
     428              :      * as needed afterward.
     429              :      *
     430              :      * @param [in] aRequestCommandPath the concrete path of the command we are responding to
     431              :      * @param [in] aResponseCommandId the id of the command to encode
     432              :      * @param [in] aEncodable the data to encode for the given aResponseCommandId
     433              :      */
     434              :     CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId,
     435              :                                   const DataModel::EncodableToTLV & aEncodable);
     436              : 
     437              :     void SetExchangeInterface(CommandHandlerExchangeInterface * commandResponder);
     438              : 
     439          187 :     bool ResponsesAccepted() { return mpResponder != nullptr && !mGroupRequest; }
     440              : 
     441              :     /**
     442              :      * Sets the state flag to keep the information that request we are handling is targeted to a group.
     443              :      */
     444            0 :     void SetGroupRequest(bool isGroupRequest) { mGroupRequest = isGroupRequest; }
     445              : 
     446          155 :     CommandPathRegistry & GetCommandPathRegistry() const { return *mCommandPathRegistry; }
     447              : 
     448           58 :     size_t MaxPathsPerInvoke() const { return mMaxPathsPerInvoke; }
     449              : 
     450              :     void AddToHandleList(Handle * handle);
     451              : 
     452              :     void RemoveFromHandleList(Handle * handle);
     453              : 
     454              :     void InvalidateHandles();
     455              : 
     456            3 :     bool TestOnlyIsInIdleState() const { return mState == State::Idle; }
     457              : 
     458              :     /**
     459              :      * Returns the ExchangeContext, if one is still available, for use during asynchronous
     460              :      * command processing. This is a best-effort accessor with no guarantees that
     461              :      * an ExchangeContext is present once a command has gone async.
     462              :      *
     463              :      * This method exists to prevent use of GetExchangeContext() in async code paths and
     464              :      * must NOT be used by cluster implementations.
     465              :      */
     466              :     Messaging::ExchangeContext * TryGetExchangeContextWhenAsync() const override;
     467              : 
     468              :     Callback * mpCallback = nullptr;
     469              :     InvokeResponseMessage::Builder mInvokeResponseBuilder;
     470              :     TLV::TLVType mDataElementContainerType = TLV::kTLVType_NotSpecified;
     471              :     size_t mPendingWork                    = 0;
     472              :     /* List to store all currently-outstanding Handles for this Command Handler.*/
     473              :     IntrusiveList<Handle> mpHandleList;
     474              : 
     475              :     chip::System::PacketBufferTLVWriter mCommandMessageWriter;
     476              :     TLV::TLVWriter mBackupWriter;
     477              :     size_t mMaxPathsPerInvoke = CHIP_CONFIG_MAX_PATHS_PER_INVOKE;
     478              :     // TODO(#30453): See if we can reduce this size for the default cases
     479              :     // TODO Allow flexibility in registration.
     480              :     BasicCommandPathRegistry<CHIP_CONFIG_MAX_PATHS_PER_INVOKE> mBasicCommandPathRegistry;
     481              :     CommandPathRegistry * mCommandPathRegistry = &mBasicCommandPathRegistry;
     482              :     std::optional<uint16_t> mRefForResponse;
     483              : 
     484              :     CommandHandlerExchangeInterface * mpResponder = nullptr;
     485              : 
     486              :     State mState = State::Idle;
     487              :     State mBackupState;
     488              :     ScopedChangeOnly<bool> mInternalCallToAddResponseData{ false };
     489              :     bool mSuppressResponse                 = false;
     490              :     bool mTimedRequest                     = false;
     491              :     bool mGroupRequest                     = false;
     492              :     bool mBufferAllocated                  = false;
     493              :     bool mReserveSpaceForMoreChunkMessages = false;
     494              :     // TODO(#32486): We should introduce breaking change where calls to add CommandData
     495              :     // need to use AddResponse, and not CommandHandler primitives directly using
     496              :     // GetCommandDataIBTLVWriter.
     497              :     bool mRollbackBackupValid = false;
     498              :     // If mGoneAsync is true, we have finished out initial processing of the
     499              :     // incoming invoke.  After this point, our session could go away at any
     500              :     // time.
     501              :     bool mGoneAsync = false;
     502              : };
     503              : } // namespace app
     504              : } // namespace chip
        

Generated by: LCOV version 2.0-1