This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2652R7: Incorrect behavior of Get Group Membership command

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 )