Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Use chip::app::ConcreteCommandPath for DispatchSingleClusterCommand, DispatchSingleClusterCommandResponse and ServerClusterCommandExists #10226

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions examples/chip-tool/commands/clusters/ModelCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,6 @@

using namespace ::chip;

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, Command * apCommandObj)
{
ChipLogDetail(Controller,
"Received Cluster Command: Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI " Endpoint=%" PRIx16,
ChipLogValueMEI(aClusterId), ChipLogValueMEI(aCommandId), aEndPointId);
ChipLogError(
Controller,
"Default DispatchSingleClusterCommand is called, this should be replaced by actual dispatched for cluster commands");
}

CHIP_ERROR ModelCommand::Run()
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down
8 changes: 6 additions & 2 deletions src/app/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,18 @@ CHIP_ERROR CommandHandler::ProcessCommandDataElement(CommandDataElement::Parser

err = aCommandElement.GetCommandPath(&commandPath);
SuccessOrExit(err);

err = commandPath.GetClusterId(&clusterId);
SuccessOrExit(err);

err = commandPath.GetCommandId(&commandId);
SuccessOrExit(err);

err = commandPath.GetEndpointId(&endpointId);
SuccessOrExit(err);

VerifyOrExit(ServerClusterCommandExists(clusterId, commandId, endpointId), err = CHIP_ERROR_INVALID_PROFILE_ID);
VerifyOrExit(ServerClusterCommandExists(ConcreteCommandPath(endpointId, clusterId, commandId)),
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
err = CHIP_ERROR_INVALID_PROFILE_ID);

err = aCommandElement.GetData(&commandDataReader);
if (CHIP_END_OF_TLV == err)
Expand All @@ -103,7 +107,7 @@ CHIP_ERROR CommandHandler::ProcessCommandDataElement(CommandDataElement::Parser
}
if (CHIP_NO_ERROR == err)
{
DispatchSingleClusterCommand(clusterId, commandId, endpointId, commandDataReader, this);
DispatchSingleClusterCommand(ConcreteCommandPath(endpointId, clusterId, commandId), commandDataReader, this);
}

exit:
Expand Down
3 changes: 2 additions & 1 deletion src/app/CommandSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser &

err = commandPath.GetClusterId(&clusterId);
SuccessOrExit(err);

err = commandPath.GetCommandId(&commandId);
SuccessOrExit(err);

Expand All @@ -153,7 +154,7 @@ CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser &
err = aCommandElement.GetData(&commandDataReader);
SuccessOrExit(err);
// TODO(#4503): Should call callbacks of cluster that sends the command.
DispatchSingleClusterResponseCommand(clusterId, commandId, endpointId, commandDataReader, this);
DispatchSingleClusterResponseCommand(ConcreteCommandPath(endpointId, clusterId, commandId), commandDataReader, this);
}

exit:
Expand Down
11 changes: 6 additions & 5 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <app/Command.h>
#include <app/CommandHandler.h>
#include <app/CommandSender.h>
#include <app/ConcreteCommandPath.h>
#include <app/InteractionModelDelegate.h>
#include <app/ReadClient.h>
#include <app/ReadHandler.h>
Expand Down Expand Up @@ -210,10 +211,10 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate
ClusterInfo * mpNextAvailableClusterInfo = nullptr;
};

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj);
void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandSender * apCommandObj);
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj);
void DispatchSingleClusterResponseCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandSender * apCommandObj);

/**
* Check whether the given cluster exists on the given endpoint and supports the given command.
Expand All @@ -225,7 +226,7 @@ void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::Comm
* @retval True if the endpoint contains the server side of the given cluster and that cluster implements the given command, false
* otherwise.
*/
bool ServerClusterCommandExists(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId);
bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath);

