From 8598de13e3dfde173fdc3f39e96dd894cece3560 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Fri, 13 Sep 2024 11:34:59 +0530 Subject: [PATCH 01/11] Regenerate zap for actions cluster --- .../all-clusters-app.matter | 17 ++- .../all-clusters-common/all-clusters-app.zap | 104 +++++++++++++++++- src/app/common/templates/config-data.yaml | 1 + .../app-common/zap-generated/callback.h | 72 ------------ 4 files changed, 117 insertions(+), 77 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 45e58fffca24ea..abf4f302af9edf 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -8170,9 +8170,22 @@ endpoint 1 { server cluster Actions { callback attribute actionList; callback attribute endpointLists; - callback attribute setupURL; + ram attribute setupURL default = "https://example.com"; ram attribute featureMap default = 0; - callback attribute clusterRevision default = 1; + ram attribute clusterRevision default = 1; + + handle command InstantAction; + handle command InstantActionWithTransition; + handle command StartAction; + handle command StartActionWithDuration; + handle command StopAction; + handle command PauseAction; + handle command PauseActionWithDuration; + handle command ResumeAction; + handle command EnableAction; + handle command EnableActionWithDuration; + handle command DisableAction; + handle command DisableActionWithDuration; } server cluster PowerSource { diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index f8e3dbd8806c3f..722ab67f04c2f2 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -7343,6 +7343,104 @@ "define": "ACTIONS_CLUSTER", "side": "server", "enabled": 1, + "commands": [ + { + "name": "InstantAction", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "InstantActionWithTransition", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartAction", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartActionWithDuration", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StopAction", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "PauseAction", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "PauseActionWithDuration", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ResumeAction", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "EnableAction", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "EnableActionWithDuration", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DisableAction", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DisableActionWithDuration", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], "attributes": [ { "name": "ActionList", @@ -7383,10 +7481,10 @@ "side": "server", "type": "long_char_string", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "https://example.com", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -7415,7 +7513,7 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "1", diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 61e7c45582268a..2c7e40e709ea4f 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -47,6 +47,7 @@ CommandHandlerInterfaceOnlyClusters: - Thread Network Directory - Water Heater Management - Water Heater Mode + - Actions # We need a more configurable way of deciding which clusters have which init functions.... # See https://github.com/project-chip/connectedhomeip/issues/4369 diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index dcf1cc651ccc62..16a92c3ca682e0 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -5677,78 +5677,6 @@ bool emberAfLevelControlClusterMoveToClosestFrequencyCallback( bool emberAfAccessControlClusterReviewFabricRestrictionsCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::DecodableType & commandData); -/** - * @brief Actions Cluster InstantAction Command callback (from client) - */ -bool emberAfActionsClusterInstantActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::InstantAction::DecodableType & commandData); -/** - * @brief Actions Cluster InstantActionWithTransition Command callback (from client) - */ -bool emberAfActionsClusterInstantActionWithTransitionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::InstantActionWithTransition::DecodableType & commandData); -/** - * @brief Actions Cluster StartAction Command callback (from client) - */ -bool emberAfActionsClusterStartActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::StartAction::DecodableType & commandData); -/** - * @brief Actions Cluster StartActionWithDuration Command callback (from client) - */ -bool emberAfActionsClusterStartActionWithDurationCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::StartActionWithDuration::DecodableType & commandData); -/** - * @brief Actions Cluster StopAction Command callback (from client) - */ -bool emberAfActionsClusterStopActionCallback(chip::app::CommandHandler * commandObj, - const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::StopAction::DecodableType & commandData); -/** - * @brief Actions Cluster PauseAction Command callback (from client) - */ -bool emberAfActionsClusterPauseActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::PauseAction::DecodableType & commandData); -/** - * @brief Actions Cluster PauseActionWithDuration Command callback (from client) - */ -bool emberAfActionsClusterPauseActionWithDurationCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::PauseActionWithDuration::DecodableType & commandData); -/** - * @brief Actions Cluster ResumeAction Command callback (from client) - */ -bool emberAfActionsClusterResumeActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::ResumeAction::DecodableType & commandData); -/** - * @brief Actions Cluster EnableAction Command callback (from client) - */ -bool emberAfActionsClusterEnableActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::EnableAction::DecodableType & commandData); -/** - * @brief Actions Cluster EnableActionWithDuration Command callback (from client) - */ -bool emberAfActionsClusterEnableActionWithDurationCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::EnableActionWithDuration::DecodableType & commandData); -/** - * @brief Actions Cluster DisableAction Command callback (from client) - */ -bool emberAfActionsClusterDisableActionCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::DisableAction::DecodableType & commandData); -/** - * @brief Actions Cluster DisableActionWithDuration Command callback (from client) - */ -bool emberAfActionsClusterDisableActionWithDurationCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Actions::Commands::DisableActionWithDuration::DecodableType & commandData); /** * @brief Basic Information Cluster MfgSpecificPing Command callback (from client) */ From df8af52135bdaa138906757b2ba0d1a3e7aaf76f Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Fri, 13 Sep 2024 11:36:02 +0530 Subject: [PATCH 02/11] Add generic implementation for action cluster --- .../include/bridged-actions-stub.h | 110 ++++++ .../src/bridged-actions-stub.cpp | 141 +++++--- .../actions-server/actions-server.cpp | 330 ++++++++++++++++++ .../clusters/actions-server/actions-server.h | 108 ++++++ 4 files changed, 635 insertions(+), 54 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h create mode 100644 src/app/clusters/actions-server/actions-server.cpp create mode 100644 src/app/clusters/actions-server/actions-server.h diff --git a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h new file mode 100644 index 00000000000000..2c38869f26802f --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h @@ -0,0 +1,110 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Actions; +using namespace chip::app::Clusters::Actions::Attributes; + +namespace chip { +namespace app { +namespace Clusters { +namespace Actions { +const uint16_t kActionListSize = 3; +const uint16_t kEndpointListSize = 3; +class ActionsDelegateImpl : public Delegate +{ +private: + using ActionListStructType = Structs::ActionStruct::Type; + using EndpointListStructType = Structs::EndpointListStruct::Type; + + const ActionListStructType kActionList[kActionListSize] = { + ActionListStructType{ .actionID = 0, + .name = CharSpan::fromCharString("TurnOnLight"), + .type = ActionTypeEnum::kScene, + .endpointListID = 0, + .supportedCommands = 0, + .state = ActionStateEnum::kInactive }, + + ActionListStructType{ .actionID = 1, + .name = CharSpan::fromCharString("TurnOffLight"), + .type = ActionTypeEnum::kScene, + .endpointListID = 1, + .supportedCommands = 0, + .state = ActionStateEnum::kInactive }, + + ActionListStructType{ .actionID = 2, + .name = CharSpan::fromCharString("ToggleLight"), + .type = ActionTypeEnum::kScene, + .endpointListID = 2, + .supportedCommands = 0, + .state = ActionStateEnum::kInactive }, + }; + + // Dummy endpoint list. + const EndpointId firstEpList[1] = { 0 }; + const EndpointId secondEpList[1] = { 0 }; + const EndpointId thirdEpList[1] = { 0 }; + + const EndpointListStructType kEndpointList[kEndpointListSize] = { + EndpointListStructType{ .endpointListID = 0, + .name = CharSpan::fromCharString("On"), + .type = EndpointListTypeEnum::kOther, + .endpoints = DataModel::List(firstEpList) }, + + EndpointListStructType{ .endpointListID = 1, + .name = CharSpan::fromCharString("Off"), + .type = EndpointListTypeEnum::kOther, + .endpoints = DataModel::List(secondEpList) }, + + EndpointListStructType{ .endpointListID = 2, + .name = CharSpan::fromCharString("Toggle"), + .type = EndpointListTypeEnum::kOther, + .endpoints = DataModel::List(thirdEpList) }, + }; + CHIP_ERROR ReadActionAtIndex(uint16_t index, ActionListStructType & action) override; + CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, EndpointListStructType & epList) override; + CHIP_ERROR FindActionIdInActionList(uint16_t actionId) override; + + Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; + Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId) override; + Status HandleStartAction(uint16_t actionId, Optional invokeId) override; + Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Status HandleStopAction(uint16_t actionId, Optional invokeId) override; + Status HandlePauseAction(uint16_t actionId, Optional invokeId) override; + Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Status HandleResumeAction(uint16_t actionId, Optional invokeId) override; + Status HandleEnableAction(uint16_t actionId, Optional invokeId) override; + Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Status HandleDisableAction(uint16_t actionId, Optional invokeId) override; + Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; +}; +} // namespace Actions +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp index 90d1b9ebd115b0..ab2670f3aa2c8f 100644 --- a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,88 +15,121 @@ * limitations under the License. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Actions; using namespace chip::app::Clusters::Actions::Attributes; -namespace { +CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, ActionListStructType & action) +{ + if (index >= ArraySize(kActionList)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + action.actionID = kActionList[index].actionID; + action.name = kActionList[index].name; + action.type = kActionList[index].type; + action.endpointListID = kActionList[index].endpointListID; + action.supportedCommands = kActionList[index].supportedCommands; + action.state = kActionList[index].state; + return CHIP_NO_ERROR; +} -class ActionsAttrAccess : public AttributeAccessInterface +CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, EndpointListStructType & epList) { -public: - // Register for the Actions cluster on all endpoints. - ActionsAttrAccess() : AttributeAccessInterface(Optional::Missing(), Actions::Id) {} + if (index >= ArraySize(kEndpointList)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + epList.endpointListID = kEndpointList[index].endpointListID; + epList.name = kEndpointList[index].name; + epList.type = kEndpointList[index].type; + epList.endpoints = kEndpointList[index].endpoints; + return CHIP_NO_ERROR; +} - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; +CHIP_ERROR ActionsDelegateImpl::FindActionIdInActionList(uint16_t actionId) +{ + for (uint16_t i = 0; i < kActionListSize; i++) + { + if (kActionList[i].actionID == actionId) + return CHIP_NO_ERROR; + } + return CHIP_ERROR_NOT_FOUND; +} -private: - static constexpr uint16_t ClusterRevision = 1; +Status ActionsDelegateImpl::HandleInstantAction(uint16_t actionId, Optional invokeId) +{ + // Not implemented + return Status::NotFound; +} - CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder); -}; +Status ActionsDelegateImpl::HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, + Optional invokeId) +{ + // Not implemented + return Status::NotFound; +} -constexpr uint16_t ActionsAttrAccess::ClusterRevision; +Status ActionsDelegateImpl::HandleStartAction(uint16_t actionId, Optional invokeId) +{ + // Not implemented + return Status::NotFound; +} + +Status ActionsDelegateImpl::HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) +{ + // Not implemented + return Status::NotFound; +} -CHIP_ERROR ActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) +Status ActionsDelegateImpl::HandleStopAction(uint16_t actionId, Optional invokeId) { - // Just return an empty list - return aEncoder.EncodeEmptyList(); + // Not implemented + return Status::NotFound; } -CHIP_ERROR ActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) +Status ActionsDelegateImpl::HandlePauseAction(uint16_t actionId, Optional invokeId) { - // Just return an empty list - return aEncoder.EncodeEmptyList(); + // Not implemented + return Status::NotFound; } -CHIP_ERROR ActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) +Status ActionsDelegateImpl::HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) { - static const char SetupUrl[] = "https://example.com"; - return aEncoder.Encode(chip::Span(SetupUrl, strlen(SetupUrl))); + // Not implemented + return Status::NotFound; } -CHIP_ERROR ActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder) +Status ActionsDelegateImpl::HandleResumeAction(uint16_t actionId, Optional invokeId) { - return aEncoder.Encode(ClusterRevision); + // Not implemented + return Status::NotFound; } -ActionsAttrAccess gAttrAccess; +Status ActionsDelegateImpl::HandleEnableAction(uint16_t actionId, Optional invokeId) +{ + // Not implemented + return Status::NotFound; +} -CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +Status ActionsDelegateImpl::HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) { - VerifyOrDie(aPath.mClusterId == Actions::Id); + // Not implemented + return Status::NotFound; +} - switch (aPath.mAttributeId) - { - case ActionList::Id: - return ReadActionListAttribute(aPath.mEndpointId, aEncoder); - case EndpointLists::Id: - return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder); - case SetupURL::Id: - return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder); - case ClusterRevision::Id: - return ReadClusterRevision(aPath.mEndpointId, aEncoder); - default: - break; - } - return CHIP_NO_ERROR; +Status ActionsDelegateImpl::HandleDisableAction(uint16_t actionId, Optional invokeId) +{ + // Not implemented + return Status::NotFound; } -} // anonymous namespace -void MatterActionsPluginServerInitCallback() +Status ActionsDelegateImpl::HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) { - AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); + // Not implemented + return Status::NotFound; } diff --git a/src/app/clusters/actions-server/actions-server.cpp b/src/app/clusters/actions-server/actions-server.cpp new file mode 100644 index 00000000000000..3e25d19c3a099d --- /dev/null +++ b/src/app/clusters/actions-server/actions-server.cpp @@ -0,0 +1,330 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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. + */ + +#include "actions-server.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Actions; +using namespace chip::app::Clusters::Actions::Attributes; + +Instance Instance::instance; +Instance * Instance::GetInstance() +{ + return &instance; +} + +CHIP_ERROR Instance::ReadActionListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder) +{ + if (GetInstance()->mDelegate == nullptr) + { + ChipLogError(Zcl, "Actions delegate is null!!!"); + return CHIP_ERROR_INCORRECT_STATE; + } + for (uint16_t i = 0; true; i++) + { + Actions::Structs::ActionStruct::Type action; + + CHIP_ERROR err = GetInstance()->mDelegate->ReadActionAtIndex(i, action); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + + ReturnErrorOnFailure(encoder.Encode(action)); + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Instance::ReadEndpointListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder) +{ + if (GetInstance()->mDelegate == nullptr) + { + ChipLogError(Zcl, "Actions delegate is null!!!"); + return CHIP_ERROR_INCORRECT_STATE; + } + for (uint16_t i = 0; true; i++) + { + Actions::Structs::EndpointListStruct::Type epList; + + CHIP_ERROR err = GetInstance()->mDelegate->ReadEndpointListAtIndex(i, epList); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + + ReturnErrorOnFailure(encoder.Encode(epList)); + } + return CHIP_NO_ERROR; +} + +void Instance::SetDefaultDelegate(Delegate * aDelegate) +{ + if (aDelegate == nullptr) + { + ChipLogError(Zcl, "Cannot set empty delegate!!!"); + return; + } + mDelegate = aDelegate; +} + +CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == Actions::Id); + + switch (aPath.mAttributeId) + { + case ActionList::Id: { + Instance * d = this; + CHIP_ERROR err = + aEncoder.EncodeList([d](const auto & encoder) -> CHIP_ERROR { return d->ReadActionListAttribute(encoder); }); + return err; + } + case EndpointLists::Id: { + Instance * d = this; + CHIP_ERROR err = + aEncoder.EncodeList([d](const auto & encoder) -> CHIP_ERROR { return d->ReadEndpointListAttribute(encoder); }); + return err; + } + default: + break; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Instance::FindActionIdInActionList(uint16_t actionId) +{ + if (GetInstance()->mDelegate == nullptr) + { + ChipLogError(Zcl, "Actions delegate is null!!!"); + return CHIP_ERROR_INCORRECT_STATE; + } + return GetInstance()->mDelegate->FindActionIdInActionList(actionId); +} + +template +void Instance::HandleCommand(HandlerContext & handlerContext, FuncT func) +{ + if (!handlerContext.mCommandHandled && (handlerContext.mRequestPath.mCommandId == RequestT::GetCommandId())) + { + RequestT requestPayload; + + // If the command matches what the caller is looking for, let's mark this as being handled + // even if errors happen after this. This ensures that we don't execute any fall-back strategies + // to handle this command since at this point, the caller is taking responsibility for handling + // the command in its entirety, warts and all. + // + handlerContext.SetCommandHandled(); + + if (DataModel::Decode(handlerContext.mPayload, requestPayload) != CHIP_NO_ERROR) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, + Protocols::InteractionModel::Status::InvalidCommand); + return; + } + + uint16_t actionId = requestPayload.actionID; + CHIP_ERROR err = GetInstance()->FindActionIdInActionList(actionId); + if (err != CHIP_NO_ERROR) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Protocols::InteractionModel::Status::NotFound); + return; + } + + func(handlerContext, requestPayload); + } +} + +void Instance::HandleInstantAction(HandlerContext & ctx, const Commands::InstantAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleInstantAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleInstantActionWithTransition(HandlerContext & ctx, + const Commands::InstantActionWithTransition::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + uint16_t transitionTime = commandData.transitionTime; + Status status = GetInstance()->mDelegate->HandleInstantActionWithTransition(actionId, transitionTime, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleStartAction(HandlerContext & ctx, const Commands::StartAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleStartAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleStartActionWithDuration(HandlerContext & ctx, + const Commands::StartActionWithDuration::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + uint32_t duration = commandData.duration; + Status status = GetInstance()->mDelegate->HandleStartActionWithDuration(actionId, duration, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleStopAction(HandlerContext & ctx, const Commands::StopAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleStopAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandlePauseAction(HandlerContext & ctx, const Commands::PauseAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandlePauseAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandlePauseActionWithDuration(HandlerContext & ctx, + const Commands::PauseActionWithDuration::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + uint32_t duration = commandData.duration; + Status status = GetInstance()->mDelegate->HandlePauseActionWithDuration(actionId, duration, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleResumeAction(HandlerContext & ctx, const Commands::ResumeAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleResumeAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleEnableAction(HandlerContext & ctx, const Commands::EnableAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleEnableAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleEnableActionWithDuration(HandlerContext & ctx, + const Commands::EnableActionWithDuration::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + uint32_t duration = commandData.duration; + Status status = GetInstance()->mDelegate->HandleEnableActionWithDuration(actionId, duration, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleDisableAction(HandlerContext & ctx, const Commands::DisableAction::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + Status status = GetInstance()->mDelegate->HandleDisableAction(actionId, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::HandleDisableActionWithDuration(HandlerContext & ctx, + const Commands::DisableActionWithDuration::DecodableType & commandData) +{ + uint16_t actionId = commandData.actionID; + Optional invokeId = commandData.invokeID; + uint32_t duration = commandData.duration; + Status status = GetInstance()->mDelegate->HandleDisableActionWithDuration(actionId, duration, invokeId); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +void Instance::InvokeCommand(HandlerContext & handlerContext) +{ + switch (handlerContext.mRequestPath.mCommandId) + { + case Actions::Commands::InstantAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleInstantAction(ctx, commandData); }); + return; + case Actions::Commands::InstantActionWithTransition::Id: + HandleCommand( + handlerContext, + [this](HandlerContext & ctx, const auto & commandData) { HandleInstantActionWithTransition(ctx, commandData); }); + return; + case Actions::Commands::StartAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleStartAction(ctx, commandData); }); + return; + case Actions::Commands::StartActionWithDuration::Id: + HandleCommand( + handlerContext, + [this](HandlerContext & ctx, const auto & commandData) { HandleStartActionWithDuration(ctx, commandData); }); + return; + case Actions::Commands::StopAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleStopAction(ctx, commandData); }); + return; + case Actions::Commands::PauseAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandlePauseAction(ctx, commandData); }); + return; + case Actions::Commands::PauseActionWithDuration::Id: + HandleCommand( + handlerContext, + [this](HandlerContext & ctx, const auto & commandData) { HandlePauseActionWithDuration(ctx, commandData); }); + return; + case Actions::Commands::ResumeAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleResumeAction(ctx, commandData); }); + return; + case Actions::Commands::EnableAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleEnableAction(ctx, commandData); }); + return; + case Actions::Commands::EnableActionWithDuration::Id: + HandleCommand( + handlerContext, + [this](HandlerContext & ctx, const auto & commandData) { HandleEnableActionWithDuration(ctx, commandData); }); + return; + case Actions::Commands::DisableAction::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleDisableAction(ctx, commandData); }); + return; + case Actions::Commands::DisableActionWithDuration::Id: + HandleCommand( + handlerContext, + [this](HandlerContext & ctx, const auto & commandData) { HandleDisableActionWithDuration(ctx, commandData); }); + return; + } +} +void MatterActionsPluginServerInitCallback() +{ + AttributeAccessInterfaceRegistry::Instance().Register(Instance::GetInstance()); + CommandHandlerInterfaceRegistry::Instance().RegisterCommandHandler(Instance::GetInstance()); +} diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h new file mode 100644 index 00000000000000..7c7a4f6d80cbe9 --- /dev/null +++ b/src/app/clusters/actions-server/actions-server.h @@ -0,0 +1,108 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::Protocols::InteractionModel; + +namespace chip { +namespace app { +namespace Clusters { +namespace Actions { + +class Delegate; + +class Instance : public AttributeAccessInterface, public CommandHandlerInterface +{ +public: + // Register for the Actions cluster on all endpoints. + Instance() : + AttributeAccessInterface(Optional::Missing(), Actions::Id), + CommandHandlerInterface(Optional::Missing(), Actions::Id) + {} + + static Instance * GetInstance(); + void SetDefaultDelegate(Delegate * aDelegate); + +private: + Delegate * mDelegate; + static Instance instance; + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + + CHIP_ERROR ReadActionListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder); + CHIP_ERROR ReadEndpointListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder); + CHIP_ERROR FindActionIdInActionList(uint16_t actionId); + + // CommandHandlerInterface + template + void HandleCommand(HandlerContext & handlerContext, FuncT func); + + void InvokeCommand(HandlerContext & handlerContext) override; + + void HandleInstantAction(HandlerContext & ctx, const Commands::InstantAction::DecodableType & commandData); + void HandleInstantActionWithTransition(HandlerContext & ctx, + const Commands::InstantActionWithTransition::DecodableType & commandData); + void HandleStartAction(HandlerContext & ctx, const Commands::StartAction::DecodableType & commandData); + void HandleStartActionWithDuration(HandlerContext & ctx, const Commands::StartActionWithDuration::DecodableType & commandData); + void HandleStopAction(HandlerContext & ctx, const Commands::StopAction::DecodableType & commandData); + void HandlePauseAction(HandlerContext & ctx, const Commands::PauseAction::DecodableType & commandData); + void HandlePauseActionWithDuration(HandlerContext & ctx, const Commands::PauseActionWithDuration::DecodableType & commandData); + void HandleResumeAction(HandlerContext & ctx, const Commands::ResumeAction::DecodableType & commandData); + void HandleEnableAction(HandlerContext & ctx, const Commands::EnableAction::DecodableType & commandData); + void HandleEnableActionWithDuration(HandlerContext & ctx, + const Commands::EnableActionWithDuration::DecodableType & commandData); + void HandleDisableAction(HandlerContext & ctx, const Commands::DisableAction::DecodableType & commandData); + void HandleDisableActionWithDuration(HandlerContext & ctx, + const Commands::DisableActionWithDuration::DecodableType & commandData); +}; + +class Delegate +{ +public: + virtual ~Delegate() = default; + + virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, Structs::ActionStruct::Type & action); + virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, Structs::EndpointListStruct::Type & epList); + virtual CHIP_ERROR FindActionIdInActionList(uint16_t actionId); + + virtual Status HandleInstantAction(uint16_t actionId, Optional invokeId); + virtual Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId); + virtual Status HandleStartAction(uint16_t actionId, Optional invokeId); + virtual Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Status HandleStopAction(uint16_t actionId, Optional invokeId); + virtual Status HandlePauseAction(uint16_t actionId, Optional invokeId); + virtual Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Status HandleResumeAction(uint16_t actionId, Optional invokeId); + virtual Status HandleEnableAction(uint16_t actionId, Optional invokeId); + virtual Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Status HandleDisableAction(uint16_t actionId, Optional invokeId); + virtual Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); +}; + +} // namespace Actions +} // namespace Clusters +} // namespace app +} // namespace chip From dbf4a61aafc3cd34089c662d1be195fd01b974d1 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Fri, 13 Sep 2024 11:36:42 +0530 Subject: [PATCH 03/11] Example changes --- examples/all-clusters-app/esp32/main/CMakeLists.txt | 1 + examples/all-clusters-app/esp32/main/main.cpp | 4 +++- examples/bridge-app/esp32/main/main.cpp | 8 -------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 31292543ca5f50..85f655004ec1de 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -83,6 +83,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/group-key-mgmt-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/basic-information" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/bindings" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/actions-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/icd-management-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 6a0d0d389a92e2..e6f211f279b1cb 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,7 @@ AppCallbacks sCallbacks; app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; app::Clusters::ModeSelect::StaticSupportedModesManager sStaticSupportedModesManager; +app::Clusters::Actions::ActionsDelegateImpl sActionsDelegateImpl; constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; @@ -126,9 +128,9 @@ static void InitServer(intptr_t context) app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); app::Clusters::ModeSelect::setSupportedModesManager(&sStaticSupportedModesManager); + app::Clusters::Actions::Instance::GetInstance()->SetDefaultDelegate(&sActionsDelegateImpl); } -// #include #include #include diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index 016b75803cd69b..bbb3d0dab776ba 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -349,14 +349,6 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) } } -bool emberAfActionsClusterInstantActionCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, - const Actions::Commands::InstantAction::DecodableType & commandData) -{ - // No actions are implemented, just return status NotFound. - commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::NotFound); - return true; -} - const EmberAfDeviceType gRootDeviceTypes[] = { { DEVICE_TYPE_ROOT_NODE, DEVICE_VERSION_DEFAULT } }; const EmberAfDeviceType gAggregateNodeDeviceTypes[] = { { DEVICE_TYPE_BRIDGE, DEVICE_VERSION_DEFAULT } }; From 5a96005709f4b8bd245889c9a54dab2a02561779 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Tue, 17 Sep 2024 11:38:52 +0530 Subject: [PATCH 04/11] Add documentation and fix pipeline --- .../clusters/actions-server/actions-server.h | 136 ++++++++++++++++++ src/app/zap_cluster_list.json | 3 +- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index 7c7a4f6d80cbe9..657bd872f69d61 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -84,21 +84,157 @@ class Delegate public: virtual ~Delegate() = default; + /** + * Get the action at the Nth index from list of actions. + * @param index The index of the action to be returned. It is assumed that actions are indexable from 0 and with no gaps. + * @param action A reference to the action struct which copies existing and initialised buffer at index. + * @return Returns a CHIP_NO_ERROR if there was no error and the action was returned successfully. + * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available actions. + */ virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, Structs::ActionStruct::Type & action); + + /** + * Get the EndpointList at the Nth index from list of endpointList. + * @param index The index of the endpointList to be returned. It is assumed that actions are indexable from 0 and with no gaps. + * @param epList A reference to the endpointList struct which copies existing and initialised buffer at index. + * @return Returns a CHIP_NO_ERROR if there was no error and the epList was returned successfully. + * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available endpointList. + */ virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, Structs::EndpointListStruct::Type & epList); + + /** + * Find the action with matching actionId in the list of action. + * @param actionId The action to be find in the list of action. + * @return Returns a CHIP_NO_ERROR if matching action is found. + * CHIP_ERROR_NOT_FOUND if the matching action does not found in the list of action. + */ virtual CHIP_ERROR FindActionIdInActionList(uint16_t actionId); + /** + * On reciept of each and every command, + * if the InvokeID data field is provided by the client when invoking a command, the server SHALL generate a StateChanged event + * when the action changes to a new state or an ActionFailed event when execution of the action fails. + * + * @return If the command refers to an action which currently is not in a state where the command applies, a response SHALL be + * generated with the StatusCode INVALID_COMMAND. + */ + + /** + * When an InstantAction command is recieved, an action (state change) on the involved endpoints shall trigger, + * in a "fire and forget" manner. Afterwards, the action’s state SHALL be Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleInstantAction(uint16_t actionId, Optional invokeId); + + /** + * When an InstantActionWithTransition command is recieved, an action (state change) on the involved endpoints shall trigger, + * with a specified time to transition from the current state to the new state. During the transition, the action’s state SHALL + * be Active. Afterwards, the action’s state SHALL be Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @param transitionTime The time for transition from the current state to the new state. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId); + + /** + * When a StartAction command is recieved, the commencement of an action on the involved endpoints shall trigger. Afterwards, + * the action’s state SHALL be Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleStartAction(uint16_t actionId, Optional invokeId); + + /** + * When a StartActionWithDuration command is recieved, the commencement of an action on the involved endpoints shall trigger, + * and SHALL change the action’s state to Active. After the specified Duration, the action will stop, and the action’s state + * SHALL change to Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @param duration The time for which an action shall be in start state. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + + /** + * When a StopAction command is recieved, the ongoing action on the involved endpoints shall stop. Afterwards, the action’s + * state SHALL be Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleStopAction(uint16_t actionId, Optional invokeId); + + /** + * When a PauseAction command is recieved, the ongoing action on the involved endpoints shall pause and SHALL change the + * action’s state to Paused. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandlePauseAction(uint16_t actionId, Optional invokeId); + + /** + * When a PauseActionWithDuration command is recieved, pauses an ongoing action, and SHALL change the action’s state to Paused. + * After the specified Duration, the ongoing action will be automatically resumed. which SHALL change the action’s state to + * Active. + * + * @param actionId The id of an action on which an action shall takes place. + * @param duration The time for which an action shall be in pause state. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + + /** + * When a ResumeAction command is recieved, the previously paused action shall resume and SHALL change the action’s state to + * Active. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleResumeAction(uint16_t actionId, Optional invokeId); + + /** + * When an EnableAction command is recieved, it enables a certain action or automation. Afterwards, the action’s state SHALL be + * Active. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleEnableAction(uint16_t actionId, Optional invokeId); + + /** + * When an EnableActionWithDuration command is recieved, it enables a certain action or automation, and SHALL change the + * action’s state to be Active. After the specified Duration, the action or automation will stop, and the action’s state SHALL + * change to Disabled. + * + * @param actionId The id of an action on which an action shall takes place. + * @param duration The time for which an action shall be in active state. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + + /** + * When a DisableAction command is recieved, it disables a certain action or automation, and SHALL change the action’s state to + * Inactive. + * + * @param actionId The id of an action on which an action shall takes place. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleDisableAction(uint16_t actionId, Optional invokeId); + + /** + * When a DisableActionWithDuration command is recieved, it disables a certain action or automation, and SHALL change the + * action’s state to Disabled. After the specified Duration, the action or automation will re-start, and the action’s state + * SHALL change to either Inactive or Active, depending on the actions. + * + * @param actionId The id of an action on which an action shall takes place. + * @param duration The time for which an action shall be in disable state. + * @return Returns a Success if an action took place successfully otherwise, suitable error. + */ virtual Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); }; diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index d4c4801058415c..7c877a32065de5 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -320,6 +320,7 @@ "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "WATER_HEATER_MANAGEMENT_CLUSTER": ["water-heater-management-server"], "WATER_HEATER_MODE_CLUSTER": ["mode-base-server"], - "ZONE_MANAGEMENT_CLUSTER": [] + "ZONE_MANAGEMENT_CLUSTER": [], + "ACTIONS_CLUSTER": ["actions-server"] } } From cf546c083b025cf30eab32c28d7b9a52cd367099 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Tue, 17 Sep 2024 17:02:29 +0530 Subject: [PATCH 05/11] Some example changes --- .../include/bridged-actions-stub.h | 30 ++++++++----------- .../src/bridged-actions-stub.cpp | 1 + .../esp32/main/CMakeLists.txt | 1 + .../asr/src/bridged-actions-stub.cpp | 8 ++--- .../bridge-app/linux/bridged-actions-stub.cpp | 8 ++--- .../bridge-app/telink/src/DeviceCallbacks.cpp | 8 ++--- .../actions-server/actions-server.cpp | 1 + .../clusters/actions-server/actions-server.h | 29 ++++++++---------- 8 files changed, 39 insertions(+), 47 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h index 2c38869f26802f..1366f404b98672 100644 --- a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h +++ b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h @@ -25,12 +25,6 @@ #include #include -using namespace chip; -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::Actions; -using namespace chip::app::Clusters::Actions::Attributes; - namespace chip { namespace app { namespace Clusters { @@ -91,18 +85,18 @@ class ActionsDelegateImpl : public Delegate CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, EndpointListStructType & epList) override; CHIP_ERROR FindActionIdInActionList(uint16_t actionId) override; - Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; - Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId) override; - Status HandleStartAction(uint16_t actionId, Optional invokeId) override; - Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; - Status HandleStopAction(uint16_t actionId, Optional invokeId) override; - Status HandlePauseAction(uint16_t actionId, Optional invokeId) override; - Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; - Status HandleResumeAction(uint16_t actionId, Optional invokeId) override; - Status HandleEnableAction(uint16_t actionId, Optional invokeId) override; - Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; - Status HandleDisableAction(uint16_t actionId, Optional invokeId) override; - Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId) override; + Protocols::InteractionModel::Status HandleStartAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleStopAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandlePauseAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleResumeAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandleEnableAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleDisableAction(uint16_t actionId, Optional invokeId) override; + Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; }; } // namespace Actions } // namespace Clusters diff --git a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp index ab2670f3aa2c8f..bd9a588f6047e4 100644 --- a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp @@ -22,6 +22,7 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::Actions; using namespace chip::app::Clusters::Actions::Attributes; +using namespace chip::Protocols::InteractionModel; CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, ActionListStructType & action) { diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt index f82f301e3ae362..39253c24ed3fad 100644 --- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt @@ -94,6 +94,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/resource-monitoring-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/actions-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" ) diff --git a/examples/bridge-app/asr/src/bridged-actions-stub.cpp b/examples/bridge-app/asr/src/bridged-actions-stub.cpp index 73b7e8dd9877a0..d6289a733f2259 100755 --- a/examples/bridge-app/asr/src/bridged-actions-stub.cpp +++ b/examples/bridge-app/asr/src/bridged-actions-stub.cpp @@ -95,7 +95,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -void MatterActionsPluginServerInitCallback(void) -{ - AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -} +//void MatterActionsPluginServerInitCallback(void) +//{ +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +//} diff --git a/examples/bridge-app/linux/bridged-actions-stub.cpp b/examples/bridge-app/linux/bridged-actions-stub.cpp index 580f4f2239bd1a..cca8d38d809c94 100644 --- a/examples/bridge-app/linux/bridged-actions-stub.cpp +++ b/examples/bridge-app/linux/bridged-actions-stub.cpp @@ -131,7 +131,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -void MatterActionsPluginServerInitCallback() -{ - AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -} +//void MatterActionsPluginServerInitCallback() +//{ +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +//} diff --git a/examples/bridge-app/telink/src/DeviceCallbacks.cpp b/examples/bridge-app/telink/src/DeviceCallbacks.cpp index 9e3273e7107472..65218c68295bba 100644 --- a/examples/bridge-app/telink/src/DeviceCallbacks.cpp +++ b/examples/bridge-app/telink/src/DeviceCallbacks.cpp @@ -99,7 +99,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -void MatterActionsPluginServerInitCallback(void) -{ - AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -} +//void MatterActionsPluginServerInitCallback(void) +//{ +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +//} diff --git a/src/app/clusters/actions-server/actions-server.cpp b/src/app/clusters/actions-server/actions-server.cpp index 3e25d19c3a099d..023cbcf9c1a0cd 100644 --- a/src/app/clusters/actions-server/actions-server.cpp +++ b/src/app/clusters/actions-server/actions-server.cpp @@ -30,6 +30,7 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::Actions; using namespace chip::app::Clusters::Actions::Attributes; +using namespace chip::Protocols::InteractionModel; Instance Instance::instance; Instance * Instance::GetInstance() diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index 657bd872f69d61..e4d65a803e8a8e 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -22,11 +22,6 @@ #include #include -using namespace chip; -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::Protocols::InteractionModel; - namespace chip { namespace app { namespace Clusters { @@ -126,7 +121,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleInstantAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId); /** * When an InstantActionWithTransition command is recieved, an action (state change) on the involved endpoints shall trigger, @@ -137,7 +132,7 @@ class Delegate * @param transitionTime The time for transition from the current state to the new state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId); /** * When a StartAction command is recieved, the commencement of an action on the involved endpoints shall trigger. Afterwards, @@ -146,7 +141,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleStartAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStartAction(uint16_t actionId, Optional invokeId); /** * When a StartActionWithDuration command is recieved, the commencement of an action on the involved endpoints shall trigger, @@ -157,7 +152,7 @@ class Delegate * @param duration The time for which an action shall be in start state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); /** * When a StopAction command is recieved, the ongoing action on the involved endpoints shall stop. Afterwards, the action’s @@ -166,7 +161,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleStopAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStopAction(uint16_t actionId, Optional invokeId); /** * When a PauseAction command is recieved, the ongoing action on the involved endpoints shall pause and SHALL change the @@ -175,7 +170,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandlePauseAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandlePauseAction(uint16_t actionId, Optional invokeId); /** * When a PauseActionWithDuration command is recieved, pauses an ongoing action, and SHALL change the action’s state to Paused. @@ -186,7 +181,7 @@ class Delegate * @param duration The time for which an action shall be in pause state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); /** * When a ResumeAction command is recieved, the previously paused action shall resume and SHALL change the action’s state to @@ -195,7 +190,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleResumeAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleResumeAction(uint16_t actionId, Optional invokeId); /** * When an EnableAction command is recieved, it enables a certain action or automation. Afterwards, the action’s state SHALL be @@ -204,7 +199,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleEnableAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleEnableAction(uint16_t actionId, Optional invokeId); /** * When an EnableActionWithDuration command is recieved, it enables a certain action or automation, and SHALL change the @@ -215,7 +210,7 @@ class Delegate * @param duration The time for which an action shall be in active state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); /** * When a DisableAction command is recieved, it disables a certain action or automation, and SHALL change the action’s state to @@ -224,7 +219,7 @@ class Delegate * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleDisableAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleDisableAction(uint16_t actionId, Optional invokeId); /** * When a DisableActionWithDuration command is recieved, it disables a certain action or automation, and SHALL change the @@ -235,7 +230,7 @@ class Delegate * @param duration The time for which an action shall be in disable state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); }; } // namespace Actions From 4b78081f0262b567cd20742f9c5039ccfa8c996f Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Tue, 24 Sep 2024 17:00:52 +0530 Subject: [PATCH 06/11] Add comment about scope of name --- src/app/clusters/actions-server/actions-server.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index e4d65a803e8a8e..03bdb38754e08f 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -82,7 +82,10 @@ class Delegate /** * Get the action at the Nth index from list of actions. * @param index The index of the action to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param action A reference to the action struct which copies existing and initialised buffer at index. + * @param action A reference to the action struct which copies existing initialised buffer at index. + * Name field (CharSpan) of ActionStruct contails the name of an action. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. * @return Returns a CHIP_NO_ERROR if there was no error and the action was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available actions. */ @@ -91,7 +94,10 @@ class Delegate /** * Get the EndpointList at the Nth index from list of endpointList. * @param index The index of the endpointList to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param epList A reference to the endpointList struct which copies existing and initialised buffer at index. + * @param epList A reference to the endpointList struct which copies existing initialised buffer at index. + * Name field (CharSpan) of EndpointList contails the name of an endpointList. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. * @return Returns a CHIP_NO_ERROR if there was no error and the epList was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available endpointList. */ From 895d829de5a6bc3edc73fb2aec548eec3d92846f Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 24 Sep 2024 11:31:23 +0000 Subject: [PATCH 07/11] Restyled by clang-format --- .../include/bridged-actions-stub.h | 15 ++++++++++----- .../bridge-app/asr/src/bridged-actions-stub.cpp | 6 +++--- .../bridge-app/linux/bridged-actions-stub.cpp | 6 +++--- .../bridge-app/telink/src/DeviceCallbacks.cpp | 6 +++--- .../linux/src/bridged-actions-stub.cpp | 8 ++++---- src/app/clusters/actions-server/actions-server.h | 15 ++++++++++----- 6 files changed, 33 insertions(+), 23 deletions(-) mode change 100755 => 100644 examples/bridge-app/asr/src/bridged-actions-stub.cpp diff --git a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h index 1366f404b98672..6c1a5c65fd8f20 100644 --- a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h +++ b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h @@ -86,17 +86,22 @@ class ActionsDelegateImpl : public Delegate CHIP_ERROR FindActionIdInActionList(uint16_t actionId) override; Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; - Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId) override; + Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, + Optional invokeId) override; Protocols::InteractionModel::Status HandleStartAction(uint16_t actionId, Optional invokeId) override; - Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId) override; Protocols::InteractionModel::Status HandleStopAction(uint16_t actionId, Optional invokeId) override; Protocols::InteractionModel::Status HandlePauseAction(uint16_t actionId, Optional invokeId) override; - Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId) override; Protocols::InteractionModel::Status HandleResumeAction(uint16_t actionId, Optional invokeId) override; Protocols::InteractionModel::Status HandleEnableAction(uint16_t actionId, Optional invokeId) override; - Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId) override; Protocols::InteractionModel::Status HandleDisableAction(uint16_t actionId, Optional invokeId) override; - Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId) override; + Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId) override; }; } // namespace Actions } // namespace Clusters diff --git a/examples/bridge-app/asr/src/bridged-actions-stub.cpp b/examples/bridge-app/asr/src/bridged-actions-stub.cpp old mode 100755 new mode 100644 index d6289a733f2259..84dca65f832107 --- a/examples/bridge-app/asr/src/bridged-actions-stub.cpp +++ b/examples/bridge-app/asr/src/bridged-actions-stub.cpp @@ -95,7 +95,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -//void MatterActionsPluginServerInitCallback(void) +// void MatterActionsPluginServerInitCallback(void) //{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -//} +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +// } diff --git a/examples/bridge-app/linux/bridged-actions-stub.cpp b/examples/bridge-app/linux/bridged-actions-stub.cpp index cca8d38d809c94..0eff1e7b6d05bc 100644 --- a/examples/bridge-app/linux/bridged-actions-stub.cpp +++ b/examples/bridge-app/linux/bridged-actions-stub.cpp @@ -131,7 +131,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -//void MatterActionsPluginServerInitCallback() +// void MatterActionsPluginServerInitCallback() //{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -//} +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +// } diff --git a/examples/bridge-app/telink/src/DeviceCallbacks.cpp b/examples/bridge-app/telink/src/DeviceCallbacks.cpp index 65218c68295bba..8511d7047dfb0a 100644 --- a/examples/bridge-app/telink/src/DeviceCallbacks.cpp +++ b/examples/bridge-app/telink/src/DeviceCallbacks.cpp @@ -99,7 +99,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -//void MatterActionsPluginServerInitCallback(void) +// void MatterActionsPluginServerInitCallback(void) //{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -//} +// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +// } diff --git a/examples/placeholder/linux/src/bridged-actions-stub.cpp b/examples/placeholder/linux/src/bridged-actions-stub.cpp index d7abf17cd9106e..ad934cc881077c 100644 --- a/examples/placeholder/linux/src/bridged-actions-stub.cpp +++ b/examples/placeholder/linux/src/bridged-actions-stub.cpp @@ -96,7 +96,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -void MatterActionsPluginServerInitCallback(void) -{ - chip::app::AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -} +// void MatterActionsPluginServerInitCallback(void) +//{ +// chip::app::AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +// } diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index 03bdb38754e08f..f702069cfa68b7 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -138,7 +138,8 @@ class Delegate * @param transitionTime The time for transition from the current state to the new state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, + Optional invokeId); /** * When a StartAction command is recieved, the commencement of an action on the involved endpoints shall trigger. Afterwards, @@ -158,7 +159,8 @@ class Delegate * @param duration The time for which an action shall be in start state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId); /** * When a StopAction command is recieved, the ongoing action on the involved endpoints shall stop. Afterwards, the action’s @@ -187,7 +189,8 @@ class Delegate * @param duration The time for which an action shall be in pause state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId); /** * When a ResumeAction command is recieved, the previously paused action shall resume and SHALL change the action’s state to @@ -216,7 +219,8 @@ class Delegate * @param duration The time for which an action shall be in active state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId); /** * When a DisableAction command is recieved, it disables a certain action or automation, and SHALL change the action’s state to @@ -236,7 +240,8 @@ class Delegate * @param duration The time for which an action shall be in disable state. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, + Optional invokeId); }; } // namespace Actions From 08dd94307c9347b1e978c64c28ac884197dde9be Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Fri, 4 Oct 2024 13:09:42 +0530 Subject: [PATCH 08/11] Add generic struct to copy the ActionStruct and EndpointListStruct along with name buffer and added events --- .../include/bridged-actions-stub.h | 55 +++------ .../src/bridged-actions-stub.cpp | 16 +-- .../actions-server/actions-server.cpp | 34 +++++- .../clusters/actions-server/actions-server.h | 115 ++++++++++++++++-- 4 files changed, 156 insertions(+), 64 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h index 6c1a5c65fd8f20..91c9999d7cf90d 100644 --- a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h +++ b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h @@ -34,30 +34,10 @@ const uint16_t kEndpointListSize = 3; class ActionsDelegateImpl : public Delegate { private: - using ActionListStructType = Structs::ActionStruct::Type; - using EndpointListStructType = Structs::EndpointListStruct::Type; - - const ActionListStructType kActionList[kActionListSize] = { - ActionListStructType{ .actionID = 0, - .name = CharSpan::fromCharString("TurnOnLight"), - .type = ActionTypeEnum::kScene, - .endpointListID = 0, - .supportedCommands = 0, - .state = ActionStateEnum::kInactive }, - - ActionListStructType{ .actionID = 1, - .name = CharSpan::fromCharString("TurnOffLight"), - .type = ActionTypeEnum::kScene, - .endpointListID = 1, - .supportedCommands = 0, - .state = ActionStateEnum::kInactive }, - - ActionListStructType{ .actionID = 2, - .name = CharSpan::fromCharString("ToggleLight"), - .type = ActionTypeEnum::kScene, - .endpointListID = 2, - .supportedCommands = 0, - .state = ActionStateEnum::kInactive }, + const GenericActionStruct kActionList[kActionListSize] = { + GenericActionStruct(0, CharSpan::fromCharString("TurnOnLight"), ActionTypeEnum::kScene, 0, 0, ActionStateEnum::kInactive), + GenericActionStruct(1, CharSpan::fromCharString("TurnOffLight"), ActionTypeEnum::kScene, 1, 0, ActionStateEnum::kInactive), + GenericActionStruct(2, CharSpan::fromCharString("ToggleLight"), ActionTypeEnum::kScene, 2, 0, ActionStateEnum::kInactive), }; // Dummy endpoint list. @@ -65,24 +45,17 @@ class ActionsDelegateImpl : public Delegate const EndpointId secondEpList[1] = { 0 }; const EndpointId thirdEpList[1] = { 0 }; - const EndpointListStructType kEndpointList[kEndpointListSize] = { - EndpointListStructType{ .endpointListID = 0, - .name = CharSpan::fromCharString("On"), - .type = EndpointListTypeEnum::kOther, - .endpoints = DataModel::List(firstEpList) }, - - EndpointListStructType{ .endpointListID = 1, - .name = CharSpan::fromCharString("Off"), - .type = EndpointListTypeEnum::kOther, - .endpoints = DataModel::List(secondEpList) }, - - EndpointListStructType{ .endpointListID = 2, - .name = CharSpan::fromCharString("Toggle"), - .type = EndpointListTypeEnum::kOther, - .endpoints = DataModel::List(thirdEpList) }, + const GenericEndpointList kEndpointList[kEndpointListSize] = { + GenericEndpointList(0, CharSpan::fromCharString("On"), EndpointListTypeEnum::kOther, + DataModel::List(firstEpList)), + GenericEndpointList(1, CharSpan::fromCharString("Off"), EndpointListTypeEnum::kOther, + DataModel::List(secondEpList)), + GenericEndpointList(2, CharSpan::fromCharString("Toggle"), EndpointListTypeEnum::kOther, + DataModel::List(thirdEpList)), }; - CHIP_ERROR ReadActionAtIndex(uint16_t index, ActionListStructType & action) override; - CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, EndpointListStructType & epList) override; + + CHIP_ERROR ReadActionAtIndex(uint16_t index, GenericActionStruct & action) override; + CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList) override; CHIP_ERROR FindActionIdInActionList(uint16_t actionId) override; Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; diff --git a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp index bd9a588f6047e4..e7f0dd701015b3 100644 --- a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp @@ -24,31 +24,23 @@ using namespace chip::app::Clusters::Actions; using namespace chip::app::Clusters::Actions::Attributes; using namespace chip::Protocols::InteractionModel; -CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, ActionListStructType & action) +CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, GenericActionStruct & action) { if (index >= ArraySize(kActionList)) { return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; } - action.actionID = kActionList[index].actionID; - action.name = kActionList[index].name; - action.type = kActionList[index].type; - action.endpointListID = kActionList[index].endpointListID; - action.supportedCommands = kActionList[index].supportedCommands; - action.state = kActionList[index].state; + action = kActionList[index]; return CHIP_NO_ERROR; } -CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, EndpointListStructType & epList) +CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList) { if (index >= ArraySize(kEndpointList)) { return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; } - epList.endpointListID = kEndpointList[index].endpointListID; - epList.name = kEndpointList[index].name; - epList.type = kEndpointList[index].type; - epList.endpoints = kEndpointList[index].endpoints; + epList = kEndpointList[index]; return CHIP_NO_ERROR; } diff --git a/src/app/clusters/actions-server/actions-server.cpp b/src/app/clusters/actions-server/actions-server.cpp index 023cbcf9c1a0cd..3945903b85d410 100644 --- a/src/app/clusters/actions-server/actions-server.cpp +++ b/src/app/clusters/actions-server/actions-server.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,35 @@ Instance * Instance::GetInstance() return &instance; } +void Instance::OnStateChanged(EndpointId endpoint, uint16_t actionId, uint32_t invokeId, ActionStateEnum actionState) +{ + ChipLogProgress(Zcl, "ActionsServer: OnStateChanged"); + + // Record StateChanged event + EventNumber eventNumber; + Events::StateChanged::Type event{ actionId, invokeId, actionState }; + + if (CHIP_NO_ERROR != LogEvent(event, endpoint, eventNumber)) + { + ChipLogError(Zcl, "ActionsServer: Failed to record OnStateChanged event"); + } +} + +void Instance::OnActionFailed(EndpointId endpoint, uint16_t actionId, uint32_t invokeId, ActionStateEnum actionState, + ActionErrorEnum actionError) +{ + ChipLogProgress(Zcl, "ActionsServer: OnActionFailed"); + + // Record ActionFailed event + EventNumber eventNumber; + Events::ActionFailed::Type event{ actionId, invokeId, actionState, actionError }; + + if (CHIP_NO_ERROR != LogEvent(event, endpoint, eventNumber)) + { + ChipLogError(Zcl, "ActionsServer: Failed to record OnActionFailed event"); + } +} + CHIP_ERROR Instance::ReadActionListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder) { if (GetInstance()->mDelegate == nullptr) @@ -47,7 +77,7 @@ CHIP_ERROR Instance::ReadActionListAttribute(const AttributeValueEncoder::ListEn } for (uint16_t i = 0; true; i++) { - Actions::Structs::ActionStruct::Type action; + GenericActionStruct action; CHIP_ERROR err = GetInstance()->mDelegate->ReadActionAtIndex(i, action); if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) @@ -69,7 +99,7 @@ CHIP_ERROR Instance::ReadEndpointListAttribute(const AttributeValueEncoder::List } for (uint16_t i = 0; true; i++) { - Actions::Structs::EndpointListStruct::Type epList; + GenericEndpointList epList; CHIP_ERROR err = GetInstance()->mDelegate->ReadEndpointListAtIndex(i, epList); if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index f702069cfa68b7..d081bdfd6c44e0 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -27,8 +27,94 @@ namespace app { namespace Clusters { namespace Actions { +inline constexpr size_t kActionNameMaxSize = 128u; +inline constexpr size_t kEndpointListNameMaxSize = 128u; + class Delegate; +struct GenericActionStruct : public Structs::ActionStruct::Type +{ + GenericActionStruct(){}; + + GenericActionStruct(uint16_t action, CharSpan label, ActionTypeEnum actionType, uint16_t epListID, + BitMask commands, ActionStateEnum actionState) + { + Set(action, label, actionType, epListID, commands, actionState); + } + + GenericActionStruct(const GenericActionStruct & action) { *this = action; } + + GenericActionStruct & operator=(const GenericActionStruct & action) + { + Set(action.actionID, action.name, action.type, action.endpointListID, action.supportedCommands, action.state); + return *this; + } + + void Set(uint16_t action, CharSpan label, ActionTypeEnum actionType, uint16_t epListID, BitMask commands, + ActionStateEnum actionState) + { + actionID = action; + type = actionType; + endpointListID = epListID; + supportedCommands = commands; + state = actionState; + memset(mActionNameBuffer, 0, sizeof(mActionNameBuffer)); + if (label.size() > sizeof(mActionNameBuffer)) + { + memcpy(mActionNameBuffer, label.data(), sizeof(mActionNameBuffer)); + name = CharSpan(mActionNameBuffer, sizeof(mActionNameBuffer)); + } + else + { + memcpy(mActionNameBuffer, label.data(), label.size()); + name = CharSpan(mActionNameBuffer, label.size()); + } + } + +private: + char mActionNameBuffer[kActionNameMaxSize]; +}; + +struct GenericEndpointList : public Structs::EndpointListStruct::Type +{ + GenericEndpointList(){}; + + GenericEndpointList(uint16_t epListId, CharSpan label, EndpointListTypeEnum epListType, + DataModel::List endpointList) + { + Set(epListId, label, epListType, endpointList); + } + + GenericEndpointList(const GenericEndpointList & epList) { *this = epList; } + + GenericEndpointList & operator=(const GenericEndpointList & epList) + { + Set(epList.endpointListID, epList.name, epList.type, epList.endpoints); + return *this; + } + + void Set(uint16_t epListId, CharSpan label, EndpointListTypeEnum epListType, DataModel::List endpointList) + { + endpointListID = epListId; + type = epListType; + endpoints = endpointList; + memset(mEndpointListNameBuffer, 0, sizeof(mEndpointListNameBuffer)); + if (label.size() > sizeof(mEndpointListNameBuffer)) + { + memcpy(mEndpointListNameBuffer, label.data(), sizeof(mEndpointListNameBuffer)); + name = CharSpan(mEndpointListNameBuffer, sizeof(mEndpointListNameBuffer)); + } + else + { + memcpy(mEndpointListNameBuffer, label.data(), label.size()); + name = CharSpan(mEndpointListNameBuffer, label.size()); + } + } + +private: + char mEndpointListNameBuffer[kEndpointListNameMaxSize]; +}; + class Instance : public AttributeAccessInterface, public CommandHandlerInterface { public: @@ -38,6 +124,19 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface CommandHandlerInterface(Optional::Missing(), Actions::Id) {} + /** + * @brief + * Called when the state of action is changed. + */ + void OnStateChanged(EndpointId endpoint, uint16_t actionId, uint32_t invokeId, ActionStateEnum actionState); + + /** + * @brief + * Called when the action is failed.. + */ + void OnActionFailed(EndpointId endpoint, uint16_t actionId, uint32_t invokeId, ActionStateEnum actionState, + ActionErrorEnum actionError); + static Instance * GetInstance(); void SetDefaultDelegate(Delegate * aDelegate); @@ -82,26 +181,24 @@ class Delegate /** * Get the action at the Nth index from list of actions. * @param index The index of the action to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param action A reference to the action struct which copies existing initialised buffer at index. + * @param action A reference to the GenericActionStruct which copies the buffer into it's own memory. * Name field (CharSpan) of ActionStruct contails the name of an action. - * The underlying data must remain allocated throughout the lifetime of the device, - * as the API does not make a copy. + * The API makes a copy of name. * @return Returns a CHIP_NO_ERROR if there was no error and the action was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available actions. */ - virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, Structs::ActionStruct::Type & action); + virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, GenericActionStruct & action); /** * Get the EndpointList at the Nth index from list of endpointList. * @param index The index of the endpointList to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param epList A reference to the endpointList struct which copies existing initialised buffer at index. - * Name field (CharSpan) of EndpointList contails the name of an endpointList. - * The underlying data must remain allocated throughout the lifetime of the device, - * as the API does not make a copy. + * @param epList A reference to the GenericEndpointList which copies the buffer into it's own memory. + * Name field (CharSpan) of EndpointList contails the name of an endpoint list. + * The API makes a copy of name. * @return Returns a CHIP_NO_ERROR if there was no error and the epList was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available endpointList. */ - virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, Structs::EndpointListStruct::Type & epList); + virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList); /** * Find the action with matching actionId in the list of action. From 3a0d9a5702f9fa1d24d3aa429b9622b37aefb84b Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Mon, 7 Oct 2024 17:27:26 +0530 Subject: [PATCH 09/11] Address review comments --- .../include/bridged-actions-stub.h | 22 +-- .../src/bridged-actions-stub.cpp | 10 +- examples/bridge-app/asr/BUILD.gn | 1 - .../asr/src/bridged-actions-stub.cpp | 101 ------------ .../asr/subdevice/SubDeviceManager.cpp | 8 - examples/bridge-app/linux/BUILD.gn | 8 + .../bridge-app/linux/bridged-actions-stub.cpp | 8 +- examples/bridge-app/telink/src/AppTask.cpp | 8 - .../bridge-app/telink/src/DeviceCallbacks.cpp | 105 ------------- examples/placeholder/linux/apps/app1/BUILD.gn | 1 - examples/placeholder/linux/apps/app2/BUILD.gn | 1 - .../linux/src/bridged-actions-stub.cpp | 102 ------------ .../actions-server/actions-server.cpp | 12 +- .../clusters/actions-server/actions-server.h | 148 +++++++++--------- 14 files changed, 103 insertions(+), 432 deletions(-) delete mode 100644 examples/bridge-app/asr/src/bridged-actions-stub.cpp delete mode 100644 examples/bridge-app/telink/src/DeviceCallbacks.cpp delete mode 100644 examples/placeholder/linux/src/bridged-actions-stub.cpp diff --git a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h index 91c9999d7cf90d..ca8b0e26d2004d 100644 --- a/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h +++ b/examples/all-clusters-app/all-clusters-common/include/bridged-actions-stub.h @@ -34,10 +34,10 @@ const uint16_t kEndpointListSize = 3; class ActionsDelegateImpl : public Delegate { private: - const GenericActionStruct kActionList[kActionListSize] = { - GenericActionStruct(0, CharSpan::fromCharString("TurnOnLight"), ActionTypeEnum::kScene, 0, 0, ActionStateEnum::kInactive), - GenericActionStruct(1, CharSpan::fromCharString("TurnOffLight"), ActionTypeEnum::kScene, 1, 0, ActionStateEnum::kInactive), - GenericActionStruct(2, CharSpan::fromCharString("ToggleLight"), ActionTypeEnum::kScene, 2, 0, ActionStateEnum::kInactive), + const ActionStructStorage kActionList[kActionListSize] = { + ActionStructStorage(0, CharSpan::fromCharString("TurnOnLight"), ActionTypeEnum::kScene, 0, 0, ActionStateEnum::kInactive), + ActionStructStorage(1, CharSpan::fromCharString("TurnOffLight"), ActionTypeEnum::kScene, 1, 0, ActionStateEnum::kInactive), + ActionStructStorage(2, CharSpan::fromCharString("ToggleLight"), ActionTypeEnum::kScene, 2, 0, ActionStateEnum::kInactive), }; // Dummy endpoint list. @@ -45,18 +45,18 @@ class ActionsDelegateImpl : public Delegate const EndpointId secondEpList[1] = { 0 }; const EndpointId thirdEpList[1] = { 0 }; - const GenericEndpointList kEndpointList[kEndpointListSize] = { - GenericEndpointList(0, CharSpan::fromCharString("On"), EndpointListTypeEnum::kOther, + const EndpointListStorage kEndpointList[kEndpointListSize] = { + EndpointListStorage(0, CharSpan::fromCharString("On"), EndpointListTypeEnum::kOther, DataModel::List(firstEpList)), - GenericEndpointList(1, CharSpan::fromCharString("Off"), EndpointListTypeEnum::kOther, + EndpointListStorage(1, CharSpan::fromCharString("Off"), EndpointListTypeEnum::kOther, DataModel::List(secondEpList)), - GenericEndpointList(2, CharSpan::fromCharString("Toggle"), EndpointListTypeEnum::kOther, + EndpointListStorage(2, CharSpan::fromCharString("Toggle"), EndpointListTypeEnum::kOther, DataModel::List(thirdEpList)), }; - CHIP_ERROR ReadActionAtIndex(uint16_t index, GenericActionStruct & action) override; - CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList) override; - CHIP_ERROR FindActionIdInActionList(uint16_t actionId) override; + CHIP_ERROR ReadActionAtIndex(uint16_t index, ActionStructStorage & action) override; + CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, EndpointListStorage & epList) override; + bool FindActionIdInActionList(uint16_t actionId) override; Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId) override; Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, diff --git a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp index e7f0dd701015b3..e5e7c98ae0d0c1 100644 --- a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp @@ -24,7 +24,7 @@ using namespace chip::app::Clusters::Actions; using namespace chip::app::Clusters::Actions::Attributes; using namespace chip::Protocols::InteractionModel; -CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, GenericActionStruct & action) +CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, ActionStructStorage & action) { if (index >= ArraySize(kActionList)) { @@ -34,7 +34,7 @@ CHIP_ERROR ActionsDelegateImpl::ReadActionAtIndex(uint16_t index, GenericActionS return CHIP_NO_ERROR; } -CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList) +CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, EndpointListStorage & epList) { if (index >= ArraySize(kEndpointList)) { @@ -44,14 +44,14 @@ CHIP_ERROR ActionsDelegateImpl::ReadEndpointListAtIndex(uint16_t index, GenericE return CHIP_NO_ERROR; } -CHIP_ERROR ActionsDelegateImpl::FindActionIdInActionList(uint16_t actionId) +bool ActionsDelegateImpl::FindActionIdInActionList(uint16_t actionId) { for (uint16_t i = 0; i < kActionListSize; i++) { if (kActionList[i].actionID == actionId) - return CHIP_NO_ERROR; + return true; } - return CHIP_ERROR_NOT_FOUND; + return false; } Status ActionsDelegateImpl::HandleInstantAction(uint16_t actionId, Optional invokeId) diff --git a/examples/bridge-app/asr/BUILD.gn b/examples/bridge-app/asr/BUILD.gn index 0fb9be4dcd99c4..19f8263e12bb7c 100755 --- a/examples/bridge-app/asr/BUILD.gn +++ b/examples/bridge-app/asr/BUILD.gn @@ -78,7 +78,6 @@ asr_executable("bridge_app") { "${examples_plat_dir}/shell/matter_shell.cpp", "src/AppTask.cpp", "src/DeviceCallbacks.cpp", - "src/bridged-actions-stub.cpp", "src/main.cpp", "subdevice/SubDevice.cpp", "subdevice/SubDeviceManager.cpp", diff --git a/examples/bridge-app/asr/src/bridged-actions-stub.cpp b/examples/bridge-app/asr/src/bridged-actions-stub.cpp deleted file mode 100644 index 84dca65f832107..00000000000000 --- a/examples/bridge-app/asr/src/bridged-actions-stub.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::Actions::Attributes; - -namespace { - -class ActionsAttrAccess : public AttributeAccessInterface -{ -public: - // Register for the Actions cluster on all endpoints. - ActionsAttrAccess() : AttributeAccessInterface(Optional::Missing(), Actions::Id) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - -private: - static constexpr uint16_t ClusterRevision = 1; - - CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder); -}; - -constexpr uint16_t ActionsAttrAccess::ClusterRevision; - -CHIP_ERROR ActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - static const char SetupUrl[] = "https://example.com"; - return aEncoder.Encode(chip::Span(SetupUrl, strlen(SetupUrl))); -} - -CHIP_ERROR ActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - return aEncoder.Encode(ClusterRevision); -} - -ActionsAttrAccess gAttrAccess; - -CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) -{ - VerifyOrDie(aPath.mClusterId == Actions::Id); - - switch (aPath.mAttributeId) - { - case ActionList::Id: - return ReadActionListAttribute(aPath.mEndpointId, aEncoder); - case EndpointLists::Id: - return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder); - case SetupURL::Id: - return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder); - case ClusterRevision::Id: - return ReadClusterRevision(aPath.mEndpointId, aEncoder); - default: - break; - } - return CHIP_NO_ERROR; -} -} // anonymous namespace - -// void MatterActionsPluginServerInitCallback(void) -//{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -// } diff --git a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp index 3508068c4832c6..c73f5fab84a88b 100644 --- a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp +++ b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp @@ -243,14 +243,6 @@ void HandleDeviceStatusChanged(SubDevice * dev, SubDevice::Changed_t itemChanged const EmberAfDeviceType gRootDeviceTypes[] = { { DEVICE_TYPE_ROOT_NODE, DEVICE_VERSION_DEFAULT } }; const EmberAfDeviceType gAggregateNodeDeviceTypes[] = { { DEVICE_TYPE_BRIDGE, DEVICE_VERSION_DEFAULT } }; -bool emberAfActionsClusterInstantActionCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, - const Actions::Commands::InstantAction::DecodableType & commandData) -{ - // No actions are implemented, just return status NotFound. - commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::NotFound); - return true; -} - void Init_Bridge_Endpoint() { // bridge will have own database named gSubDevices. diff --git a/examples/bridge-app/linux/BUILD.gn b/examples/bridge-app/linux/BUILD.gn index 212fb9dd3a9264..42bdbe83f2ed1c 100644 --- a/examples/bridge-app/linux/BUILD.gn +++ b/examples/bridge-app/linux/BUILD.gn @@ -28,6 +28,14 @@ executable("chip-bridge-app") { "main.cpp", ] + # Generic implementation of the actions cluster is not introduced in this app as this app has + # an interface to test actions. + # TODO: Generic implementation can be used here instead of having its own. + excludes = [ "${chip_root}/src/app/clusters/actions-server/**" ] + + # Apply excludes to the sources + sources -= excludes + deps = [ "${chip_root}/examples/bridge-app/bridge-common", "${chip_root}/examples/platform/linux:app-main", diff --git a/examples/bridge-app/linux/bridged-actions-stub.cpp b/examples/bridge-app/linux/bridged-actions-stub.cpp index 0eff1e7b6d05bc..580f4f2239bd1a 100644 --- a/examples/bridge-app/linux/bridged-actions-stub.cpp +++ b/examples/bridge-app/linux/bridged-actions-stub.cpp @@ -131,7 +131,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -// void MatterActionsPluginServerInitCallback() -//{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -// } +void MatterActionsPluginServerInitCallback() +{ + AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); +} diff --git a/examples/bridge-app/telink/src/AppTask.cpp b/examples/bridge-app/telink/src/AppTask.cpp index e080e40eb5dda9..122fa53ad064be 100644 --- a/examples/bridge-app/telink/src/AppTask.cpp +++ b/examples/bridge-app/telink/src/AppTask.cpp @@ -387,14 +387,6 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) } } -bool emberAfActionsClusterInstantActionCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, - const Clusters::Actions::Commands::InstantAction::DecodableType & commandData) -{ - // No actions are implemented, just return status NotFound. - commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::NotFound); - return true; -} - CHIP_ERROR AppTask::Init(void) { SetExampleButtonCallbacks(LightingActionEventHandler); diff --git a/examples/bridge-app/telink/src/DeviceCallbacks.cpp b/examples/bridge-app/telink/src/DeviceCallbacks.cpp deleted file mode 100644 index 8511d7047dfb0a..00000000000000 --- a/examples/bridge-app/telink/src/DeviceCallbacks.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Copyright (c) 2023 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::app::Clusters; -using namespace ::chip::app::Clusters::Actions::Attributes; -using namespace ::chip::Inet; -using namespace ::chip::System; - -namespace { - -class ActionsAttrAccess : public AttributeAccessInterface -{ -public: - // Register for the Actions cluster on all endpoints. - ActionsAttrAccess() : AttributeAccessInterface(Optional::Missing(), Actions::Id) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - -private: - static constexpr uint16_t ClusterRevision = 1; - - CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder); -}; - -constexpr uint16_t ActionsAttrAccess::ClusterRevision; - -CHIP_ERROR ActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - static const char SetupUrl[] = "https://example.com"; - return aEncoder.Encode(chip::CharSpan::fromCharString(SetupUrl)); -} - -CHIP_ERROR ActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - return aEncoder.Encode(ClusterRevision); -} - -ActionsAttrAccess gAttrAccess; - -CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) -{ - VerifyOrDie(aPath.mClusterId == Actions::Id); - - switch (aPath.mAttributeId) - { - case ActionList::Id: - return ReadActionListAttribute(aPath.mEndpointId, aEncoder); - case EndpointLists::Id: - return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder); - case SetupURL::Id: - return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder); - case ClusterRevision::Id: - return ReadClusterRevision(aPath.mEndpointId, aEncoder); - default: - break; - } - return CHIP_NO_ERROR; -} -} // anonymous namespace - -// void MatterActionsPluginServerInitCallback(void) -//{ -// AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -// } diff --git a/examples/placeholder/linux/apps/app1/BUILD.gn b/examples/placeholder/linux/apps/app1/BUILD.gn index aba1e870f7a041..f8cc1b36a2b0ee 100644 --- a/examples/placeholder/linux/apps/app1/BUILD.gn +++ b/examples/placeholder/linux/apps/app1/BUILD.gn @@ -28,7 +28,6 @@ source_set("app1") { sources = [ "../../resource-monitoring-delegates.cpp", - "../../src/bridged-actions-stub.cpp", "../../static-supported-modes-manager.cpp", "../../thread-border-router-management.cpp", ] diff --git a/examples/placeholder/linux/apps/app2/BUILD.gn b/examples/placeholder/linux/apps/app2/BUILD.gn index 2bea36611ffb37..302054f5bf927b 100644 --- a/examples/placeholder/linux/apps/app2/BUILD.gn +++ b/examples/placeholder/linux/apps/app2/BUILD.gn @@ -28,7 +28,6 @@ source_set("app2") { sources = [ "../../resource-monitoring-delegates.cpp", - "../../src/bridged-actions-stub.cpp", "../../static-supported-modes-manager.cpp", ] diff --git a/examples/placeholder/linux/src/bridged-actions-stub.cpp b/examples/placeholder/linux/src/bridged-actions-stub.cpp deleted file mode 100644 index ad934cc881077c..00000000000000 --- a/examples/placeholder/linux/src/bridged-actions-stub.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::Actions::Attributes; - -namespace { - -class ActionsAttrAccess : public AttributeAccessInterface -{ -public: - // Register for the Actions cluster on all endpoints. - ActionsAttrAccess() : AttributeAccessInterface(Optional::Missing(), Actions::Id) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - -private: - static constexpr uint16_t ClusterRevision = 1; - - CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder); - CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder); -}; - -constexpr uint16_t ActionsAttrAccess::ClusterRevision; - -CHIP_ERROR ActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - // Just return an empty list - return aEncoder.EncodeEmptyList(); -} - -CHIP_ERROR ActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - static const char SetupUrl[] = "https://example.com"; - return aEncoder.Encode(chip::Span(SetupUrl, strlen(SetupUrl))); -} - -CHIP_ERROR ActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder) -{ - return aEncoder.Encode(ClusterRevision); -} - -ActionsAttrAccess gAttrAccess; - -CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) -{ - VerifyOrDie(aPath.mClusterId == Actions::Id); - - switch (aPath.mAttributeId) - { - case ActionList::Id: - return ReadActionListAttribute(aPath.mEndpointId, aEncoder); - case EndpointLists::Id: - return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder); - case SetupURL::Id: - return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder); - case ClusterRevision::Id: - return ReadClusterRevision(aPath.mEndpointId, aEncoder); - default: - break; - } - return CHIP_NO_ERROR; -} -} // anonymous namespace - -// void MatterActionsPluginServerInitCallback(void) -//{ -// chip::app::AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); -// } diff --git a/src/app/clusters/actions-server/actions-server.cpp b/src/app/clusters/actions-server/actions-server.cpp index 3945903b85d410..543e4e6aa078b7 100644 --- a/src/app/clusters/actions-server/actions-server.cpp +++ b/src/app/clusters/actions-server/actions-server.cpp @@ -16,7 +16,6 @@ */ #include "actions-server.h" -#include #include #include #include @@ -77,7 +76,7 @@ CHIP_ERROR Instance::ReadActionListAttribute(const AttributeValueEncoder::ListEn } for (uint16_t i = 0; true; i++) { - GenericActionStruct action; + ActionStructStorage action; CHIP_ERROR err = GetInstance()->mDelegate->ReadActionAtIndex(i, action); if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) @@ -99,7 +98,7 @@ CHIP_ERROR Instance::ReadEndpointListAttribute(const AttributeValueEncoder::List } for (uint16_t i = 0; true; i++) { - GenericEndpointList epList; + EndpointListStorage epList; CHIP_ERROR err = GetInstance()->mDelegate->ReadEndpointListAtIndex(i, epList); if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) @@ -146,12 +145,12 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu return CHIP_NO_ERROR; } -CHIP_ERROR Instance::FindActionIdInActionList(uint16_t actionId) +bool Instance::FindActionIdInActionList(uint16_t actionId) { if (GetInstance()->mDelegate == nullptr) { ChipLogError(Zcl, "Actions delegate is null!!!"); - return CHIP_ERROR_INCORRECT_STATE; + return false; } return GetInstance()->mDelegate->FindActionIdInActionList(actionId); } @@ -178,8 +177,7 @@ void Instance::HandleCommand(HandlerContext & handlerContext, FuncT func) } uint16_t actionId = requestPayload.actionID; - CHIP_ERROR err = GetInstance()->FindActionIdInActionList(actionId); - if (err != CHIP_NO_ERROR) + if (!GetInstance()->FindActionIdInActionList(actionId)) { handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Protocols::InteractionModel::Status::NotFound); return; diff --git a/src/app/clusters/actions-server/actions-server.h b/src/app/clusters/actions-server/actions-server.h index d081bdfd6c44e0..ba30566a1e3101 100644 --- a/src/app/clusters/actions-server/actions-server.h +++ b/src/app/clusters/actions-server/actions-server.h @@ -21,36 +21,39 @@ #include #include #include +#include namespace chip { namespace app { namespace Clusters { namespace Actions { -inline constexpr size_t kActionNameMaxSize = 128u; -inline constexpr size_t kEndpointListNameMaxSize = 128u; +static constexpr size_t kActionNameMaxSize = 128u; +static constexpr size_t kEndpointListNameMaxSize = 128u; +static constexpr size_t kEndpointListMaxSize = 256u; class Delegate; -struct GenericActionStruct : public Structs::ActionStruct::Type +struct ActionStructStorage : public Structs::ActionStruct::Type { - GenericActionStruct(){}; + ActionStructStorage() : mActionName(mBuffer, sizeof(mBuffer)){}; - GenericActionStruct(uint16_t action, CharSpan label, ActionTypeEnum actionType, uint16_t epListID, - BitMask commands, ActionStateEnum actionState) + ActionStructStorage(uint16_t action, CharSpan actionName, ActionTypeEnum actionType, uint16_t epListID, + BitMask commands, ActionStateEnum actionState) : + mActionName(mBuffer, sizeof(mBuffer)) { - Set(action, label, actionType, epListID, commands, actionState); + Set(action, actionName, actionType, epListID, commands, actionState); } - GenericActionStruct(const GenericActionStruct & action) { *this = action; } + ActionStructStorage(const ActionStructStorage & action) : mActionName(mBuffer, sizeof(mBuffer)) { *this = action; } - GenericActionStruct & operator=(const GenericActionStruct & action) + ActionStructStorage & operator=(const ActionStructStorage & action) { Set(action.actionID, action.name, action.type, action.endpointListID, action.supportedCommands, action.state); return *this; } - void Set(uint16_t action, CharSpan label, ActionTypeEnum actionType, uint16_t epListID, BitMask commands, + void Set(uint16_t action, CharSpan actionName, ActionTypeEnum actionType, uint16_t epListID, BitMask commands, ActionStateEnum actionState) { actionID = action; @@ -58,61 +61,55 @@ struct GenericActionStruct : public Structs::ActionStruct::Type endpointListID = epListID; supportedCommands = commands; state = actionState; - memset(mActionNameBuffer, 0, sizeof(mActionNameBuffer)); - if (label.size() > sizeof(mActionNameBuffer)) - { - memcpy(mActionNameBuffer, label.data(), sizeof(mActionNameBuffer)); - name = CharSpan(mActionNameBuffer, sizeof(mActionNameBuffer)); - } - else - { - memcpy(mActionNameBuffer, label.data(), label.size()); - name = CharSpan(mActionNameBuffer, label.size()); - } + CopyCharSpanToMutableCharSpanWithTruncation(actionName, mActionName); + name = mActionName; } private: - char mActionNameBuffer[kActionNameMaxSize]; + char mBuffer[kActionNameMaxSize]; + MutableCharSpan mActionName; }; -struct GenericEndpointList : public Structs::EndpointListStruct::Type +struct EndpointListStorage : public Structs::EndpointListStruct::Type { - GenericEndpointList(){}; + EndpointListStorage() : mEpListName(mBuffer, sizeof(mBuffer)){}; - GenericEndpointList(uint16_t epListId, CharSpan label, EndpointListTypeEnum epListType, - DataModel::List endpointList) + EndpointListStorage(uint16_t epListId, CharSpan epListName, EndpointListTypeEnum epListType, + DataModel::List endpointList) : + mEpListName(mBuffer, sizeof(mBuffer)) { - Set(epListId, label, epListType, endpointList); + Set(epListId, epListName, epListType, endpointList); } - GenericEndpointList(const GenericEndpointList & epList) { *this = epList; } + EndpointListStorage(const EndpointListStorage & epList) : mEpListName(mBuffer, sizeof(mBuffer)) { *this = epList; } - GenericEndpointList & operator=(const GenericEndpointList & epList) + EndpointListStorage & operator=(const EndpointListStorage & epList) { Set(epList.endpointListID, epList.name, epList.type, epList.endpoints); return *this; } - void Set(uint16_t epListId, CharSpan label, EndpointListTypeEnum epListType, DataModel::List endpointList) + void Set(uint16_t epListId, CharSpan epListName, EndpointListTypeEnum epListType, + DataModel::List endpointList) { endpointListID = epListId; type = epListType; - endpoints = endpointList; - memset(mEndpointListNameBuffer, 0, sizeof(mEndpointListNameBuffer)); - if (label.size() > sizeof(mEndpointListNameBuffer)) - { - memcpy(mEndpointListNameBuffer, label.data(), sizeof(mEndpointListNameBuffer)); - name = CharSpan(mEndpointListNameBuffer, sizeof(mEndpointListNameBuffer)); - } - else + + for (uint8_t index = 0; index < std::min(endpointList.size(), kEndpointListMaxSize); index++) { - memcpy(mEndpointListNameBuffer, label.data(), label.size()); - name = CharSpan(mEndpointListNameBuffer, label.size()); + mEpList.push_back(endpointList[index]); } + mEpListSpan = Span(mEpList.data(), mEpList.size()); + endpoints = DataModel::List(mEpListSpan); + CopyCharSpanToMutableCharSpanWithTruncation(epListName, mEpListName); + name = mEpListName; } private: - char mEndpointListNameBuffer[kEndpointListNameMaxSize]; + char mBuffer[kEndpointListNameMaxSize]; + MutableCharSpan mEpListName; + std::vector mEpList; + Span mEpListSpan; }; class Instance : public AttributeAccessInterface, public CommandHandlerInterface @@ -148,7 +145,7 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface CHIP_ERROR ReadActionListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder); CHIP_ERROR ReadEndpointListAttribute(const AttributeValueEncoder::ListEncodeHelper & encoder); - CHIP_ERROR FindActionIdInActionList(uint16_t actionId); + bool FindActionIdInActionList(uint16_t actionId); // CommandHandlerInterface template @@ -181,35 +178,30 @@ class Delegate /** * Get the action at the Nth index from list of actions. * @param index The index of the action to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param action A reference to the GenericActionStruct which copies the buffer into it's own memory. - * Name field (CharSpan) of ActionStruct contails the name of an action. - * The API makes a copy of name. + * @param action A reference to the ActionStructStorage which should be initialized via copy/assignments or calling Set(). * @return Returns a CHIP_NO_ERROR if there was no error and the action was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available actions. */ - virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, GenericActionStruct & action); + virtual CHIP_ERROR ReadActionAtIndex(uint16_t index, ActionStructStorage & action) = 0; /** * Get the EndpointList at the Nth index from list of endpointList. * @param index The index of the endpointList to be returned. It is assumed that actions are indexable from 0 and with no gaps. - * @param epList A reference to the GenericEndpointList which copies the buffer into it's own memory. - * Name field (CharSpan) of EndpointList contails the name of an endpoint list. - * The API makes a copy of name. + * @param action A reference to the EndpointListStorage which should be initialized via copy/assignments or calling Set(). * @return Returns a CHIP_NO_ERROR if there was no error and the epList was returned successfully. * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index in beyond the list of available endpointList. */ - virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, GenericEndpointList & epList); + virtual CHIP_ERROR ReadEndpointListAtIndex(uint16_t index, EndpointListStorage & epList) = 0; /** * Find the action with matching actionId in the list of action. * @param actionId The action to be find in the list of action. - * @return Returns a CHIP_NO_ERROR if matching action is found. - * CHIP_ERROR_NOT_FOUND if the matching action does not found in the list of action. + * @return Returns a true if matching action is found otherwise false. */ - virtual CHIP_ERROR FindActionIdInActionList(uint16_t actionId); + virtual bool FindActionIdInActionList(uint16_t actionId) = 0; /** - * On reciept of each and every command, + * On receipt of each and every command, * if the InvokeID data field is provided by the client when invoking a command, the server SHALL generate a StateChanged event * when the action changes to a new state or an ActionFailed event when execution of the action fails. * @@ -218,16 +210,16 @@ class Delegate */ /** - * When an InstantAction command is recieved, an action (state change) on the involved endpoints shall trigger, + * When an InstantAction command is received, an action (state change) on the involved endpoints shall trigger, * in a "fire and forget" manner. Afterwards, the action’s state SHALL be Inactive. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleInstantAction(uint16_t actionId, Optional invokeId) = 0; /** - * When an InstantActionWithTransition command is recieved, an action (state change) on the involved endpoints shall trigger, + * When an InstantActionWithTransition command is received, an action (state change) on the involved endpoints shall trigger, * with a specified time to transition from the current state to the new state. During the transition, the action’s state SHALL * be Active. Afterwards, the action’s state SHALL be Inactive. * @@ -236,19 +228,19 @@ class Delegate * @return Returns a Success if an action took place successfully otherwise, suitable error. */ virtual Protocols::InteractionModel::Status HandleInstantActionWithTransition(uint16_t actionId, uint16_t transitionTime, - Optional invokeId); + Optional invokeId) = 0; /** - * When a StartAction command is recieved, the commencement of an action on the involved endpoints shall trigger. Afterwards, + * When a StartAction command is received, the commencement of an action on the involved endpoints shall trigger. Afterwards, * the action’s state SHALL be Inactive. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleStartAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStartAction(uint16_t actionId, Optional invokeId) = 0; /** - * When a StartActionWithDuration command is recieved, the commencement of an action on the involved endpoints shall trigger, + * When a StartActionWithDuration command is received, the commencement of an action on the involved endpoints shall trigger, * and SHALL change the action’s state to Active. After the specified Duration, the action will stop, and the action’s state * SHALL change to Inactive. * @@ -257,28 +249,28 @@ class Delegate * @return Returns a Success if an action took place successfully otherwise, suitable error. */ virtual Protocols::InteractionModel::Status HandleStartActionWithDuration(uint16_t actionId, uint32_t duration, - Optional invokeId); + Optional invokeId) = 0; /** - * When a StopAction command is recieved, the ongoing action on the involved endpoints shall stop. Afterwards, the action’s + * When a StopAction command is received, the ongoing action on the involved endpoints shall stop. Afterwards, the action’s * state SHALL be Inactive. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleStopAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleStopAction(uint16_t actionId, Optional invokeId) = 0; /** - * When a PauseAction command is recieved, the ongoing action on the involved endpoints shall pause and SHALL change the + * When a PauseAction command is received, the ongoing action on the involved endpoints shall pause and SHALL change the * action’s state to Paused. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandlePauseAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandlePauseAction(uint16_t actionId, Optional invokeId) = 0; /** - * When a PauseActionWithDuration command is recieved, pauses an ongoing action, and SHALL change the action’s state to Paused. + * When a PauseActionWithDuration command is received, pauses an ongoing action, and SHALL change the action’s state to Paused. * After the specified Duration, the ongoing action will be automatically resumed. which SHALL change the action’s state to * Active. * @@ -287,28 +279,28 @@ class Delegate * @return Returns a Success if an action took place successfully otherwise, suitable error. */ virtual Protocols::InteractionModel::Status HandlePauseActionWithDuration(uint16_t actionId, uint32_t duration, - Optional invokeId); + Optional invokeId) = 0; /** - * When a ResumeAction command is recieved, the previously paused action shall resume and SHALL change the action’s state to + * When a ResumeAction command is received, the previously paused action shall resume and SHALL change the action’s state to * Active. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleResumeAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleResumeAction(uint16_t actionId, Optional invokeId) = 0; /** - * When an EnableAction command is recieved, it enables a certain action or automation. Afterwards, the action’s state SHALL be + * When an EnableAction command is received, it enables a certain action or automation. Afterwards, the action’s state SHALL be * Active. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleEnableAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleEnableAction(uint16_t actionId, Optional invokeId) = 0; /** - * When an EnableActionWithDuration command is recieved, it enables a certain action or automation, and SHALL change the + * When an EnableActionWithDuration command is received, it enables a certain action or automation, and SHALL change the * action’s state to be Active. After the specified Duration, the action or automation will stop, and the action’s state SHALL * change to Disabled. * @@ -317,19 +309,19 @@ class Delegate * @return Returns a Success if an action took place successfully otherwise, suitable error. */ virtual Protocols::InteractionModel::Status HandleEnableActionWithDuration(uint16_t actionId, uint32_t duration, - Optional invokeId); + Optional invokeId) = 0; /** - * When a DisableAction command is recieved, it disables a certain action or automation, and SHALL change the action’s state to + * When a DisableAction command is received, it disables a certain action or automation, and SHALL change the action’s state to * Inactive. * * @param actionId The id of an action on which an action shall takes place. * @return Returns a Success if an action took place successfully otherwise, suitable error. */ - virtual Protocols::InteractionModel::Status HandleDisableAction(uint16_t actionId, Optional invokeId); + virtual Protocols::InteractionModel::Status HandleDisableAction(uint16_t actionId, Optional invokeId) = 0; /** - * When a DisableActionWithDuration command is recieved, it disables a certain action or automation, and SHALL change the + * When a DisableActionWithDuration command is received, it disables a certain action or automation, and SHALL change the * action’s state to Disabled. After the specified Duration, the action or automation will re-start, and the action’s state * SHALL change to either Inactive or Active, depending on the actions. * @@ -338,7 +330,7 @@ class Delegate * @return Returns a Success if an action took place successfully otherwise, suitable error. */ virtual Protocols::InteractionModel::Status HandleDisableActionWithDuration(uint16_t actionId, uint32_t duration, - Optional invokeId); + Optional invokeId) = 0; }; } // namespace Actions From 7c9f3375c653504c04fe674ce04e93609bc535d6 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Thu, 10 Oct 2024 13:30:22 +0530 Subject: [PATCH 10/11] Fix CI and apps should use emberAfActionsClusterInitCallback instead of MatterActionsPluginServerInitCallback in example --- .../esp32/sdkconfig_m5stack.defaults | 6 ++++++ .../esp32/sdkconfig_m5stack_rpc.defaults | 6 ++++++ examples/bridge-app/linux/BUILD.gn | 8 -------- examples/bridge-app/linux/bridged-actions-stub.cpp | 2 +- examples/bridge-app/telink/CMakeLists.txt | 1 - 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack.defaults b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack.defaults index 287262d17e57cc..03691548ea91db 100644 --- a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack.defaults +++ b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack.defaults @@ -73,3 +73,9 @@ CONFIG_BUILD_CHIP_TESTS=y # Move functions from IRAM to flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y + +# Reduce the event logging buffer to reduce the DRAM usage +# TODO: [ESP32] Fix the DRAM overflow in esp32 apps #34717 +CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=512 diff --git a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults index d2eaffb9bfd15b..6c4907410a1c22 100644 --- a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults +++ b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults @@ -88,3 +88,9 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=1024 CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP=y + +# Reduce the event logging buffer to reduce the DRAM usage +# TODO: [ESP32] Fix the DRAM overflow in esp32 apps #34717 +CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=512 diff --git a/examples/bridge-app/linux/BUILD.gn b/examples/bridge-app/linux/BUILD.gn index 42bdbe83f2ed1c..212fb9dd3a9264 100644 --- a/examples/bridge-app/linux/BUILD.gn +++ b/examples/bridge-app/linux/BUILD.gn @@ -28,14 +28,6 @@ executable("chip-bridge-app") { "main.cpp", ] - # Generic implementation of the actions cluster is not introduced in this app as this app has - # an interface to test actions. - # TODO: Generic implementation can be used here instead of having its own. - excludes = [ "${chip_root}/src/app/clusters/actions-server/**" ] - - # Apply excludes to the sources - sources -= excludes - deps = [ "${chip_root}/examples/bridge-app/bridge-common", "${chip_root}/examples/platform/linux:app-main", diff --git a/examples/bridge-app/linux/bridged-actions-stub.cpp b/examples/bridge-app/linux/bridged-actions-stub.cpp index 580f4f2239bd1a..f5224199a03336 100644 --- a/examples/bridge-app/linux/bridged-actions-stub.cpp +++ b/examples/bridge-app/linux/bridged-actions-stub.cpp @@ -131,7 +131,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr } } // anonymous namespace -void MatterActionsPluginServerInitCallback() +void emberAfActionsClusterInitCallback() { AttributeAccessInterfaceRegistry::Instance().Register(&gAttrAccess); } diff --git a/examples/bridge-app/telink/CMakeLists.txt b/examples/bridge-app/telink/CMakeLists.txt index f2e80864d46e01..e7984bc1332853 100644 --- a/examples/bridge-app/telink/CMakeLists.txt +++ b/examples/bridge-app/telink/CMakeLists.txt @@ -38,7 +38,6 @@ target_include_directories(app PRIVATE target_sources(app PRIVATE src/AppTask.cpp src/Device.cpp - src/DeviceCallbacks.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp From 2416258766010ac7a00a7892e5d4ea1e031ae672 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Sun, 20 Oct 2024 18:08:41 +0530 Subject: [PATCH 11/11] Try to fix CI --- examples/all-clusters-app/esp32/main/main.cpp | 5 +++++ examples/all-clusters-app/linux/main-common.cpp | 7 +++++++ scripts/tools/check_includes_config.py | 1 + 3 files changed, 13 insertions(+) diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index e6f211f279b1cb..d6ddf464bc1db1 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -131,6 +131,11 @@ static void InitServer(intptr_t context) app::Clusters::Actions::Instance::GetInstance()->SetDefaultDelegate(&sActionsDelegateImpl); } +void emberAfActionsClusterInitCallback(EndpointId endpoint) +{ + app::Clusters::Actions::Instance::GetInstance()->SetDefaultDelegate(&sActionsDelegateImpl); +} + #include #include diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index b62d154f0d58f7..543168a804fea5 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupporte Clusters::ModeSelect::StaticSupportedModesManager sStaticSupportedModesManager; Clusters::ValveConfigurationAndControl::ValveControlDelegate sValveDelegate; Clusters::TimeSynchronization::ExtendedTimeSyncDelegate sTimeSyncDelegate; +Clusters::Actions::ActionsDelegateImpl sActionsDelegateImpl; // Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces constexpr const uint8_t kNamespaceCommon = 7; @@ -340,6 +342,11 @@ void emberAfThermostatClusterInitCallback(EndpointId endpoint) SetDefaultDelegate(endpoint, &delegate); } +void emberAfActionsClusterInitCallback(EndpointId endpoint) +{ + Clusters::Actions::Instance::GetInstance()->SetDefaultDelegate(&sActionsDelegateImpl); +} + Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, uint16_t maxReadLength) diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index 2e79c6f8f9cfa9..910b595f912e31 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -127,6 +127,7 @@ 'src/app/clusters/application-launcher-server/application-launcher-server.cpp': {'string'}, 'src/app/clusters/application-launcher-server/application-launcher-delegate.h': {'list'}, 'src/app/clusters/audio-output-server/audio-output-delegate.h': {'list'}, + 'src/app/clusters/actions-server/actions-server.h': {'vector'}, # EcosystemInformationCluster is for Fabric Sync and is intended to run on device that are capable of handling these types. 'src/app/clusters/ecosystem-information-server/ecosystem-information-server.h': {'map', 'string', 'vector'}, 'src/app/clusters/channel-server/channel-delegate.h': {'list'},