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

Include identify server cluster into lighting-app #8512

Closed
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
176 changes: 176 additions & 0 deletions examples/lighting-app/lighting-common/gen/IMClusterCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,179 @@ void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aComman

} // namespace GeneralCommissioning

namespace Identify {

void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
TLV::TLVReader & aDataTlv)
{
// We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
// When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
// Any error value TLVUnpackError means we have received an illegal value.
// The following variables are used for all commands to save code size.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint32_t validArgumentCount = 0;
uint32_t expectArgumentCount = 0;
uint32_t currentDecodeTagId = 0;
bool wasHandled = false;
{
switch (aCommandId)
{
case Clusters::Identify::Commands::Ids::Identify: {
expectArgumentCount = 1;
uint16_t identifyTime;
bool argExists[1];

memset(argExists, 0, sizeof argExists);

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
// Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
// Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
if (!TLV::IsContextTag(aDataTlv.GetTag()))
{
continue;
}
currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
if (currentDecodeTagId < 1)
{
if (argExists[currentDecodeTagId])
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
else
{
argExists[currentDecodeTagId] = true;
validArgumentCount++;
}
}
switch (currentDecodeTagId)
{
case 0:
TLVUnpackError = aDataTlv.Get(identifyTime);
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (CHIP_NO_ERROR != TLVUnpackError)
{
break;
}
}

if (CHIP_END_OF_TLV == TLVError)
{
// CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
TLVError = CHIP_NO_ERROR;
}

if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
wasHandled = emberAfIdentifyClusterIdentifyCallback(aEndpointId, apCommandObj, identifyTime);
}
break;
}
case Clusters::Identify::Commands::Ids::IdentifyQuery: {

wasHandled = emberAfIdentifyClusterIdentifyQueryCallback(aEndpointId, apCommandObj);
break;
}
case Clusters::Identify::Commands::Ids::TriggerEffect: {
expectArgumentCount = 2;
uint8_t effectId;
uint8_t effectVariant;
bool argExists[2];

memset(argExists, 0, sizeof argExists);

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
// Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
// Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
if (!TLV::IsContextTag(aDataTlv.GetTag()))
{
continue;
}
currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
if (currentDecodeTagId < 2)
{
if (argExists[currentDecodeTagId])
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
else
{
argExists[currentDecodeTagId] = true;
validArgumentCount++;
}
}
switch (currentDecodeTagId)
{
case 0:
TLVUnpackError = aDataTlv.Get(effectId);
break;
case 1:
TLVUnpackError = aDataTlv.Get(effectVariant);
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (CHIP_NO_ERROR != TLVUnpackError)
{
break;
}
}

if (CHIP_END_OF_TLV == TLVError)
{
// CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
TLVError = CHIP_NO_ERROR;
}

if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
wasHandled = emberAfIdentifyClusterTriggerEffectCallback(aEndpointId, apCommandObj, effectId, effectVariant);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::Identify::Id, aCommandId);
return;
}
}
}

if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
{
chip::app::CommandPathParams returnStatusParam = { aEndpointId,
0, // GroupId
Clusters::Identify::Id, aCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
ChipLogProgress(Zcl,
"Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
// A command with no arguments would never write currentDecodeTagId. If
// progress logging is also disabled, it would look unused. Silence that
// warning.
UNUSED_VAR(currentDecodeTagId);
}
}

} // namespace Identify

namespace LevelControl {

void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
Expand Down Expand Up @@ -3824,6 +3997,9 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC
case Clusters::GeneralCommissioning::Id:
clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
case Clusters::Identify::Id:
clusters::Identify::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
case Clusters::LevelControl::Id:
clusters::LevelControl::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
Expand Down
30 changes: 23 additions & 7 deletions examples/lighting-app/lighting-common/gen/af-gen-event.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

// Code used to configure the cluster event mechanism
#define EMBER_AF_GENERATED_EVENT_CODE \
EmberEventControl emberAfIdentifyClusterServerTickCallbackControl1; \
EmberEventControl emberAfLevelControlClusterServerTickCallbackControl1; \
extern EmberEventControl emberAfPluginColorControlServerHueSatTransitionEventControl; \
extern EmberEventControl emberAfPluginColorControlServerTempTransitionEventControl; \
Expand All @@ -55,30 +56,45 @@
(*callback)(endpoint); \
/* emberAfPopNetworkIndex(); */ \
} \
\
void emberAfIdentifyClusterServerTickCallbackWrapperFunction1(void) \
{ \
clusterTickWrapper(&emberAfIdentifyClusterServerTickCallbackControl1, emberAfIdentifyClusterServerTickCallback, 1); \
} \
void emberAfLevelControlClusterServerTickCallbackWrapperFunction1(void) \
{ \
clusterTickWrapper(&emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallback, \
1); \
} \
EmberEventControl emberAfPluginZllIdentifyServerTriggerEffectEndpointEventControls[1]; \
extern void emberAfPluginZllIdentifyServerTriggerEffectEndpointEventHandler(EndpointId endpoint); \
void emberAfPluginZllIdentifyServerTriggerEffectEndpointEventWrapper1(void) \
{ \
clusterTickWrapper(&emberAfPluginZllIdentifyServerTriggerEffectEndpointEventControls[0], \
emberAfPluginZllIdentifyServerTriggerEffectEndpointEventHandler, 1); \
}

