Skip to content

Commit

Permalink
Add correct checking for whether a command is supported.
Browse files Browse the repository at this point in the history
This also fixes the status reporting for unsupported endpoints and clusters.

Fixes project-chip#7612
Fixes project-chip#13920
Fixes project-chip#14022
  • Loading branch information
bzbarsky-apple committed Feb 4, 2022
1 parent 9423bb4 commit e594aeb
Show file tree
Hide file tree
Showing 26 changed files with 366 additions and 115 deletions.
4 changes: 4 additions & 0 deletions .github/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ ImplClass
implementers
imx
imxlinux
incomingCommands
indexhtml
Inet
InetLayer
Expand Down Expand Up @@ -549,6 +550,7 @@ jupyterlab
KA
Kconfig
KeypadInput
kInvalidCommandId
KitProg
kNodeIdNotSpecified
knownissues
Expand Down Expand Up @@ -715,6 +717,7 @@ nrfdks
nrfutil
nrfxlib
NTAG
nullptr
NUM
nwk
NXP
Expand Down Expand Up @@ -762,6 +765,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 e594aeb

Please sign in to comment.