/**
* Fetch attribute value and version info and write to the TLVWriter provided.
Expand Down
26 changes: 13 additions & 13 deletions src/app/tests/TestCommandInteraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,33 @@ constexpr CommandId kTestCommandId = 4;

namespace app {

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj)
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj)
{
chip::app::ConcreteCommandPath commandPath(aEndPointId, aClusterId, aCommandId);

ChipLogDetail(Controller,
"Received Cluster Command: Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI " Endpoint=%" PRIx16,
ChipLogValueMEI(aClusterId), ChipLogValueMEI(aCommandId), aEndPointId);
"Received Cluster Command: Endpoint=%" PRIx16 " Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI,
aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId));

apCommandObj->AddStatusCode(commandPath, Protocols::SecureChannel::GeneralStatusCode::kSuccess, Protocols::SecureChannel::Id,
apCommandObj->AddStatusCode(aCommandPath, Protocols::SecureChannel::GeneralStatusCode::kSuccess, Protocols::SecureChannel::Id,
Protocols::InteractionModel::Status::Success);

chip::isCommandDispatched = true;
}

void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandSender * apCommandObj)
void DispatchSingleClusterResponseCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandSender * apCommandObj)
{
ChipLogDetail(Controller, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId,
aCommandId, aEndPointId);
ChipLogDetail(Controller,
"Received Cluster Command: Endpoint=%" PRIx16 " Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI,
aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId));
// Nothing todo.
}

bool ServerClusterCommandExists(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId)
bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath)
{
// Mock cluster catalog, only support one command on one cluster on one endpoint.
return (aEndPointId == kTestEndpointId && aClusterId == kTestClusterId && aCommandId == kTestCommandId);
return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == kTestClusterId &&
aCommandPath.mCommandId == kTestCommandId);
}

class TestCommandInteraction
Expand Down
13 changes: 7 additions & 6 deletions src/app/tests/integration/chip_im_initiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,22 +620,23 @@ class MockInteractionModelApp : public chip::app::InteractionModelDelegate
namespace chip {
namespace app {

bool ServerClusterCommandExists(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId)
bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath)
{
// Always return true in test.
return true;
}

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj)
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj)
{
// Nothing todo.
}

void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandSender * apCommandObj)
void DispatchSingleClusterResponseCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandSender * apCommandObj)
{
if (aClusterId != kTestClusterId || aCommandId != kTestCommandId || aEndPointId != kTestEndpointId)
if (aCommandPath.mClusterId != kTestClusterId || aCommandPath.mCommandId != kTestCommandId ||
aCommandPath.mEndpointId != kTestEndpointId)
{
return;
}
Expand Down
20 changes: 11 additions & 9 deletions src/app/tests/integration/chip_im_responder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,19 @@
namespace chip {
namespace app {

bool ServerClusterCommandExists(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId)
bool ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath)
{
// The Mock cluster catalog -- only have one command on one cluster on one endpoint.
return (aEndPointId == kTestEndpointId && aClusterId == kTestClusterId && aCommandId == kTestCommandId);
return (aCommandPath.mEndpointId == kTestEndpointId && aCommandPath.mClusterId == kTestClusterId &&
aCommandPath.mCommandId == kTestCommandId);
}

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj)
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj)
{
static bool statusCodeFlipper = false;

if (aClusterId != kTestClusterId || aCommandId != kTestCommandId || aEndPointId != kTestEndpointId)
if (!ServerClusterCommandExists(aCommandPath))
{
return;
}
Expand Down Expand Up @@ -100,11 +101,12 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC
statusCodeFlipper = !statusCodeFlipper;
}

void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, CommandSender * apCommandObj)
void DispatchSingleClusterResponseCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandSender * apCommandObj)
{
ChipLogDetail(Controller, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId,
aCommandId, aEndPointId);
ChipLogDetail(Controller,
"Received Cluster Command: Endpoint=%" PRIx16 " Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI,
aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId));
// Nothing todo.
}

Expand Down
12 changes: 6 additions & 6 deletions src/app/util/ember-compatibility-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,17 @@ EmberAfAttributeType BaseType(EmberAfAttributeType type)

} // namespace

void SetupEmberAfObjects(Command * command, ClusterId clusterId, CommandId commandId, EndpointId endpointId)
void SetupEmberAfObjects(Command * command, const ConcreteCommandPath & commandPath)
{
Messaging::ExchangeContext * commandExchangeCtx = command->GetExchangeContext();

imCompatibilityEmberApsFrame.clusterId = clusterId;
imCompatibilityEmberApsFrame.destinationEndpoint = endpointId;
imCompatibilityEmberApsFrame.clusterId = commandPath.mClusterId;
imCompatibilityEmberApsFrame.destinationEndpoint = commandPath.mEndpointId;
imCompatibilityEmberApsFrame.sourceEndpoint = 1; // source endpoint is fixed to 1 for now.
imCompatibilityEmberApsFrame.sequence =
(commandExchangeCtx != nullptr ? static_cast<uint8_t>(commandExchangeCtx->GetExchangeId() & 0xFF) : 0);

imCompatibilityEmberAfCluster.commandId = commandId;
imCompatibilityEmberAfCluster.commandId = commandPath.mCommandId;
imCompatibilityEmberAfCluster.apsFrame = &imCompatibilityEmberApsFrame;
imCompatibilityEmberAfCluster.interPanHeader = &imCompatibilityInterpanHeader;
imCompatibilityEmberAfCluster.source = commandExchangeCtx;
Expand Down Expand Up @@ -184,11 +184,11 @@ namespace {
uint8_t attributeData[kAttributeReadBufferSize];
} // namespace

bool ServerClusterCommandExists(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId)
bool 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(aEndPointId, aClusterId);
return emberAfContainsServer(aCommandPath.mEndpointId, aCommandPath.mClusterId);
}

CHIP_ERROR ReadSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVWriter * apWriter, bool * apDataExists)
Expand Down
3 changes: 2 additions & 1 deletion src/app/util/ember-compatibility-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
#pragma once

#include <app/Command.h>
#include <app/ConcreteCommandPath.h>
#include <app/util/af-types.h>
#include <lib/core/CHIPCore.h>

namespace chip {
namespace app {
namespace Compatibility {

void SetupEmberAfObjects(Command * command, ClusterId clusterId, CommandId commandId, EndpointId endpointId);
void SetupEmberAfObjects(Command * command, const ConcreteCommandPath & commandPath);
bool IMEmberAfSendDefaultResponseWithCallback(EmberAfStatus status);
void ResetEmberAfObjects();

Expand Down
58 changes: 32 additions & 26 deletions src/app/zap-templates/templates/app/im-cluster-command-handler.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -89,64 +89,70 @@ void Dispatch{{asUpperCamelCase side}}Command({{#if (isServer side)}}CommandHand

} // namespace Clusters

void DispatchSingleClusterCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId,
TLV::TLVReader & aReader, CommandHandler * apCommandObj)
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aReader, CommandHandler * apCommandObj)
{
ChipLogDetail(Zcl, "Received Cluster Command: Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI " Endpoint=%" PRIx16, ChipLogValueMEI(aClusterId),
ChipLogValueMEI(aCommandId), aEndPointId);
Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId);
ConcreteCommandPath commandPath(aEndPointId, aClusterId, aCommandId);
ChipLogDetail(Zcl, "Received Cluster Command: Endpoint=%" PRIx16 " Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI, aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId));

Compatibility::SetupEmberAfObjects(apCommandObj, aCommandPath);

TLV::TLVType dataTlvType;
SuccessOrExit(aReader.EnterContainer(dataTlvType));
switch (aClusterId)
switch (aCommandPath.mClusterId)
{
{{#chip_server_clusters}}
{{#if (user_cluster_has_enabled_command name side)}}
case Clusters::{{asUpperCamelCase name}}::Id:
Clusters::{{asUpperCamelCase name}}::Dispatch{{asUpperCamelCase side}}Command(apCommandObj, commandPath, aReader);
Clusters::{{asUpperCamelCase name}}::Dispatch{{asUpperCamelCase side}}Command(apCommandObj, aCommandPath, aReader);
break;
{{/if}}
{{/chip_server_clusters}}
default:
// Unrecognized cluster ID, error status will apply.
apCommandObj->AddStatusCode(commandPath, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id,
Protocols::InteractionModel::Status::InvalidCommand);
ChipLogError(Zcl, "Unknown cluster %" PRIx32, aClusterId);
ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandPath.mClusterId));
apCommandObj->AddStatusCode(
aCommandPath,
Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::InteractionModel::Id,
Protocols::InteractionModel::Status::UnsupportedCluster
);
break;
}

exit:
Compatibility::ResetEmberAfObjects();
aReader.ExitContainer(dataTlvType);
Compatibility::ResetEmberAfObjects();
}

void DispatchSingleClusterResponseCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId,
TLV::TLVReader & aReader, CommandSender * apCommandObj)
void DispatchSingleClusterResponseCommand(const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aReader, CommandSender * apCommandObj)
{
ChipLogDetail(Zcl, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId,
aCommandId, aEndPointId);
Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId);
ConcreteCommandPath commandPath(aEndPointId, aClusterId, aCommandId);
ChipLogDetail(Zcl, "Received Cluster Command: Endpoint=%" PRIx16 " Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI, aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId));

Compatibility::SetupEmberAfObjects(apCommandObj, aCommandPath);

TLV::TLVType dataTlvType;
SuccessOrExit(aReader.EnterContainer(dataTlvType));
switch (aClusterId)
switch (aCommandPath.mClusterId)
{
{{#chip_client_clusters}}
{{#if (user_cluster_has_enabled_command name side)}}
case Clusters::{{asUpperCamelCase name}}::Id:
Clusters::{{asUpperCamelCase name}}::Dispatch{{asUpperCamelCase side}}Command(apCommandObj, commandPath, aReader);
Clusters::{{asUpperCamelCase name}}::Dispatch{{asUpperCamelCase side}}Command(apCommandObj, aCommandPath, aReader);
break;
{{/if}}
{{/chip_client_clusters}}
default:
// Unrecognized cluster ID, error status will apply.
apCommandObj->AddStatusCode(commandPath, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id,
Protocols::InteractionModel::Status::InvalidCommand);
ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aClusterId));
ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandPath.mClusterId));
apCommandObj->AddStatusCode(
aCommandPath,
Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::InteractionModel::Id,
Protocols::InteractionModel::Status::UnsupportedCluster
);
break;
}

exit:
Compatibility::ResetEmberAfObjects();
aReader.ExitContainer(dataTlvType);
Compatibility::ResetEmberAfObjects();
}

} // namespace app
Expand Down
Loading