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

Scenes: emberAfCurrentCommand and emberAfCurrentEndpoint removal #25136

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
154 changes: 61 additions & 93 deletions src/app/clusters/scenes/scenes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ bool emberAfScenesClusterAddSceneCallback(app::CommandHandler * commandObj, cons
auto & sceneName = commandData.sceneName;
auto & extensionFieldSets = commandData.extensionFieldSets;

return emberAfPluginScenesServerParseAddScene(commandObj, emberAfCurrentCommand(), groupId, sceneId, transitionTime, sceneName,
return emberAfPluginScenesServerParseAddScene(commandObj, commandPath, groupId, sceneId, transitionTime, sceneName,
extensionFieldSets);
}

Expand All @@ -241,7 +241,7 @@ bool emberAfScenesClusterViewSceneCallback(app::CommandHandler * commandObj, con
auto & groupId = commandData.groupID;
auto & sceneId = commandData.sceneID;

return emberAfPluginScenesServerParseViewScene(commandObj, emberAfCurrentCommand(), groupId, sceneId);
return emberAfPluginScenesServerParseViewScene(commandObj, commandPath, groupId, sceneId);
}

bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
Expand All @@ -256,7 +256,7 @@ bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, c

emberAfScenesClusterPrintln("RX: RemoveScene 0x%2x, 0x%x", groupId, sceneId);

if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
if (!isEndpointInGroup(fabricIndex, commandPath.mEndpointId, groupId))
{
status = EMBER_ZCL_STATUS_INVALID_COMMAND;
}
Expand All @@ -267,33 +267,27 @@ bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, c
{
EmberAfSceneTableEntry entry;
emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId && entry.sceneId == sceneId)
if (entry.endpoint == commandPath.mEndpointId && entry.groupId == groupId && entry.sceneId == sceneId)
{
entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
emberAfPluginScenesServerSaveSceneEntry(entry, i);
emberAfPluginScenesServerDecrNumSceneEntriesInUse();
emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
emberAfScenesSetSceneCountAttribute(commandPath.mEndpointId, emberAfPluginScenesServerNumSceneEntriesInUse());
status = EMBER_ZCL_STATUS_SUCCESS;
break;
}
}
}

// Remove Scene commands are only responded to when they are addressed to a
// single device.
if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
{
{
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, RemoveSceneResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());
}
}
app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, RemoveSceneResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());

exit:
if (err != CHIP_NO_ERROR)
{
Expand All @@ -313,38 +307,31 @@ bool emberAfScenesClusterRemoveAllScenesCallback(app::CommandHandler * commandOb

emberAfScenesClusterPrintln("RX: RemoveAllScenes 0x%2x", groupId);

if (isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
if (isEndpointInGroup(fabricIndex, commandPath.mEndpointId, groupId))
{
uint8_t i;
status = EMBER_ZCL_STATUS_SUCCESS;
for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
{
EmberAfSceneTableEntry entry;
emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
if (entry.endpoint == commandPath.mEndpointId && entry.groupId == groupId)
{
entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
emberAfPluginScenesServerSaveSceneEntry(entry, i);
emberAfPluginScenesServerDecrNumSceneEntriesInUse();
}
}
emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
emberAfScenesSetSceneCountAttribute(commandPath.mEndpointId, emberAfPluginScenesServerNumSceneEntriesInUse());
}

// Remove All Scenes commands are only responded to when they are addressed
// to a single device.
if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
{
{
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, RemoveAllScenesResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = commandObj->FinishCommand());
}
}
app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, RemoveAllScenesResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = commandObj->FinishCommand());
exit:
if (err != CHIP_NO_ERROR)
{
Expand All @@ -363,23 +350,16 @@ bool emberAfScenesClusterStoreSceneCallback(app::CommandHandler * commandObj, co
EmberAfStatus status;
CHIP_ERROR err = CHIP_NO_ERROR;
emberAfScenesClusterPrintln("RX: StoreScene 0x%2x, 0x%x", groupId, sceneId);
status = emberAfScenesClusterStoreCurrentSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);
status = emberAfScenesClusterStoreCurrentSceneCallback(fabricIndex, commandPath.mEndpointId, groupId, sceneId);

// Store Scene commands are only responded to when they are addressed to a
// single device.
if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
{
{
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, StoreSceneResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());
}
}
app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, StoreSceneResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());
exit:
if (err != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -410,11 +390,11 @@ bool emberAfScenesClusterRecallSceneCallback(app::CommandHandler * commandObj, c

EmberAfStatus status;
emberAfScenesClusterPrintln("RX: RecallScene 0x%2x, 0x%x", groupId, sceneId);
status = emberAfScenesClusterRecallSavedSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);
status = emberAfScenesClusterRecallSavedSceneCallback(fabricIndex, commandPath.mEndpointId, groupId, sceneId);
#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
if (status == EMBER_ZCL_STATUS_SUCCESS)
{
emberAfPluginZllScenesServerRecallSceneZllExtensions(emberAfCurrentEndpoint());
emberAfPluginZllScenesServerRecallSceneZllExtensions(commandPath.mEndpointId);
}
#endif
CHIP_ERROR sendErr = commandObj->AddStatus(commandPath, app::ToInteractionModelStatus(status));
Expand All @@ -438,7 +418,7 @@ bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * comman

emberAfScenesClusterPrintln("RX: GetSceneMembership 0x%2x", groupId);

if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
if (!isEndpointInGroup(fabricIndex, commandPath.mEndpointId, groupId))
{
status = EMBER_ZCL_STATUS_INVALID_COMMAND;
}
Expand All @@ -450,7 +430,7 @@ bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * comman
{
EmberAfSceneTableEntry entry;
emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
if (entry.endpoint == commandPath.mEndpointId && entry.groupId == groupId)
{
sceneList[sceneCount] = entry.sceneId;
sceneCount++;
Expand All @@ -464,7 +444,7 @@ bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * comman
}

{
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, GetSceneMembershipResponse::Id };
app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, GetSceneMembershipResponse::Id };
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
Expand Down Expand Up @@ -738,15 +718,16 @@ struct NullableUnderlyingType<app::DataModel::Nullable<T>>
};

