Skip to content

Commit 5bad4ed

Browse files
Groups cluster server implemented using the Group Data provider. (project-chip#11132)
* Groups cluster server implemented using the Group Data provider. * Groups cluster server: Review comments applied. * Groups cluster server: Review comments applied. * Groups cluster server: Review comments applied. * Groups cluster server: Review comments applied. * Groups cluster server: Rebased.
1 parent b32e41a commit 5bad4ed

File tree

35 files changed

+1866
-506
lines changed

35 files changed

+1866
-506
lines changed

examples/chip-tool/templates/tests.js

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ function getTests()
184184
'TestDescriptorCluster',
185185
'TestBasicInformation',
186186
'TestIdentifyCluster',
187+
'TestGroupsCluster',
187188
'TestOperationalCredentialsCluster',
188189
'TestModeSelectCluster',
189190
'TestGroupMessaging',

src/app/clusters/groups-server/groups-server.cpp

+226-283
Large diffs are not rendered by default.

src/app/clusters/groups-server/groups-server.h

+1-31
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,6 @@
2020
#include <app/util/basic-types.h>
2121
#include <lib/support/Span.h>
2222

23-
/** @brief Get Group Name
24-
*
25-
* This function returns the name of a group with the provided group ID, should
26-
* it exist.
27-
*
28-
* @param endpoint Endpoint Ver.: always
29-
* @param groupId Group ID Ver.: always
30-
* @param groupName Group Name Ver.: always
31-
*/
32-
void emberAfPluginGroupsServerGetGroupNameCallback(chip::EndpointId endpoint, chip::GroupId groupId, uint8_t * groupName);
33-
34-
/** @brief Set Group Name
35-
*
36-
* This function sets the name of a group with the provided group ID.
37-
*
38-
* @param endpoint Endpoint Ver.: always
39-
* @param groupId Group ID Ver.: always
40-
* @param groupName Group Name Ver.: always
41-
*/
42-
void emberAfPluginGroupsServerSetGroupNameCallback(chip::EndpointId endpoint, chip::GroupId groupId,
43-
const chip::CharSpan & groupName);
44-
45-
/** @brief Group Names Supported
46-
*
47-
* This function returns whether or not group names are supported.
48-
*
49-
* @param endpoint Endpoint Ver.: always
50-
*/
51-
bool emberAfPluginGroupsServerGroupNamesSupportedCallback(chip::EndpointId endpoint);
52-
5323
/** @brief Groups Cluster Endpoint In Group
5424
*
5525
* This function is called by the framework when it needs to determine if an
@@ -59,4 +29,4 @@ bool emberAfPluginGroupsServerGroupNamesSupportedCallback(chip::EndpointId endpo
5929
* @param endpoint The endpoint. Ver.: always
6030
* @param groupId The group identifier. Ver.: always
6131
*/
62-
bool emberAfGroupsClusterEndpointInGroupCallback(chip::EndpointId endpoint, chip::GroupId groupId);
32+
bool emberAfGroupsClusterEndpointInGroupCallback(chip::FabricIndex fabricIndex, chip::EndpointId endpoint, chip::GroupId groupId);

src/app/clusters/scenes/scenes.cpp

+38-21
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ uint8_t emberAfPluginScenesServerEntriesInUse = 0;
6565
EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[EMBER_AF_PLUGIN_SCENES_TABLE_SIZE];
6666
#endif
6767

68+
static FabricIndex GetFabricIndex(app::CommandHandler * commandObj)
69+
{
70+
VerifyOrReturnError(nullptr != commandObj, 0);
71+
VerifyOrReturnError(nullptr != commandObj->GetExchangeContext(), 0);
72+
return commandObj->GetExchangeContext()->GetSessionHandle().GetFabricIndex();
73+
}
74+
6875
static bool readServerAttribute(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, const char * name,
6976
uint8_t * data, uint8_t size)
7077
{
@@ -95,10 +102,11 @@ static EmberAfStatus writeServerAttribute(EndpointId endpoint, ClusterId cluster
95102
return status;
96103
}
97104

98-
bool isEndpointInGroup(EndpointId endpoint, GroupId groupId)
105+
bool isEndpointInGroup(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId)
99106
{
100107
#ifdef EMBER_AF_PLUGIN_GROUPS_SERVER
101-
return (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID || emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId));
108+
return (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID ||
109+
emberAfGroupsClusterEndpointInGroupCallback(fabricIndex, endpoint, groupId));
102110
#else
103111
return (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID);
104112
#endif // EMBER_AF_PLUGIN_GROUPS_SERVER
@@ -244,15 +252,16 @@ bool emberAfScenesClusterViewSceneCallback(app::CommandHandler * commandObj, con
244252
bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
245253
const Commands::RemoveScene::DecodableType & commandData)
246254
{
247-
auto & groupId = commandData.groupId;
248-
auto & sceneId = commandData.sceneId;
255+
auto fabricIndex = GetFabricIndex(commandObj);
256+
auto & groupId = commandData.groupId;
257+
auto & sceneId = commandData.sceneId;
249258

250259
EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
251260
CHIP_ERROR err = CHIP_NO_ERROR;
252261

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

255-
if (!isEndpointInGroup(emberAfCurrentEndpoint(), groupId))
264+
if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
256265
{
257266
status = EMBER_ZCL_STATUS_INVALID_FIELD;
258267
}
@@ -302,14 +311,15 @@ bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, c
302311
bool emberAfScenesClusterRemoveAllScenesCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
303312
const Commands::RemoveAllScenes::DecodableType & commandData)
304313
{
305-
auto & groupId = commandData.groupId;
314+
auto fabricIndex = GetFabricIndex(commandObj);
315+
auto & groupId = commandData.groupId;
306316

307317
EmberAfStatus status = EMBER_ZCL_STATUS_INVALID_FIELD;
308318
CHIP_ERROR err = CHIP_NO_ERROR;
309319

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

312-
if (isEndpointInGroup(emberAfCurrentEndpoint(), groupId))
322+
if (isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
313323
{
314324
uint8_t i;
315325
status = EMBER_ZCL_STATUS_SUCCESS;
@@ -354,13 +364,14 @@ bool emberAfScenesClusterRemoveAllScenesCallback(app::CommandHandler * commandOb
354364
bool emberAfScenesClusterStoreSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
355365
const Commands::StoreScene::DecodableType & commandData)
356366
{
357-
auto & groupId = commandData.groupId;
358-
auto & sceneId = commandData.sceneId;
367+
auto fabricIndex = GetFabricIndex(commandObj);
368+
auto & groupId = commandData.groupId;
369+
auto & sceneId = commandData.sceneId;
359370

360371
EmberAfStatus status;
361372
CHIP_ERROR err = CHIP_NO_ERROR;
362373
emberAfScenesClusterPrintln("RX: StoreScene 0x%2x, 0x%x", groupId, sceneId);
363-
status = emberAfScenesClusterStoreCurrentSceneCallback(emberAfCurrentEndpoint(), groupId, sceneId);
374+
status = emberAfScenesClusterStoreCurrentSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);
364375

365376
// Store Scene commands are only responded to when they are addressed to a
366377
// single device.
@@ -389,8 +400,9 @@ bool emberAfScenesClusterStoreSceneCallback(app::CommandHandler * commandObj, co
389400
bool emberAfScenesClusterRecallSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
390401
const Commands::RecallScene::DecodableType & commandData)
391402
{
392-
auto & groupId = commandData.groupId;
393-
auto & sceneId = commandData.sceneId;
403+
auto fabricIndex = GetFabricIndex(commandObj);
404+
auto & groupId = commandData.groupId;
405+
auto & sceneId = commandData.sceneId;
394406

395407
// NOTE: TransitionTime field in the RecallScene command is currently
396408
// ignored. Per Zigbee Alliance ZCL 7 (07-5123-07):
@@ -408,7 +420,7 @@ bool emberAfScenesClusterRecallSceneCallback(app::CommandHandler * commandObj, c
408420
EmberAfStatus status;
409421
EmberStatus sendStatus = EMBER_SUCCESS;
410422
emberAfScenesClusterPrintln("RX: RecallScene 0x%2x, 0x%x", groupId, sceneId);
411-
status = emberAfScenesClusterRecallSavedSceneCallback(emberAfCurrentEndpoint(), groupId, sceneId);
423+
status = emberAfScenesClusterRecallSavedSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);
412424
#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
413425
if (status == EMBER_ZCL_STATUS_SUCCESS)
414426
{
@@ -426,7 +438,8 @@ bool emberAfScenesClusterRecallSceneCallback(app::CommandHandler * commandObj, c
426438
bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
427439
const Commands::GetSceneMembership::DecodableType & commandData)
428440
{
429-
auto & groupId = commandData.groupId;
441+
auto fabricIndex = GetFabricIndex(commandObj);
442+
auto & groupId = commandData.groupId;
430443

431444
CHIP_ERROR err = CHIP_NO_ERROR;
432445
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
@@ -435,7 +448,7 @@ bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * comman
435448

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

438-
if (!isEndpointInGroup(emberAfCurrentEndpoint(), groupId))
451+
if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
439452
{
440453
status = EMBER_ZCL_STATUS_INVALID_FIELD;
441454
}
@@ -485,12 +498,13 @@ bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * comman
485498
return true;
486499
}
487500

488-
EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(EndpointId endpoint, GroupId groupId, uint8_t sceneId)
501+
EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId,
502+
uint8_t sceneId)
489503
{
490504
EmberAfSceneTableEntry entry;
491505
uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
492506

493-
if (!isEndpointInGroup(endpoint, groupId))
507+
if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
494508
{
495509
return EMBER_ZCL_STATUS_INVALID_FIELD;
496510
}
@@ -610,9 +624,10 @@ EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(EndpointId endpoint,
610624
return EMBER_ZCL_STATUS_SUCCESS;
611625
}
612626

613-
EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(EndpointId endpoint, GroupId groupId, uint8_t sceneId)
627+
EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId,
628+
uint8_t sceneId)
614629
{
615-
if (!isEndpointInGroup(endpoint, groupId))
630+
if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
616631
{
617632
return EMBER_ZCL_STATUS_INVALID_FIELD;
618633
}
@@ -755,6 +770,7 @@ bool emberAfPluginScenesServerParseAddScene(
755770
EmberAfSceneTableEntry entry;
756771
EmberAfStatus status;
757772
bool enhanced = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
773+
auto fabricIndex = GetFabricIndex(commandObj);
758774
EndpointId endpoint = cmd->apsFrame->destinationEndpoint;
759775
uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
760776

@@ -764,7 +780,7 @@ bool emberAfPluginScenesServerParseAddScene(
764780
auto fieldSetIter = extensionFieldSets.begin();
765781

766782
// Add Scene commands can only reference groups to which we belong.
767-
if (!isEndpointInGroup(endpoint, groupId))
783+
if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
768784
{
769785
status = EMBER_ZCL_STATUS_INVALID_FIELD;
770786
goto kickout;
@@ -1092,12 +1108,13 @@ bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, c
10921108
EmberAfSceneTableEntry entry = {};
10931109
EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
10941110
bool enhanced = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
1111+
FabricIndex fabricIndex = GetFabricIndex(commandObj);
10951112
EndpointId endpoint = cmd->apsFrame->destinationEndpoint;
10961113

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

10991116
// View Scene commands can only reference groups which we belong to.
1100-
if (!isEndpointInGroup(endpoint, groupId))
1117+
if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
11011118
{
11021119
status = EMBER_ZCL_STATUS_INVALID_FIELD;
11031120
}

src/app/clusters/scenes/scenes.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ bool emberAfPluginScenesServerParseViewScene(chip::app::CommandHandler * command
100100
* @param groupId The group identifier. Ver.: always
101101
* @param sceneId The scene identifier. Ver.: always
102102
*/
103-
EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::EndpointId endpoint, chip::GroupId groupId, uint8_t sceneId);
103+
EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::FabricIndex fabricIndex, chip::EndpointId endpoint,
104+
chip::GroupId groupId, uint8_t sceneId);
104105

105106
/** @brief Scenes Cluster Store Current Scene
106107
*
@@ -114,7 +115,8 @@ EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::EndpointId endp
114115
* @param groupId The group identifier. Ver.: always
115116
* @param sceneId The scene identifier. Ver.: always
116117
*/
117-
EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(chip::EndpointId endpoint, chip::GroupId groupId, uint8_t sceneId);
118+
EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(chip::FabricIndex fabricIndex, chip::EndpointId endpoint,
119+
chip::GroupId groupId, uint8_t sceneId);
118120

119121
/** @brief Scenes Cluster Remove Scenes In Group
120122
*

0 commit comments

Comments
 (0)