Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faster chip-tool builds. #11699

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ executable("chip-tool") {
"commands/common/CHIPCommand.cpp",
"commands/common/CHIPCommand.h",
"commands/common/Command.cpp",
"commands/common/CommandInvoker.h",
"commands/common/Commands.cpp",
"commands/discover/DiscoverCommand.cpp",
"commands/discover/DiscoverCommissionablesCommand.cpp",
Expand Down
166 changes: 166 additions & 0 deletions examples/chip-tool/commands/common/CommandInvoker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#pragma once

#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandSender.h>
#include <app/DeviceProxy.h>
#include <app/InteractionModelEngine.h>
#include <app/util/error-mapping.h>

namespace chip {
namespace Controller {
namespace detail {
template <typename ResponseType>
class ResponseReceiver : public app::CommandSender::Callback
{
public:
using SuccessCallback = void (*)(void * context, const ResponseType & data);
using FailureCallback = void (*)(void * context, EmberAfStatus status);

virtual ~ResponseReceiver() {}

protected:
ResponseReceiver(void * aContext, SuccessCallback aOnSuccess, FailureCallback aOnError) :
mContext(aContext), mOnSuccess(aOnSuccess), mOnError(aOnError)
{}

inline void OnResponse(app::CommandSender * aCommandSender, const app::ConcreteCommandPath & aPath,
const app::StatusIB & aStatus, TLV::TLVReader * aData) override;

void OnError(const app::CommandSender * aCommandSender, const app::StatusIB & aStatus, CHIP_ERROR aError) override
{
mOnError(mContext, app::ToEmberAfStatus(aStatus.mStatus));
}

void OnDone(app::CommandSender * aCommandSender) override
{
Platform::Delete(aCommandSender);
Platform::Delete(this);
}

private:
void * mContext;
SuccessCallback mOnSuccess;
FailureCallback mOnError;
};

template <typename RequestType>
class CommandInvoker final : public ResponseReceiver<typename RequestType::ResponseType>
{
using Super = ResponseReceiver<typename RequestType::ResponseType>;

public:
CommandInvoker(void * aContext, typename Super::SuccessCallback aOnSuccess, typename Super::FailureCallback aOnError) :
Super(aContext, aOnSuccess, aOnError)
{}

/**
* Use of CommandInvoker looks as follows:
*
* auto invoker = CommandInvoker<type>::Alloc(args);
* VerifyOrReturnError(invoker != nullptr, CHIP_ERROR_NO_MEMORY);
* ReturnErrorOnFailure(invoker->InvokeCommand(args));
* invoker.release(); // The invoker will deallocate itself now.
*/
static auto Alloc(void * aContext, typename Super::SuccessCallback aOnSuccess, typename Super::FailureCallback aOnError)
{
return Platform::MakeUnique<CommandInvoker>(aContext, aOnSuccess, aOnError);
}

CHIP_ERROR InvokeCommand(DeviceProxy * aDevice, EndpointId aEndpoint, const RequestType & aRequestData)
{
app::CommandPathParams commandPath = { aEndpoint, 0, RequestType::GetClusterId(), RequestType::GetCommandId(),
(app::CommandPathFlags::kEndpointIdValid) };
auto commandSender = Platform::MakeUnique<app::CommandSender>(this, aDevice->GetExchangeManager());
VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY);

ReturnErrorOnFailure(commandSender->AddRequestData(commandPath, aRequestData));
ReturnErrorOnFailure(commandSender->SendCommandRequest(aDevice->GetSecureSession().Value()));
commandSender.release();
return CHIP_NO_ERROR;
}
};

template <typename ResponseType>
void ResponseReceiver<ResponseType>::OnResponse(app::CommandSender * aCommandSender, const app::ConcreteCommandPath & aPath,
const app::StatusIB & aStatus, TLV::TLVReader * aData)
{
ResponseType response;
CHIP_ERROR err = CHIP_NO_ERROR;

//
// We're expecting response data in this variant of OnResponse. Consequently, aReader should always be
// non-null. If it is, it means we received a success status code instead, which is not what was expected.
//
VerifyOrExit(aData != nullptr, err = CHIP_ERROR_SCHEMA_MISMATCH);

//
// Validate that the data response we received matches what we expect in terms of its cluster and command IDs.
//
VerifyOrExit(aPath.mClusterId == ResponseType::GetClusterId() && aPath.mCommandId == ResponseType::GetCommandId(),
err = CHIP_ERROR_SCHEMA_MISMATCH);

err = app::DataModel::Decode(*aData, response);
SuccessOrExit(err);

mOnSuccess(mContext, response);

exit:
if (err != CHIP_NO_ERROR)
{
mOnError(mContext, app::ToEmberAfStatus(Protocols::InteractionModel::Status::Failure));
}
}

template <>
inline void ResponseReceiver<app::DataModel::NullObjectType>::OnResponse(app::CommandSender * aCommandSender,
const app::ConcreteCommandPath & aPath,
const app::StatusIB & aStatus, TLV::TLVReader * aData)
{
//
// If we got a valid reader, it means we received response data that we were not expecting to receive.
//
if (aData != nullptr)
{
mOnError(mContext, app::ToEmberAfStatus(Protocols::InteractionModel::Status::Failure));
return;
}

app::DataModel::NullObjectType nullResp;
mOnSuccess(mContext, nullResp);
}

} // namespace detail

template <typename RequestType>
CHIP_ERROR InvokeCommand(DeviceProxy * aDevice, void * aContext,
typename detail::CommandInvoker<RequestType>::SuccessCallback aSuccessCallback,
typename detail::CommandInvoker<RequestType>::FailureCallback aFailureCallback, EndpointId aEndpoint,
const RequestType & aRequestData)
{
auto invoker = detail::CommandInvoker<RequestType>::Alloc(aContext, aSuccessCallback, aFailureCallback);
VerifyOrReturnError(invoker != nullptr, CHIP_ERROR_NO_MEMORY);
ReturnErrorOnFailure(invoker->InvokeCommand(aDevice, aEndpoint, aRequestData));
invoker.release();
return CHIP_NO_ERROR;
}

} // namespace Controller
} // namespace chip
5 changes: 2 additions & 3 deletions examples/chip-tool/templates/commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <app/data-model/DecodableList.h>
#include <app/data-model/Nullable.h>
#include <commands/clusters/ModelCommand.h>
#include <commands/common/CommandInvoker.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/Span.h>
Expand Down Expand Up @@ -411,9 +412,7 @@ public:
{{/if}}
{{/chip_cluster_command_non_expanded_arguments}}