// EmberEventData structs used to populate the EmberEventData table
#define EMBER_AF_GENERATED_EVENTS \
{ &emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallbackWrapperFunction1 }, \
{ &emberAfIdentifyClusterServerTickCallbackControl1, emberAfIdentifyClusterServerTickCallbackWrapperFunction1 }, \
{ &emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallbackWrapperFunction1 }, \
{ &emberAfPluginColorControlServerHueSatTransitionEventControl, \
emberAfPluginColorControlServerHueSatTransitionEventHandler }, \
{ &emberAfPluginColorControlServerTempTransitionEventControl, emberAfPluginColorControlServerTempTransitionEventHandler }, \
{ &emberAfPluginColorControlServerXyTransitionEventControl, emberAfPluginColorControlServerXyTransitionEventHandler },
{ &emberAfPluginColorControlServerXyTransitionEventControl, emberAfPluginColorControlServerXyTransitionEventHandler }, \
{ &emberAfPluginZllIdentifyServerTriggerEffectEndpointEventControls[0], \
emberAfPluginZllIdentifyServerTriggerEffectEndpointEventWrapper1 },

#define EMBER_AF_GENERATED_EVENT_STRINGS \
"Level Control Cluster Server EP 1", "Color Control Cluster Server Plugin HueSatTransition", \
"Color Control Cluster Server Plugin TempTransition", "Color Control Cluster Server Plugin XyTransition",
"Identify Cluster Server EP 1", "Level Control Cluster Server EP 1", "Color Control Cluster Server Plugin HueSatTransition", \
"Color Control Cluster Server Plugin TempTransition", "Color Control Cluster Server Plugin XyTransition", \
"ZLL Identify Server Plugin TriggerEffect EP 1",

// The length of the event context table used to track and retrieve cluster events
#define EMBER_AF_EVENT_CONTEXT_LENGTH 1
#define EMBER_AF_EVENT_CONTEXT_LENGTH 2

// EmberAfEventContext structs used to populate the EmberAfEventContext table
#define EMBER_AF_GENERATED_EVENT_CONTEXT \
{ 0x1, 0x8, false, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP, &emberAfLevelControlClusterServerTickCallbackControl1 },
{ 0x1, 0x3, false, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP, &emberAfIdentifyClusterServerTickCallbackControl1 }, \
{ 0x1, 0x8, false, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP, &emberAfLevelControlClusterServerTickCallbackControl1 },

#endif // __AF_GEN_EVENT__
8 changes: 8 additions & 0 deletions examples/lighting-app/lighting-common/gen/callback-stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId)
case ZCL_GENERAL_DIAGNOSTICS_CLUSTER_ID:
emberAfGeneralDiagnosticsClusterInitCallback(endpoint);
break;
case ZCL_IDENTIFY_CLUSTER_ID:
emberAfIdentifyClusterInitCallback(endpoint);
break;
case ZCL_LEVEL_CONTROL_CLUSTER_ID:
emberAfLevelControlClusterInitCallback(endpoint);
break;
Expand Down Expand Up @@ -106,6 +109,11 @@ void __attribute__((weak)) emberAfGeneralDiagnosticsClusterInitCallback(Endpoint
// To prevent warning
(void) endpoint;
}
void __attribute__((weak)) emberAfIdentifyClusterInitCallback(EndpointId endpoint)
{
// To prevent warning
(void) endpoint;
}
void __attribute__((weak)) emberAfLevelControlClusterInitCallback(EndpointId endpoint)
{
// To prevent warning
Expand Down
Loading