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

Generated by: LCOV version 1.14