chip::Controller::{{asUpperCamelCase parent.name}}Cluster cluster;
cluster.Associate(device, endpointId);
return cluster.InvokeCommand(mRequest, this, {{#if hasSpecificResponse}}On{{asUpperCamelCase parent.name}}{{asUpperCamelCase response.name}}Success{{else}}OnDefaultSuccess{{/if}}, OnDefaultFailure);
return chip::Controller::InvokeCommand(device, this, {{#if hasSpecificResponse}}On{{asUpperCamelCase parent.name}}{{asUpperCamelCase response.name}}Success{{else}}OnDefaultSuccess{{/if}}, OnDefaultFailure, endpointId, mRequest);
}

private:
Expand Down
10 changes: 6 additions & 4 deletions examples/chip-tool/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ class {{filename}}: public TestCommand

CHIP_ERROR {{>testCommand}}()
{
chip::Controller::{{asUpperCamelCase cluster}}ClusterTest cluster;
cluster.Associate(mDevice, {{endpoint}});

{{#if isCommand}}
using RequestType = chip::app::Clusters::{{asUpperCamelCase cluster}}::Commands::{{asUpperCamelCase command}}::Type;

Expand All @@ -155,8 +152,13 @@ class {{filename}}: public TestCommand
auto failure = [](void * context, EmberAfStatus status) {
(static_cast<{{filename}} *>(context))->OnFailureResponse_{{index}}(status);
};
{{#if async}}ReturnErrorOnFailure({{else}}return {{/if}}cluster.InvokeCommand(request, this, success, failure){{#if async}}){{/if}};

ReturnErrorOnFailure(chip::Controller::InvokeCommand(mDevice, this, success, failure, {{endpoint}}, request));
{{#unless async}}return CHIP_NO_ERROR;{{/unless}}
{{else}}
chip::Controller::{{asUpperCamelCase cluster}}ClusterTest cluster;
cluster.Associate(mDevice, {{endpoint}});

{{#chip_tests_item_parameters}}
{{zapTypeToEncodableClusterObjectType type ns=parent.cluster}} {{asLowerCamelCase name}}Argument;
{{>commandValue ns=parent.cluster container=(concat (asLowerCamelCase name) "Argument") definedValue=definedValue}}
Expand Down
1 change: 1 addition & 0 deletions examples/chip-tool/templates/tests-commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

#include <commands/tests/TestCommand.h>
#include <commands/common/CommandInvoker.h>

{{>test_cluster tests=(getTests)}}

Expand Down
1 change: 0 additions & 1 deletion src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ template("chip_data_model") {
sources += [
"${invoker.zap_pregenerated_dir}/CHIPClusters.cpp",
"${invoker.zap_pregenerated_dir}/CHIPClusters.h",
"${invoker.zap_pregenerated_dir}/CHIPClustersInvoke.cpp",
"${invoker.zap_pregenerated_dir}/attribute-size.cpp",
"${invoker.zap_pregenerated_dir}/callback-stub.cpp",
]
Expand Down
5 changes: 0 additions & 5 deletions src/app/zap-templates/app-templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@
"path": "templates/app/CHIPClusters-src.zapt",
"name": "C++ ZCL API",
"output": "CHIPClusters.cpp"
},
{
"path": "templates/app/CHIPClustersInvoke-src.zapt",
"name": "C++ ZCL Invoke API",
"output": "CHIPClustersInvoke.cpp"
}
]
}
17 changes: 16 additions & 1 deletion src/controller/CHIPCluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,22 @@ class DLL_EXPORT ClusterBase
template <typename RequestDataT>
CHIP_ERROR InvokeCommand(const RequestDataT & requestData, void * context,
CommandResponseSuccessCallback<typename RequestDataT::ResponseType> successCb,
CommandResponseFailureCallback failureCb);
CommandResponseFailureCallback failureCb)
{
VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

auto onSuccessCb = [context, successCb](const app::ConcreteCommandPath & commandPath, const app::StatusIB & aStatus,
const typename RequestDataT::ResponseType & responseData) {
successCb(context, responseData);
};

auto onFailureCb = [context, failureCb](const app::StatusIB & aStatus, CHIP_ERROR aError) {
failureCb(context, app::ToEmberAfStatus(aStatus.mStatus));
};

return InvokeCommandRequest(mDevice->GetExchangeManager(), mDevice->GetSecureSession().Value(), mEndpoint, requestData,
onSuccessCb, onFailureCb);
};

/**
* Functions for writing attributes. We have lots of different
Expand Down
4 changes: 0 additions & 4 deletions src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
1ED276E026C57CF000547A89 /* CHIPCallbackBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1ED276DF26C57CF000547A89 /* CHIPCallbackBridge.mm */; };
1ED276E226C5812A00547A89 /* CHIPCluster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1ED276E126C5812A00547A89 /* CHIPCluster.mm */; };
1ED276E426C5832500547A89 /* CHIPCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ED276E326C5832500547A89 /* CHIPCluster.h */; settings = {ATTRIBUTES = (Public, ); }; };
1EF900A0273AC39C006A4018 /* CHIPClustersInvoke.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EF9009E273AC39C006A4018 /* CHIPClustersInvoke.cpp */; };
2C1B027A2641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C1B02782641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.mm */; };
2C1B027B2641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C1B02792641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.h */; };
2C222AD0255C620600E446B9 /* CHIPDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C222ACE255C620600E446B9 /* CHIPDevice.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -125,7 +124,6 @@
1ED276DF26C57CF000547A89 /* CHIPCallbackBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CHIPCallbackBridge.mm; path = "zap-generated/CHIPCallbackBridge.mm"; sourceTree = "<group>"; };
1ED276E126C5812A00547A89 /* CHIPCluster.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPCluster.mm; sourceTree = "<group>"; };
1ED276E326C5832500547A89 /* CHIPCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPCluster.h; sourceTree = "<group>"; };
1EF9009E273AC39C006A4018 /* CHIPClustersInvoke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CHIPClustersInvoke.cpp; path = "../../../../zzz_generated/controller-clusters/zap-generated/CHIPClustersInvoke.cpp"; sourceTree = "<group>"; };
2C1B02782641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPOperationalCredentialsDelegate.mm; sourceTree = "<group>"; };
2C1B02792641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPOperationalCredentialsDelegate.h; sourceTree = "<group>"; };
2C222ACE255C620600E446B9 /* CHIPDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPDevice.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -224,7 +222,6 @@
1EC4CE5825CC26AB00D7304F /* CHIPGeneratedFiles */ = {
isa = PBXGroup;
children = (
1EF9009E273AC39C006A4018 /* CHIPClustersInvoke.cpp */,
1EC3238C271999E2002A8BF0 /* cluster-objects.cpp */,
1E16A8F926B9835600683C53 /* CHIPTestClustersObjc.h */,
1E16A8FA26B9835700683C53 /* CHIPTestClustersObjc.mm */,
Expand Down Expand Up @@ -520,7 +517,6 @@
B2E0D7B6245B0B5C003C5B48 /* CHIPManualSetupPayloadParser.mm in Sources */,
1E85732826551A490050A4D9 /* attribute-table.cpp in Sources */,
1E85732626551A490050A4D9 /* attribute-storage.cpp in Sources */,
1EF900A0273AC39C006A4018 /* CHIPClustersInvoke.cpp in Sources */,
1E85732C26551A490050A4D9 /* DataModelHandler.cpp in Sources */,
1E85733126551A490050A4D9 /* chip-message-send.cpp in Sources */,
1E85730F265519AE0050A4D9 /* attribute-size.cpp in Sources */,
Expand Down

This file was deleted.

18 changes: 0 additions & 18 deletions zzz_generated/bridge-app/zap-generated/CHIPClustersInvoke.cpp

This file was deleted.

Loading