Matter SDK Coverage Report
Current view: top level - controller - InvokeInteraction.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 0.0 % 25 0
Test Date: 2025-01-17 19:00:11 Functions: 0.0 % 71 0

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 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              : #pragma once
      20              : 
      21              : #include <controller/TypedCommandCallback.h>
      22              : #include <lib/core/Optional.h>
      23              : 
      24              : #include <functional>
      25              : 
      26              : namespace chip {
      27              : namespace Controller {
      28              : 
      29              : namespace Internal {
      30              : // Cancellation functions on InvokeCommandRequest() are for internal use only.
      31              : typedef std::function<void()> InvokeCancelFn;
      32              : } // namespace Internal
      33              : 
      34              : /*
      35              :  * A typed command invocation function that takes as input a cluster-object representation of a command request and
      36              :  * callbacks for success and failure and either returns a decoded cluster-object representation of the response through
      37              :  * the provided success callback or calls the provided failure callback.
      38              :  *
      39              :  * The RequestObjectT is generally expected to be a ClusterName::Commands::CommandName::Type struct, but any object
      40              :  * that can be encoded using the DataModel::Encode machinery and exposes the
      41              :  * GetClusterId() and GetCommandId() functions and a ResponseType type
      42              :  * is expected to work.
      43              :  *
      44              :  * The ResponseType is expected to be one of two things:
      45              :  *
      46              :  *    - If a data response is expected on success, a struct type decodable via DataModel::Decode which has GetClusterId() and
      47              :  * GetCommandId() methods.  A ClusterName::Commands::ResponseCommandName::DecodableType is typically used.
      48              :  *    - If a status response is expected on success, DataModel::NullObjectType.
      49              :  *
      50              :  */
      51              : template <typename RequestObjectT>
      52              : CHIP_ERROR
      53            0 : InvokeCommandRequest(Messaging::ExchangeManager * aExchangeMgr, const SessionHandle & sessionHandle, chip::EndpointId endpointId,
      54              :                      const RequestObjectT & requestCommandData,
      55              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnSuccessCallbackType onSuccessCb,
      56              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnErrorCallbackType onErrorCb,
      57              :                      const Optional<uint16_t> & timedInvokeTimeoutMs,
      58              :                      const Optional<System::Clock::Timeout> & responseTimeout = NullOptional,
      59              :                      Internal::InvokeCancelFn * outCancelFn                   = nullptr)
      60              : {
      61              :     // InvokeCommandRequest expects responses, so cannot happen over a group session.
      62            0 :     VerifyOrReturnError(!sessionHandle->IsGroupSession(), CHIP_ERROR_INVALID_ARGUMENT);
      63              : 
      64            0 :     app::CommandPathParams commandPath = { endpointId, 0, RequestObjectT::GetClusterId(), RequestObjectT::GetCommandId(),
      65              :                                            (app::CommandPathFlags::kEndpointIdValid) };
      66              : 
      67              :     //
      68              :     // Let's create a handle version of the decoder to ensure we do correct clean-up of it if things go south at any point below
      69              :     //
      70            0 :     auto decoder = chip::Platform::MakeUnique<TypedCommandCallback<typename RequestObjectT::ResponseType>>(onSuccessCb, onErrorCb);
      71            0 :     VerifyOrReturnError(decoder != nullptr, CHIP_ERROR_NO_MEMORY);
      72              : 
      73              :     //
      74              :     // Upon successful completion of SendCommandRequest below, we're expected to free up the respective allocated objects
      75              :     // in the OnDone callback.
      76              :     //
      77            0 :     auto onDone = [rawDecoderPtr = decoder.get()](app::CommandSender * commandSender) {
      78            0 :         chip::Platform::Delete(commandSender);
      79            0 :         chip::Platform::Delete(rawDecoderPtr);
      80              :     };
      81              : 
      82            0 :     decoder->SetOnDoneCallback(onDone);
      83              : 
      84            0 :     auto commandSender =
      85            0 :         chip::Platform::MakeUnique<app::CommandSender>(decoder.get(), aExchangeMgr, timedInvokeTimeoutMs.HasValue());
      86            0 :     VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY);
      87              : 
      88            0 :     ReturnErrorOnFailure(commandSender->AddRequestData(commandPath, requestCommandData, timedInvokeTimeoutMs));
      89            0 :     ReturnErrorOnFailure(commandSender->SendCommandRequest(sessionHandle, responseTimeout));
      90              : 
      91              :     // If requested by the caller, provide a way to cancel the invoke interaction.
      92            0 :     if (outCancelFn != nullptr)
      93              :     {
      94            0 :         *outCancelFn = [rawDecoderPtr = decoder.get(), rawCommandSender = commandSender.get()]() {
      95            0 :             chip::Platform::Delete(rawCommandSender);
      96            0 :             chip::Platform::Delete(rawDecoderPtr);
      97              :         };
      98              :     }
      99              : 
     100              :     //
     101              :     // We've effectively transferred ownership of the above allocated objects to CommandSender, and we need to wait for it to call
     102              :     // us back when processing is completed (through OnDone) to eventually free up resources.
     103              :     //
     104              :     // So signal that by releasing the smart pointer.
     105              :     //
     106            0 :     decoder.release();
     107            0 :     commandSender.release();
     108              : 
     109            0 :     return CHIP_NO_ERROR;
     110            0 : }
     111              : 
     112              : /*
     113              :  * A typed group command invocation function that takes as input a cluster-object representation of a command request.
     114              :  *
     115              :  * The RequestObjectT is generally expected to be a ClusterName::Commands::CommandName::Type struct, but any object
     116              :  * that can be encoded using the DataModel::Encode machinery and exposes the GetClusterId() and GetCommandId() functions
     117              :  * and a ResponseType type is expected to work.
     118              :  *
     119              :  * Since this sends a group command, no response will be received and all allocated resources will be cleared before exiting this
     120              :  * function
     121              :  */
     122              : template <typename RequestObjectT>
     123              : CHIP_ERROR InvokeGroupCommandRequest(Messaging::ExchangeManager * exchangeMgr, chip::FabricIndex fabric, chip::GroupId groupId,
     124              :                                      const RequestObjectT & requestCommandData)
     125              : {
     126              :     app::CommandPathParams commandPath = { groupId, RequestObjectT::GetClusterId(), RequestObjectT::GetCommandId(),
     127              :                                            app::CommandPathFlags::kGroupIdValid };
     128              :     Transport::OutgoingGroupSession session(groupId, fabric);
     129              : 
     130              :     auto commandSender = chip::Platform::MakeUnique<app::CommandSender>(nullptr, exchangeMgr);
     131              :     VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY);
     132              : 
     133              :     ReturnErrorOnFailure(commandSender->AddRequestData(commandPath, requestCommandData));
     134              :     return commandSender->SendGroupCommandRequest(SessionHandle(session));
     135              : }
     136              : 
     137              : template <typename RequestObjectT>
     138              : CHIP_ERROR
     139              : InvokeCommandRequest(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, chip::EndpointId endpointId,
     140              :                      const RequestObjectT & requestCommandData,
     141              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnSuccessCallbackType onSuccessCb,
     142              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnErrorCallbackType onErrorCb,
     143              :                      uint16_t timedInvokeTimeoutMs, const Optional<System::Clock::Timeout> & responseTimeout = NullOptional)
     144              : {
     145              :     return InvokeCommandRequest(exchangeMgr, sessionHandle, endpointId, requestCommandData, onSuccessCb, onErrorCb,
     146              :                                 MakeOptional(timedInvokeTimeoutMs), responseTimeout);
     147              : }
     148              : 
     149              : template <typename RequestObjectT, typename std::enable_if_t<!RequestObjectT::MustUseTimedInvoke(), int> = 0>
     150              : CHIP_ERROR
     151            0 : InvokeCommandRequest(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, chip::EndpointId endpointId,
     152              :                      const RequestObjectT & requestCommandData,
     153              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnSuccessCallbackType onSuccessCb,
     154              :                      typename TypedCommandCallback<typename RequestObjectT::ResponseType>::OnErrorCallbackType onErrorCb,
     155              :                      const Optional<System::Clock::Timeout> & responseTimeout = NullOptional)
     156              : {
     157            0 :     return InvokeCommandRequest(exchangeMgr, sessionHandle, endpointId, requestCommandData, onSuccessCb, onErrorCb, NullOptional,
     158            0 :                                 responseTimeout);
     159              : }
     160              : 
     161              : } // namespace Controller
     162              : } // namespace chip
        

Generated by: LCOV version 2.0-1