diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index dbfe7fee594cbe..d1851402c94200 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -503,6 +503,7 @@ ImplClass implementers imx imxlinux +incomingCommands indexhtml Inet InetLayer @@ -549,6 +550,7 @@ jupyterlab KA Kconfig KeypadInput +kInvalidCommandId KitProg kNodeIdNotSpecified knownissues @@ -715,6 +717,7 @@ nrfdks nrfutil nrfxlib NTAG +nullptr NUM nwk NXP @@ -762,6 +765,7 @@ otasoftwareupdaterequestor otaURL OTBR otcli +outgoingCommands PAA PacketBuffer PAI diff --git a/examples/bridge-app/esp32/README.md b/examples/bridge-app/esp32/README.md index 963ae595bece86..df50e4becfce52 100644 --- a/examples/bridge-app/esp32/README.md +++ b/examples/bridge-app/esp32/README.md @@ -58,7 +58,7 @@ defined: application's `main.cpp` for an example of this implementation. `DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(clusterListName)` -`DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs)` +`DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs, incomingCommands, outgoingCommands)` `DECLARE_DYNAMIC_CLUSTER_LIST_END` - These three macros are used to declare a list of clusters for use within a @@ -66,7 +66,9 @@ defined: `DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN` macro which will define the name of the allocated cluster structure. Each cluster is then added by the `DECLARE_DYNAMIC_CLUSTER` macro referencing attribute list previously - defined by the `DECLARE_DYNAMIC_ATTRIBUTE...` macros. Finally, + defined by the `DECLARE_DYNAMIC_ATTRIBUTE...` macros and the lists of + incoming/outgoing commands terminated by kInvalidCommandId (or nullptr if + there aren't any commands in the list). Finally, `DECLARE_DYNAMIC_CLUSTER_LIST_END` macro should be used to close the definition. diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index be17e3fa11466a..d12a81b2c10ed8 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -97,10 +97,23 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_LABEL_LIST_ATTRIBUTE_ID, ARRAY, kFixedLabelAttribu DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); // Declare Cluster List for Bridged Light endpoint +// TODO: It's not clear whether it would be better to get the command lists from +// the ZAP config on our last fixed endpoint instead. +constexpr CommandId onOffIncomingCommands[] = { + app::Clusters::OnOff::Commands::Off::Id, + app::Clusters::OnOff::Commands::On::Id, + app::Clusters::OnOff::Commands::Toggle::Id, + app::Clusters::OnOff::Commands::OffWithEffect::Id, + app::Clusters::OnOff::Commands::OnWithRecallGlobalScene::Id, + app::Clusters::OnOff::Commands::OnWithTimedOff::Id, + kInvalidCommandId, +}; + DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedLightClusters) -DECLARE_DYNAMIC_CLUSTER(ZCL_ON_OFF_CLUSTER_ID, onOffAttrs), DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, fixedLabelAttrs) DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(ZCL_ON_OFF_CLUSTER_ID, onOffAttrs, onOffIncomingCommands, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, fixedLabelAttrs, nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER_LIST_END; // Declare Bridged Light endpoint DECLARE_DYNAMIC_ENDPOINT(bridgedLightEndpoint, bridgedLightClusters); diff --git a/examples/bridge-app/linux/README.md b/examples/bridge-app/linux/README.md index 9cdd2a30f8080c..5ff4087b7d89c0 100644 --- a/examples/bridge-app/linux/README.md +++ b/examples/bridge-app/linux/README.md @@ -55,7 +55,7 @@ defined: application's `main.cpp` for an example of this implementation. `DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(clusterListName)` -`DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs)` +`DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs, incomingCommands, outgoingCommands)` `DECLARE_DYNAMIC_CLUSTER_LIST_END` - These three macros are used to declare a list of clusters for use within a @@ -63,7 +63,9 @@ defined: `DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN` macro which will define the name of the allocated cluster structure. Each cluster is then added by the `DECLARE_DYNAMIC_CLUSTER` macro referencing attribute list previously - defined by the `DECLARE_DYNAMIC_ATTRIBUTE...` macros. Finally, + defined by the `DECLARE_DYNAMIC_ATTRIBUTE...` macros and the lists of + incoming/outgoing commands terminated by kInvalidCommandId (or nullptr if + there aren't any commands in the list). Finally, `DECLARE_DYNAMIC_CLUSTER_LIST_END` macro should be used to close the definition. diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index bf4627f8109d5a..9c98f4f7822c4a 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -117,10 +117,23 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_LABEL_LIST_ATTRIBUTE_ID, ARRAY, kFixedLabelAttribu DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); // Declare Cluster List for Bridged Light endpoint +// TODO: It's not clear whether it would be better to get the command lists from +// the ZAP config on our last fixed endpoint instead. +constexpr CommandId onOffIncomingCommands[] = { + app::Clusters::OnOff::Commands::Off::Id, + app::Clusters::OnOff::Commands::On::Id, + app::Clusters::OnOff::Commands::Toggle::Id, + app::Clusters::OnOff::Commands::OffWithEffect::Id, + app::Clusters::OnOff::Commands::OnWithRecallGlobalScene::Id, + app::Clusters::OnOff::Commands::OnWithTimedOff::Id, + kInvalidCommandId, +}; + DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedLightClusters) -DECLARE_DYNAMIC_CLUSTER(ZCL_ON_OFF_CLUSTER_ID, onOffAttrs), DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, fixedLabelAttrs) DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(ZCL_ON_OFF_CLUSTER_ID, onOffAttrs, onOffIncomingCommands, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, fixedLabelAttrs, nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER_LIST_END; // Declare Bridged Light endpoint DECLARE_DYNAMIC_ENDPOINT(bridgedLightEndpoint, bridgedLightClusters); @@ -166,10 +179,10 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_LABEL_LIST_ATTRIBUTE_ID, ARRAY, kFixedLabelAttribu // Declare Cluster List for Bridged Switch endpoint DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedSwitchClusters) -DECLARE_DYNAMIC_CLUSTER(ZCL_SWITCH_CLUSTER_ID, switchAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, switchDescriptorAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, switchBridgedDeviceBasicAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, switchFixedLabelAttrs) DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(ZCL_SWITCH_CLUSTER_ID, switchAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, switchDescriptorAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, switchBridgedDeviceBasicAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, switchFixedLabelAttrs, nullptr, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END; // Declare Bridged Switch endpoint DECLARE_DYNAMIC_ENDPOINT(bridgedSwitchEndpoint, bridgedSwitchClusters); diff --git a/examples/tv-app/linux/AppImpl.cpp b/examples/tv-app/linux/AppImpl.cpp index 6099c8fb48edba..0a9a3698d29510 100644 --- a/examples/tv-app/linux/AppImpl.cpp +++ b/examples/tv-app/linux/AppImpl.cpp @@ -132,17 +132,94 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttri DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_CURRENT_CHANNEL_ATTRIBUTE_ID, STRUCT, 1, 0), /* current channel */ DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); +constexpr CommandId keypadInputIncomingCommands[] = { + app::Clusters::KeypadInput::Commands::SendKeyRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId keypadInputOutgoingCommands[] = { + app::Clusters::KeypadInput::Commands::SendKeyResponse::Id, + kInvalidCommandId, +}; +constexpr CommandId applicationLauncherIncomingCommands[] = { + app::Clusters::ApplicationLauncher::Commands::LaunchAppRequest::Id, + app::Clusters::ApplicationLauncher::Commands::StopAppRequest::Id, + app::Clusters::ApplicationLauncher::Commands::HideAppRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId applicationLauncherOutgoingCommands[] = { + app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Id, + kInvalidCommandId, +}; +constexpr CommandId accountLoginIncomingCommands[] = { + app::Clusters::AccountLogin::Commands::GetSetupPINRequest::Id, + app::Clusters::AccountLogin::Commands::LoginRequest::Id, + app::Clusters::AccountLogin::Commands::LogoutRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId accountLoginOutgoingCommands[] = { + app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Id, + kInvalidCommandId, +}; +// TODO: Sort out when the optional commands here should be listed. +constexpr CommandId contentLauncherIncomingCommands[] = { + app::Clusters::ContentLauncher::Commands::LaunchContentRequest::Id, + app::Clusters::ContentLauncher::Commands::LaunchURLRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId contentLauncherOutgoingCommands[] = { + app::Clusters::ContentLauncher::Commands::LaunchResponse::Id, + kInvalidCommandId, +}; +// TODO: Sort out when the optional commands here should be listed. +constexpr CommandId mediaPlaybackIncomingCommands[] = { + app::Clusters::MediaPlayback::Commands::PlayRequest::Id, app::Clusters::MediaPlayback::Commands::PauseRequest::Id, + app::Clusters::MediaPlayback::Commands::StopRequest::Id, app::Clusters::MediaPlayback::Commands::StartOverRequest::Id, + app::Clusters::MediaPlayback::Commands::PreviousRequest::Id, app::Clusters::MediaPlayback::Commands::NextRequest::Id, + app::Clusters::MediaPlayback::Commands::RewindRequest::Id, app::Clusters::MediaPlayback::Commands::FastForwardRequest::Id, + app::Clusters::MediaPlayback::Commands::SkipForwardRequest::Id, app::Clusters::MediaPlayback::Commands::SkipBackwardRequest::Id, + app::Clusters::MediaPlayback::Commands::SeekRequest::Id, kInvalidCommandId, +}; +constexpr CommandId mediaPlaybackOutgoingCommands[] = { + app::Clusters::MediaPlayback::Commands::PlaybackResponse::Id, + kInvalidCommandId, +}; +constexpr CommandId targetNavigatorIncomingCommands[] = { + app::Clusters::TargetNavigator::Commands::NavigateTargetRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId targetNavigatorOutgoingCommands[] = { + app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Id, + kInvalidCommandId, +}; +// TODO: Sort out when the optional commands here should be listed. +constexpr CommandId channelIncomingCommands[] = { + app::Clusters::Channel::Commands::ChangeChannelRequest::Id, + app::Clusters::Channel::Commands::ChangeChannelByNumberRequest::Id, + app::Clusters::Channel::Commands::SkipChannelRequest::Id, + kInvalidCommandId, +}; +constexpr CommandId channelOutgoingCommands[] = { + app::Clusters::Channel::Commands::ChangeChannelResponse::Id, + kInvalidCommandId, +}; // Declare Cluster List for Content App endpoint DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(contentAppClusters) -DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_BASIC_CLUSTER_ID, applicationBasicAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_KEYPAD_INPUT_CLUSTER_ID, keypadInputAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_LAUNCHER_CLUSTER_ID, applicationLauncherAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_ACCOUNT_LOGIN_CLUSTER_ID, accountLoginAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_CONTENT_LAUNCH_CLUSTER_ID, contentLauncherAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_MEDIA_PLAYBACK_CLUSTER_ID, mediaPlaybackAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_TARGET_NAVIGATOR_CLUSTER_ID, targetNavigatorAttrs), - DECLARE_DYNAMIC_CLUSTER(ZCL_CHANNEL_CLUSTER_ID, channelAttrs) DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_BASIC_CLUSTER_ID, applicationBasicAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(ZCL_KEYPAD_INPUT_CLUSTER_ID, keypadInputAttrs, keypadInputIncomingCommands, + keypadInputOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_LAUNCHER_CLUSTER_ID, applicationLauncherAttrs, applicationLauncherIncomingCommands, + applicationLauncherOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_ACCOUNT_LOGIN_CLUSTER_ID, accountLoginAttrs, accountLoginIncomingCommands, + accountLoginOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_CONTENT_LAUNCH_CLUSTER_ID, contentLauncherAttrs, contentLauncherIncomingCommands, + contentLauncherOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_MEDIA_PLAYBACK_CLUSTER_ID, mediaPlaybackAttrs, mediaPlaybackIncomingCommands, + mediaPlaybackOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_TARGET_NAVIGATOR_CLUSTER_ID, targetNavigatorAttrs, targetNavigatorIncomingCommands, + targetNavigatorOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER(ZCL_CHANNEL_CLUSTER_ID, channelAttrs, channelIncomingCommands, channelOutgoingCommands), + DECLARE_DYNAMIC_CLUSTER_LIST_END; // Declare Content App endpoint DECLARE_DYNAMIC_ENDPOINT(contentAppEndpoint, contentAppClusters); diff --git a/src/app/CommandHandler.cpp b/src/app/CommandHandler.cpp index 476a080c1c801e..e83b45a09dda1c 100644 --- a/src/app/CommandHandler.cpp +++ b/src/app/CommandHandler.cpp @@ -254,7 +254,18 @@ CHIP_ERROR CommandHandler::ProcessCommandDataIB(CommandDataIB::Parser & aCommand err = commandPath.GetEndpointId(&concretePath.mEndpointId); SuccessOrExit(err); - VerifyOrExit(mpCallback->CommandExists(concretePath), err = CHIP_ERROR_INVALID_PROFILE_ID); + using Protocols::InteractionModel::Status; + { + Status commandExists = mpCallback->CommandExists(concretePath); + if (commandExists != Status::Success) + { + ChipLogDetail(DataManagement, "No command " ChipLogFormatMEI " in Cluster " ChipLogFormatMEI " on Endpoint 0x%" PRIx16, + ChipLogValueMEI(concretePath.mCommandId), ChipLogValueMEI(concretePath.mClusterId), + concretePath.mEndpointId); + return AddStatus(concretePath, commandExists); + } + } + VerifyOrExit(mpExchangeCtx != nullptr && mpExchangeCtx->HasSessionHandle(), err = CHIP_ERROR_INCORRECT_STATE); { @@ -272,10 +283,10 @@ CHIP_ERROR CommandHandler::ProcessCommandDataIB(CommandDataIB::Parser & aCommand { if (err != CHIP_ERROR_ACCESS_DENIED) { - return AddStatus(concretePath, Protocols::InteractionModel::Status::Failure); + return AddStatus(concretePath, Status::Failure); } // TODO: when wildcard invokes are supported, handle them to discard rather than fail with status - return AddStatus(concretePath, Protocols::InteractionModel::Status::UnsupportedAccess); + return AddStatus(concretePath, Status::UnsupportedAccess); } } @@ -308,18 +319,7 @@ CHIP_ERROR CommandHandler::ProcessCommandDataIB(CommandDataIB::Parser & aCommand exit: if (err != CHIP_NO_ERROR) { - // The Path is the path in the request if there are any error occurred before we dispatch the command to clusters. - // Currently, it could be failed to decode Path or failed to find cluster / command on desired endpoint. - // TODO: The behavior when receiving a malformed message is not clear in the Spec. (Spec#3259) - // TODO: The error code should be updated after #7072 added error codes required by IM. - if (err == CHIP_ERROR_INVALID_PROFILE_ID) - { - ChipLogDetail(DataManagement, "No Cluster " ChipLogFormatMEI " on Endpoint 0x%" PRIx16, - ChipLogValueMEI(concretePath.mClusterId), concretePath.mEndpointId); - } - - // TODO:in particular different reasons for ServerClusterCommandExists to test false should result in different errors here - AddStatus(concretePath, Protocols::InteractionModel::Status::InvalidCommand); + return AddStatus(concretePath, Status::InvalidCommand); } // We have handled the error status above and put the error status in response, now return success status so we can process @@ -394,10 +394,10 @@ CHIP_ERROR CommandHandler::ProcessGroupCommandDataIB(CommandDataIB::Parser & aCo const ConcreteCommandPath concretePath(mapping.endpoint_id, clusterId, commandId); - if (!mpCallback->CommandExists(concretePath)) + if (mpCallback->CommandExists(concretePath) != Protocols::InteractionModel::Status::Success) { - ChipLogError(DataManagement, "No Cluster " ChipLogFormatMEI " on Endpoint 0x%" PRIx16, ChipLogValueMEI(clusterId), - mapping.endpoint_id); + ChipLogDetail(DataManagement, "No command " ChipLogFormatMEI " in Cluster " ChipLogFormatMEI " on Endpoint 0x%" PRIx16, + ChipLogValueMEI(mapping.endpoint_id), ChipLogValueMEI(clusterId), mapping.endpoint_id); continue; } diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index 690bc6e104f74d..bf4e3d52b51780 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -74,9 +75,13 @@ class CommandHandler TLV::TLVReader & apPayload) = 0; /* - * Check to see if a command implementation exists for a specific concrete command path. + * Check to see if a command implementation exists for a specific + * concrete command path. If it does, Success will be returned. If + * not, one of UnsupportedEndpoint, UnsupportedCluster, or + * UnsupportedCommand will be returned, depending on how the command + * fails to exist. */ - virtual bool CommandExists(const ConcreteCommandPath & aCommandPath) = 0; + virtual Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) = 0; }; class Handle diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index c283a5177cffab..b08db60763aa2f 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -596,7 +596,7 @@ void InteractionModelEngine::DispatchCommand(CommandHandler & apCommandObj, cons DispatchSingleClusterCommand(aCommandPath, apPayload, &apCommandObj); } -bool InteractionModelEngine::CommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status InteractionModelEngine::CommandExists(const ConcreteCommandPath & aCommandPath) { return ServerClusterCommandExists(aCommandPath); } diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index 41aa33db976a6b..c6b916fd8ba07b 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -272,7 +272,7 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate, public Comman void DispatchCommand(CommandHandler & apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & apPayload) override; - bool CommandExists(const ConcreteCommandPath & aCommandPath) override; + Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) override; bool HasActiveRead(); @@ -305,16 +305,12 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip CommandHandler * apCommandObj); /** - * Check whether the given cluster exists on the given endpoint and supports the given command. - * TODO: The implementation lives in ember-compatibility-functions.cpp, this should be replaced by IM command catalog look up - * function after we have a cluster catalog in interaction model engine. - * TODO: The endpoint id on response command (client side command) is unclear, so we don't have a ClientClusterCommandExists - * function. (Spec#3258) - * - * @retval True if the endpoint contains the server side of the given cluster and that cluster implements the given command, false - * otherwise. + * Check whether the given cluster exists on the given endpoint and supports + * the given command. If it does, Success will be returned. If it does not, + * one of UnsupportedEndpoint, UnsupportedCluster, or UnsupportedCommand + * will be returned, depending on how the command fails to exist. */ -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath); +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath); /** * Fetch attribute value and version info and write to the AttributeReport provided. diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index c0a040d3968a27..cf8a78bf196919 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -45,6 +45,7 @@ #include using TestContext = chip::Test::AppContext; +using namespace chip::Protocols; namespace chip { @@ -65,11 +66,27 @@ namespace app { CommandHandler::Handle asyncCommandHandle; -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // Mock cluster catalog, only support one command on one cluster on one endpoint. - return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == kTestClusterId && - aCommandPath.mCommandId != kTestNonExistCommandId); + // Mock cluster catalog, only support commands on one cluster on one endpoint. + using InteractionModel::Status; + + if (aCommandPath.mEndpointId != kTestEndpointId) + { + return Status::UnsupportedEndpoint; + } + + if (aCommandPath.mClusterId != kTestClusterId) + { + return Status::UnsupportedCluster; + } + + if (aCommandPath.mCommandId == kTestNonExistCommandId) + { + return Status::UnsupportedCommand; + } + + return Status::Success; } void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader, @@ -142,7 +159,10 @@ class MockCommandHandlerCallback : public CommandHandler::Callback { DispatchSingleClusterCommand(aCommandPath, apPayload, &apCommandObj); } - bool CommandExists(const ConcreteCommandPath & aCommandPath) { return ServerClusterCommandExists(aCommandPath); } + InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) + { + return ServerClusterCommandExists(aCommandPath); + } int onFinalCalledTimes = 0; } mockCommandHandlerDelegate; diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp index 472948c1c3fb3f..7f700638a37e99 100644 --- a/src/app/tests/integration/chip_im_initiator.cpp +++ b/src/app/tests/integration/chip_im_initiator.cpp @@ -632,10 +632,10 @@ void SubscribeRequestTimerHandler(chip::System::Layer * systemLayer, void * appS namespace chip { namespace app { -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // Always return true in test. - return true; + // Always return success in test. + return Protocols::InteractionModel::Status::Success; } void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader, diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp index a3d399e98ba8cc..c9d5e86c7b6eec 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -45,11 +45,27 @@ namespace chip { namespace app { -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { // The Mock cluster catalog -- only have one command on one cluster on one endpoint. - return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == kTestClusterId && - aCommandPath.mCommandId == kTestCommandId); + using Protocols::InteractionModel::Status; + + if (aCommandPath.mEndpointId != kTestEndpointId) + { + return Status::UnsupportedEndpoint; + } + + if (aCommandPath.mClusterId != kTestClusterId) + { + return Status::UnsupportedCluster; + } + + if (aCommandPath.mCommandId != kTestCommandId) + { + return Status::UnsupportedCommand; + } + + return Status::Success; } void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader, @@ -57,7 +73,7 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip { static bool statusCodeFlipper = false; - if (!ServerClusterCommandExists(aCommandPath)) + if (ServerClusterCommandExists(aCommandPath) != Protocols::InteractionModel::Status::Success) { return; } diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index 285e56fbaccdb8..545305a6afb74b 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -954,17 +954,13 @@ tests: command: "test" endpoint: 200 response: - # No such endpoint, so expect an error. - # SDK returning wrong error code here so far. - errorWrongValue: UNSUPPORTED_ENDPOINT + error: UNSUPPORTED_ENDPOINT - label: "Send Test Command to unsupported cluster" command: "test" endpoint: 0 response: - # No TestCluster on that, so expect an error. - # SDK returning wrong error code here so far. - errorWrongValue: UNSUPPORTED_CLUSTER + error: UNSUPPORTED_CLUSTER # Tests for vendor id @@ -2838,16 +2834,14 @@ tests: command: "readAttribute" attribute: "list_int8u" response: - # SDK returning wrong error code here so far. - errorWrongValue: UNSUPPORTED_ENDPOINT + error: UNSUPPORTED_ENDPOINT - label: "Read attribute from nonexistent cluster." endpoint: 0 command: "readAttribute" attribute: "list_int8u" response: - # SDK returning wrong error code here so far. - errorWrongValue: UNSUPPORTED_CLUSTER + error: UNSUPPORTED_CLUSTER # Tests for command with optional arguments - label: diff --git a/src/app/tests/suites/certification/Test_TC_SWDIAG_1_1.yaml b/src/app/tests/suites/certification/Test_TC_SWDIAG_1_1.yaml index dcbccd4cdf2ca2..0d2b5de455b5cc 100644 --- a/src/app/tests/suites/certification/Test_TC_SWDIAG_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWDIAG_1_1.yaml @@ -16,7 +16,7 @@ name: 45.1.1. [TC-SWDIAG-1.1] Attributes with server as DUT config: cluster: "Software Diagnostics" - endpoint: 1 + endpoint: 0 tests: - label: "Wait for the commissioned device to be retrieved" diff --git a/src/app/util/af.h b/src/app/util/af.h index 60bd133994eec1..84e76f7147e713 100644 --- a/src/app/util/af.h +++ b/src/app/util/af.h @@ -286,12 +286,14 @@ extern EmberAfDefinedEndpoint emAfEndpoints[]; chip::EndpointId emberAfEndpointFromIndex(uint16_t index); /** - * Returns the index of a given endpoint + * Returns the index of a given endpoint. Will return 0xFFFF if this is not a + * valid endpoint id or if the endpoint is disabled. */ uint16_t emberAfIndexFromEndpoint(chip::EndpointId endpoint); /** - * Returns the index of a given endpoint; Does not ignore disabled endpoints + * Returns the index of a given endpoint; Does not ignore disabled endpoints. + * Will return 0xFFFF if this is not a valid endpoint id. */ uint16_t emberAfIndexFromEndpointIncludingDisabledEndpoints(chip::EndpointId endpoint); diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index 004a3bf11d5f2b..069b0053e776d8 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -659,6 +659,16 @@ EmberAfStatus emAfReadOrWriteAttribute(EmberAfAttributeSearchRecord * attRecord, return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; // Sorry, attribute was not found. } +const EmberAfEndpointType * emberAfFindEndpointType(chip::EndpointId endpointId) +{ + uint16_t ep = emberAfIndexFromEndpoint(endpointId); + if (ep == 0xFFFF) + { + return nullptr; + } + return emAfEndpoints[ep].endpointType; +} + const EmberAfCluster * emberAfFindClusterInType(const EmberAfEndpointType * endpointType, ClusterId clusterId, EmberAfClusterMask mask, uint8_t * index) { diff --git a/src/app/util/attribute-storage.h b/src/app/util/attribute-storage.h index 1ae15547871cb1..6a4e4d079a4ab1 100644 --- a/src/app/util/attribute-storage.h +++ b/src/app/util/attribute-storage.h @@ -78,9 +78,10 @@ #define DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(clusterListName) EmberAfCluster clusterListName[] = { -#define DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs) \ +#define DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs, incomingCommands, outgoingCommands) \ { \ - clusterId, clusterAttrs, sizeof(clusterAttrs) / sizeof(EmberAfAttributeMetadata), 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + clusterId, clusterAttrs, sizeof(clusterAttrs) / sizeof(EmberAfAttributeMetadata), 0, ZAP_CLUSTER_MASK(SERVER), NULL, \ + incomingCommands, outgoingCommands \ } #define DECLARE_DYNAMIC_CLUSTER_LIST_END } @@ -128,6 +129,10 @@ bool emAfMatchCluster(const EmberAfCluster * cluster, EmberAfAttributeSearchReco bool emAfMatchAttribute(const EmberAfCluster * cluster, const EmberAfAttributeMetadata * am, EmberAfAttributeSearchRecord * attRecord); +// Returns endpoint type for the given endpoint id if there is an enabled +// endpoint with that endpoint id. Otherwise returns null. +const EmberAfEndpointType * emberAfFindEndpointType(chip::EndpointId endpointId); + // Check if a cluster is implemented or not. If yes, the cluster is returned. // // mask = 0 -> find either client or server diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index d8ece370e6e47b..f2b39780d5e003 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -247,11 +247,31 @@ CHIP_ERROR attributeBufferToNumericTlvData(TLV::TLVWriter & writer, bool isNulla } // anonymous namespace -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // TODO: Currently, we are using cluster catalog from the ember library, this should be modified or replaced after several - // updates to Commands. - return emberAfContainsServer(aCommandPath.mEndpointId, aCommandPath.mClusterId); + using Protocols::InteractionModel::Status; + + const EmberAfEndpointType * type = emberAfFindEndpointType(aCommandPath.mEndpointId); + if (type == nullptr) + { + return Status::UnsupportedEndpoint; + } + + const EmberAfCluster * cluster = emberAfFindClusterInType(type, aCommandPath.mClusterId, CLUSTER_MASK_SERVER); + if (cluster == nullptr) + { + return Status::UnsupportedCluster; + } + + for (const CommandId * cmd = cluster->clientGeneratedCommandList; cmd != nullptr; cmd++) + { + if (*cmd == aCommandPath.mCommandId) + { + return Status::Success; + } + } + + return Status::UnsupportedCommand; } namespace { @@ -403,6 +423,30 @@ CHIP_ERROR ReadViaAccessInterface(FabricIndex aAccessingFabricIndex, bool aIsFab return CHIP_NO_ERROR; } +// Determine the appropriate status response for an unsupported attribute for +// the given path. Must be called when the attribute is known to be unsupported +// (i.e. we found no attribute metadata for it). +Protocols::InteractionModel::Status UnsupportedAttributeStatus(const ConcreteAttributePath & aPath) +{ + using Protocols::InteractionModel::Status; + + const EmberAfEndpointType * type = emberAfFindEndpointType(aPath.mEndpointId); + if (type == nullptr) + { + return Status::UnsupportedEndpoint; + } + + const EmberAfCluster * cluster = emberAfFindClusterInType(type, aPath.mClusterId, CLUSTER_MASK_SERVER); + if (cluster == nullptr) + { + return Status::UnsupportedCluster; + } + + // Since we know the attribute is unsupported and the endpoint/cluster are + // OK, this is the only option left. + return Status::UnsupportedAttribute; +} + } // anonymous namespace CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, @@ -436,7 +480,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b if (attributeCluster == nullptr && attributeMetadata == nullptr) { - return SendFailureStatus(aPath, aAttributeReports, Protocols::InteractionModel::Status::UnsupportedAttribute, nullptr); + return SendFailureStatus(aPath, aAttributeReports, UnsupportedAttributeStatus(aPath), nullptr); } // Check access control. A failed check will disallow the operation, and may or may not generate an attribute report @@ -873,7 +917,7 @@ CHIP_ERROR WriteSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, if (attributeMetadata == nullptr) { - return apWriteHandler->AddStatus(aPath, Protocols::InteractionModel::Status::UnsupportedAttribute); + return apWriteHandler->AddStatus(aPath, UnsupportedAttributeStatus(aPath)); } if (attributeMetadata->IsReadOnly()) diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index 9304e24c8039c8..d704e16fb94f5e 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -75,7 +75,7 @@ DECLARE_DYNAMIC_ATTRIBUTE(0x00000001, INT8U, 1, 0), DECLARE_DYNAMIC_ATTRIBUTE(0x DECLARE_DYNAMIC_ATTRIBUTE(0x00000005, INT8U, 1, 0), DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(testEndpointClusters) -DECLARE_DYNAMIC_CLUSTER(TestCluster::Id, testClusterAttrs), DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(TestCluster::Id, testClusterAttrs, nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER_LIST_END; DECLARE_DYNAMIC_ENDPOINT(testEndpoint, testEndpointClusters); @@ -84,7 +84,7 @@ DECLARE_DYNAMIC_ATTRIBUTE(kTestListAttribute, ARRAY, 1, 0), DECLARE_DYNAMIC_ATTR DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(testEndpoint3Clusters) -DECLARE_DYNAMIC_CLUSTER(TestCluster::Id, testClusterAttrsOnEndpoint3), DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(TestCluster::Id, testClusterAttrsOnEndpoint3, nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER_LIST_END; DECLARE_DYNAMIC_ENDPOINT(testEndpoint3, testEndpoint3Clusters); diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index f094f717b65ac7..a6515ddd7f6551 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -144,7 +144,8 @@ void TestCommandInteraction::TestNoHandler(nlTestSuite * apSuite, void * apConte // not safe to do so. auto onFailureCb = [apSuite](CHIP_ERROR aError) { NL_TEST_ASSERT(apSuite, - aError.IsIMStatus() && app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::InvalidCommand); + aError.IsIMStatus() && + app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::UnsupportedEndpoint); }; responseDirective = kSendDataResponse; @@ -176,9 +177,14 @@ DECLARE_DYNAMIC_ATTRIBUTE(chip::app::Clusters::Descriptor::Attributes::DeviceLis DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); +constexpr CommandId testClusterCommands[] = { + TestCluster::Commands::TestSimpleArgumentRequest::Id, + kInvalidCommandId, +}; DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(testEndpointClusters) -DECLARE_DYNAMIC_CLUSTER(chip::app::Clusters::TestCluster::Id, testClusterAttrs), - DECLARE_DYNAMIC_CLUSTER(chip::app::Clusters::Descriptor::Id, descriptorAttrs), DECLARE_DYNAMIC_CLUSTER_LIST_END; +DECLARE_DYNAMIC_CLUSTER(chip::app::Clusters::TestCluster::Id, testClusterAttrs, testClusterCommands, nullptr), + DECLARE_DYNAMIC_CLUSTER(chip::app::Clusters::Descriptor::Id, descriptorAttrs, nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER_LIST_END; DECLARE_DYNAMIC_ENDPOINT(testEndpoint, testEndpointClusters); diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index c4bc3ba4881c87..d13f08f83faabd 100644 --- a/src/controller/tests/data_model/TestCommands.cpp +++ b/src/controller/tests/data_model/TestCommands.cpp @@ -36,12 +36,14 @@ #include #include #include +#include using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; +using namespace chip::Protocols; namespace { chip::ClusterStatus kTestSuccessClusterStatus = 1; @@ -129,10 +131,22 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip } } -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // Mock cluster catalog, only support one command on one cluster on one endpoint. - return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == TestCluster::Id); + // Mock cluster catalog, only support commands on one cluster on one endpoint. + using InteractionModel::Status; + + if (aCommandPath.mEndpointId != kTestEndpointId) + { + return Status::UnsupportedEndpoint; + } + + if (aCommandPath.mClusterId != TestCluster::Id) + { + return Status::UnsupportedCluster; + } + + return Status::Success; } CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 6082280c2f0106..cbf8e5ddd550ec 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -25,11 +25,13 @@ #include #include #include +#include using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app::Clusters; +using namespace chip::Protocols; namespace { @@ -52,10 +54,22 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip CommandHandler * apCommandObj) {} -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // Mock cluster catalog, only support one command on one cluster on one endpoint. - return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == TestCluster::Id); + // Mock cluster catalog, only support commands on one cluster on one endpoint. + using InteractionModel::Status; + + if (aCommandPath.mEndpointId != kTestEndpointId) + { + return Status::UnsupportedEndpoint; + } + + if (aCommandPath.mClusterId != TestCluster::Id) + { + return Status::UnsupportedCluster; + } + + return Status::Success; } CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, diff --git a/src/controller/tests/data_model/TestWrite.cpp b/src/controller/tests/data_model/TestWrite.cpp index 274948956792f7..be60e8317add34 100644 --- a/src/controller/tests/data_model/TestWrite.cpp +++ b/src/controller/tests/data_model/TestWrite.cpp @@ -26,11 +26,13 @@ #include #include #include +#include using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app::Clusters; +using namespace chip::Protocols; namespace { @@ -53,10 +55,22 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip CommandHandler * apCommandObj) {} -bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { - // Mock cluster catalog, only support one command on one cluster on one endpoint. - return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == TestCluster::Id); + // Mock cluster catalog, only support commands on one cluster on one endpoint. + using InteractionModel::Status; + + if (aCommandPath.mEndpointId != kTestEndpointId) + { + return Status::UnsupportedEndpoint; + } + + if (aCommandPath.mClusterId != TestCluster::Id) + { + return Status::UnsupportedCluster; + } + + return Status::Success; } CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index bb4439fdd94179..fc4948b78e5ac8 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -28764,7 +28764,7 @@ - (void)testSendClusterTestCluster_000144_Test [cluster testWithCompletionHandler:^(NSError * _Nullable err) { NSLog(@"Send Test Command to unsupported endpoint Error: %@", err); - XCTAssertNotEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], 0); + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT); [expectation fulfill]; }]; @@ -28782,7 +28782,7 @@ - (void)testSendClusterTestCluster_000145_Test [cluster testWithCompletionHandler:^(NSError * _Nullable err) { NSLog(@"Send Test Command to unsupported cluster Error: %@", err); - XCTAssertNotEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], 0); + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER); [expectation fulfill]; }]; @@ -34622,7 +34622,7 @@ - (void)testSendClusterTestCluster_000360_ReadAttribute [cluster readAttributeListInt8uWithCompletionHandler:^(NSArray * _Nullable value, NSError * _Nullable err) { NSLog(@"Read attribute from nonexistent endpoint. Error: %@", err); - XCTAssertNotEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], 0); + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT); [expectation fulfill]; }]; @@ -34640,7 +34640,7 @@ - (void)testSendClusterTestCluster_000361_ReadAttribute [cluster readAttributeListInt8uWithCompletionHandler:^(NSArray * _Nullable value, NSError * _Nullable err) { NSLog(@"Read attribute from nonexistent cluster. Error: %@", err); - XCTAssertNotEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], 0); + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER); [expectation fulfill]; }]; @@ -42572,7 +42572,7 @@ - (void)testSendClusterTest_TC_SWDIAG_1_1_000001_ReadAttribute CHIPDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:1 queue:queue]; + CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:0 queue:queue]; XCTAssertNotNil(cluster); [cluster readAttributeCurrentHeapFreeWithCompletionHandler:^(NSNumber * _Nullable value, NSError * _Nullable err) { @@ -42597,7 +42597,7 @@ - (void)testSendClusterTest_TC_SWDIAG_1_1_000002_ReadAttribute CHIPDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:1 queue:queue]; + CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:0 queue:queue]; XCTAssertNotNil(cluster); [cluster readAttributeCurrentHeapUsedWithCompletionHandler:^(NSNumber * _Nullable value, NSError * _Nullable err) { @@ -42622,7 +42622,7 @@ - (void)testSendClusterTest_TC_SWDIAG_1_1_000003_ReadAttribute CHIPDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:1 queue:queue]; + CHIPTestSoftwareDiagnostics * cluster = [[CHIPTestSoftwareDiagnostics alloc] initWithDevice:device endpoint:0 queue:queue]; XCTAssertNotNil(cluster); [cluster readAttributeCurrentHeapHighWatermarkWithCompletionHandler:^(NSNumber * _Nullable value, NSError * _Nullable err) { diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 582c8fbba796e6..f97a4ece310142 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -57093,7 +57093,7 @@ class TestCluster : public TestCommand void OnFailureResponse_144(CHIP_ERROR error) { chip::app::StatusIB status(error); - VerifyOrReturn(CheckConstraintNotValue("status", chip::to_underlying(status.mStatus), 0)); + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT)); NextTest(); } @@ -57121,7 +57121,7 @@ class TestCluster : public TestCommand void OnFailureResponse_145(CHIP_ERROR error) { chip::app::StatusIB status(error); - VerifyOrReturn(CheckConstraintNotValue("status", chip::to_underlying(status.mStatus), 0)); + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER)); NextTest(); } @@ -62915,7 +62915,7 @@ class TestCluster : public TestCommand void OnFailureResponse_360(CHIP_ERROR error) { chip::app::StatusIB status(error); - VerifyOrReturn(CheckConstraintNotValue("status", chip::to_underlying(status.mStatus), 0)); + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT)); NextTest(); } @@ -62935,7 +62935,7 @@ class TestCluster : public TestCommand void OnFailureResponse_361(CHIP_ERROR error) { chip::app::StatusIB status(error); - VerifyOrReturn(CheckConstraintNotValue("status", chip::to_underlying(status.mStatus), 0)); + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER)); NextTest(); } @@ -73507,7 +73507,7 @@ class Test_TC_SWDIAG_1_1 : public TestCommand CHIP_ERROR TestReadsCurrentHeapFreeNonGlobalAttributeValueFromDut_1() { - const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 1; + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::SoftwareDiagnosticsClusterTest cluster; cluster.Associate(mDevices[kIdentityAlpha], endpoint); @@ -73530,7 +73530,7 @@ class Test_TC_SWDIAG_1_1 : public TestCommand CHIP_ERROR TestReadsCurrentHeapUsedNonGlobalAttributeValueFromDut_2() { - const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 1; + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::SoftwareDiagnosticsClusterTest cluster; cluster.Associate(mDevices[kIdentityAlpha], endpoint); @@ -73553,7 +73553,7 @@ class Test_TC_SWDIAG_1_1 : public TestCommand CHIP_ERROR TestReadsCurrentHeapHighWaterMarkNonGlobalAttributeValueFromDut_3() { - const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 1; + const chip::EndpointId endpoint = mEndpoint.HasValue() ? mEndpoint.Value() : 0; chip::Controller::SoftwareDiagnosticsClusterTest cluster; cluster.Associate(mDevices[kIdentityAlpha], endpoint);