bool emberAfPluginScenesServerParseAddScene(
app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, GroupId groupId, uint8_t sceneId, uint16_t transitionTime,
const CharSpan & sceneName, const app::DataModel::DecodableList<Structs::ExtensionFieldSet::DecodableType> & extensionFieldSets)
app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, GroupId groupId, uint8_t sceneId,
uint16_t transitionTime, const CharSpan & sceneName,
const app::DataModel::DecodableList<Structs::ExtensionFieldSet::DecodableType> & extensionFieldSets)
{
CHIP_ERROR err = CHIP_NO_ERROR;
EmberAfSceneTableEntry entry;
EmberAfStatus status;
bool enhanced = (cmd->commandId == EnhancedAddScene::Id);
bool enhanced = (commandPath.mCommandId == EnhancedAddScene::Id);
auto fabricIndex = commandObj->GetAccessingFabricIndex();
EndpointId endpoint = cmd->apsFrame->destinationEndpoint;
EndpointId endpoint = commandPath.mEndpointId;
uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;

emberAfScenesClusterPrintln("RX: %pAddScene 0x%2x, 0x%x, 0x%2x, \"%.*s\"", (enhanced ? "Enhanced" : ""), groupId, sceneId,
Expand Down Expand Up @@ -1104,26 +1085,19 @@ bool emberAfPluginScenesServerParseAddScene(
status = EMBER_ZCL_STATUS_SUCCESS;

kickout:
// Add Scene commands are only responded to when they are addressed to a
// single device.
if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
{
return true;
}

app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, AddSceneResponse::Id };
if (enhanced)
{
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, AddSceneResponse::Id };
if (enhanced)
{
path = { emberAfCurrentEndpoint(), Scenes::Id, EnhancedAddSceneResponse::Id };
}
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());
path = { commandPath.mEndpointId, Scenes::Id, EnhancedAddSceneResponse::Id };
}
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
SuccessOrExit(err = commandObj->FinishCommand());

exit:
if (err != CHIP_NO_ERROR)
Expand All @@ -1133,15 +1107,15 @@ bool emberAfPluginScenesServerParseAddScene(
return true;
}

bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, GroupId groupId,
uint8_t sceneId)
bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
GroupId groupId, uint8_t sceneId)
{
CHIP_ERROR err = CHIP_NO_ERROR;
EmberAfSceneTableEntry entry = {};
EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
bool enhanced = (cmd->commandId == EnhancedViewScene::Id);
bool enhanced = (commandPath.mCommandId == EnhancedViewScene::Id);
FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex();
EndpointId endpoint = cmd->apsFrame->destinationEndpoint;
EndpointId endpoint = commandPath.mEndpointId;

emberAfScenesClusterPrintln("RX: %pViewScene 0x%2x, 0x%x", (enhanced ? "Enhanced" : ""), groupId, sceneId);

Expand All @@ -1167,10 +1141,10 @@ bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, c
// The status, group id, and scene id are always included in the response, but
// the transition time, name, and extension fields are only included if the
// scene was found.
app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ViewSceneResponse::Id };
app::ConcreteCommandPath path = { commandPath.mEndpointId, Scenes::Id, ViewSceneResponse::Id };
if (enhanced)
{
path = { emberAfCurrentEndpoint(), Scenes::Id, EnhancedViewSceneResponse::Id };
path = { commandPath.mEndpointId, Scenes::Id, EnhancedViewSceneResponse::Id };
}
TLV::TLVWriter * writer = nullptr;
SuccessOrExit(err = commandObj->PrepareCommand(path));
Expand Down Expand Up @@ -1324,12 +1298,6 @@ bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, c
#endif
}

// View Scene commands are only responded to when they are addressed to a
// single device.
if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
{
return true;
}
sendStatus = emberAfSendResponse();
if (EMBER_SUCCESS != sendStatus)
{
Expand Down Expand Up @@ -1358,7 +1326,7 @@ void emberAfScenesClusterRemoveScenesInGroupCallback(EndpointId endpoint, GroupI
entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
emberAfPluginScenesServerSaveSceneEntry(entry, i);
emberAfPluginScenesServerDecrNumSceneEntriesInUse();
emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/app/clusters/scenes/scenes.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ extern EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[];
#endif // Use tokens

bool emberAfPluginScenesServerParseAddScene(
chip::app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, chip::GroupId groupId, uint8_t sceneId,
uint16_t transitionTime, const chip::CharSpan & sceneName,
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, chip::GroupId groupId,
uint8_t sceneId, uint16_t transitionTime, const chip::CharSpan & sceneName,
const chip::app::DataModel::DecodableList<chip::app::Clusters::Scenes::Structs::ExtensionFieldSet::DecodableType> &
extensionFieldSets);
bool emberAfPluginScenesServerParseViewScene(chip::app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd,
chip::GroupId groupId, uint8_t sceneId);
bool emberAfPluginScenesServerParseViewScene(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, chip::GroupId groupId,
uint8_t sceneId);

/** @brief Scenes Cluster Recall Saved Scene
*
Expand Down