Skip to content

Commit

Permalink
Add correct checking for whether a command is supported. (#14806)
Browse files Browse the repository at this point in the history
This also fixes the status reporting for unsupported endpoints and
clusters.  And fixes some tests to use the right endpoint, now that we
are checking that sort of thing.

Fixes #7612
Fixes #13920
Fixes #14022
Fixes #11578
Fixes #11185
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Aug 1, 2023
1 parent b524f28 commit 1436544
Show file tree
Hide file tree
Showing 31 changed files with 580 additions and 277 deletions.
4 changes: 4 additions & 0 deletions .github/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ ImplClass
implementers
imx
imxlinux
incomingCommands
indexhtml
Inet
InetLayer
Expand Down Expand Up @@ -550,6 +551,7 @@ jupyterlab
KA
Kconfig
KeypadInput
kInvalidCommandId
KitProg
kNodeIdNotSpecified
knownissues
Expand Down Expand Up @@ -716,6 +718,7 @@ nrfdks
nrfutil
nrfxlib
NTAG
nullptr
NUM
nwk
NXP
Expand Down Expand Up @@ -763,6 +766,7 @@ otasoftwareupdaterequestor
otaURL
OTBR
otcli
outgoingCommands
PAA
PacketBuffer
PAI
Expand Down
6 changes: 4 additions & 2 deletions examples/bridge-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,17 @@ 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
endpoint. The declaration must begin with the
`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.

Expand Down
19 changes: 16 additions & 3 deletions examples/bridge-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions examples/bridge-app/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,17 @@ 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
endpoint. The declaration must begin with the
`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.

Expand Down
27 changes: 20 additions & 7 deletions examples/bridge-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
95 changes: 86 additions & 9 deletions examples/tv-app/linux/AppImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
36 changes: 18 additions & 18 deletions src/app/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

{
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
9 changes: 7 additions & 2 deletions src/app/CommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <messaging/ExchangeContext.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <protocols/interaction_model/Constants.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
16 changes: 6 additions & 10 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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.
Expand Down
Loading

0 comments on commit 1436544

Please sign in to comment.