Part Number: CC2652R7
Tool/software:
With respect to the Get Group Membership ZCL command and response, the ZCL (rev 7/8) states:
Section 3.6.2.3.4.2 (Effect on Receipt)
On receipt of the get group membership command, each receiving entity SHALL respond with group mem-
bership information using the get group membership response frame as follows:
If the group count field of the command frame has a value of 0 indicating that the group list field is empty,
the entity SHALL respond with all group identifiers of which the entity is a member.
If the group list field of the command frame contains at least one group of which the entity is a member, the
entity SHALL respond with each entity group identifier that match a group in the group list field.
If the group count is non-zero, and the group list field of the command frame does not contain any group of
which the entity is a member, the entity SHALL only respond if the command is unicast. The response
SHALL return a group count of zero.
Regarding the final case, if a client sends a get group membership command with one or more groups, and the receiving device has no groups that match those in the command, then it should send a response with group count == 0.
The current ZStack does not send a response in this scenario. The relevant code is in `source/ti/zstack/stack/zcl/zcl_general.c`:
case COMMAND_GROUPS_GET_GROUP_MEMBERSHIP:
{
grpCnt = *pData++;
// Allocate space for the group list
grpList = zcl_mem_alloc( sizeof( uint16_t ) * APS_MAX_GROUPS );
if ( grpList != NULL )
{
if ( grpCnt == 0 )
{
// Find out all the groups of which the endpoint is a member.
grpRspCnt = aps_FindAllGroupsForEndpoint( pInMsg->msg->endPoint, grpList );
}
else
{
// Find out the groups (in the list) of which the endpoint is a member.
for ( i = 0; i < grpCnt; i++ )
{
group.ID = BUILD_UINT16( pData[0], pData[1] );
pData += 2;
if ( aps_FindGroup( pInMsg->msg->endPoint, group.ID ) )
grpList[grpRspCnt++] = group.ID;
}
}
if ( grpCnt == 0 || grpRspCnt != 0 )
{
zclGeneral_SendGroupGetMembershipResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
aps_GroupsRemaingCapacity(), grpRspCnt,
grpList, true, pInMsg->hdr.transSeqNum );
}
zcl_mem_free( grpList );
}
else
{
// Couldn't allocate space for the group list -- send a Default Response command back.
zclDefaultRspCmd_t defaultRspCmd;
defaultRspCmd.commandID = pInMsg->hdr.commandID;
defaultRspCmd.statusCode = ZCL_STATUS_INSUFFICIENT_SPACE;
zcl_SendDefaultRspCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
pInMsg->msg->clusterId, &defaultRspCmd,
ZCL_FRAME_SERVER_CLIENT_DIR, true, 0, pInMsg->hdr.transSeqNum );
}
stat = ZCL_STATUS_CMD_HAS_RSP;
}
break;
The correct4 behavior can be implemented by changing:
if ( grpCnt == 0 || grpRspCnt != 0 )
to:
if ( grpCnt == 0 || grpRspCnt != 0 || !pInMsg->msg->wasBroadcast )