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.

Z-Stack 2.4 - ZCL Read attribute issue

Other Parts Discussed in Thread: Z-STACK

Hello,

 

I'm developing a ZigBee Home Automation compliant application. I'd like to be able to send a "READ attribute" command to one of the connected device (an On/Off switch).

 

zclReadCmd_t * readCmd;

readCmd = osal_mem_alloc(sizeof(zclReadCmd_t) + sizeof(uint16));
if(readCmd)
{
readCmd->numAttr = 1;
readCmd->attrID[0] = ATTRID_ON_OFF;                
                           
zcl_SendRead(HOMIPRL_ENDPOINT, &addr, ZCL_CLUSTER_ID_GEN_ON_OFF, readCmd, ZCL_FRAME_CLIENT_SERVER_DIR, 0, 0);
                           
osal_mem_free(readCmd);
}

This code works. I receive the right cluster and value. But if I retry this same piece of code, the osal_mem_alloc returns NULL.

First I thank that it comes from somewhere else in the code but curiously if I increase the size to allocate in the previous mem_alloc (+10 instead of sizeof(uint16)) the code works fine and we can go through this read command many times with no issue.

So I'd like to know if anyone knows where we can find more information about the ZCL. I've searched in the docs, there's only one (Z-Stack ZCL API) but it doesn't cover the READ attributes. There's no information at all on read, write etc attributes commands, callbacks etc.

If someone from Ti reads me, it would be great to have more documentation on this subject. I've heard about a zcl_testapp.c that has never been added to the Z-Stack.

 

Thanks for your support,

Regards,

Michaël Ughetti

 

  • Dear Michael,

        Did you get any answer regarding the problem you reported here?

        I'm involved in a similar project and so far I could find sufficient information about ATTRBUTES (general and special), out to use them, etc..

        Your help (and others too of course) would be appreciated.

    Regards,

    RSM

     

     

  • Hi Rodrigo,

     

    No I didn't got any support from Ti but I manage to find my own answers ;).

    There's almost no information on Attributes in Ti's documentation. So I've read their Zstack attributes code to find how to use it.

    Can you please make a summary of what you are trying to do with attributes and precise questions ?

     

    Are you familiar with Zstack ?

    Are you using a known profile ? ie. Home Automation (like me) or Smart Energy etc.

     

    Best regards,

    Michaël

  • Hi Michael,

    Thank you for your quick answer.

    I'm using the public HA profile. I already managed to make binds between routers / coordinator, etc.

    The problem is that when a bind is made, I would like to get an attrbute value from one device to another. Imagine the following scenario:

    Device 1 - Box with buttons

    Device 2 - Box with 2 relays for lighting control and 1 button

     

    Here are the steps I've implemented:

    1. Start binding process by pressing a button on Device 1

    2. Select on Device 1 the button you want to associate to the bind's future actions

    3. Select on Device 2 which relay output you want to actuate

    4. (Not Yet Impemented) Device 1 requests from Device 2 a specific/special attribute value (for example, type of function: ON/OFF/TOGGLE)

    5. (Not Yet Impemented) Device 2 responds to Device 1 with requested attributte's value

    Problem: Guarantee that functions on topic 4 and 5 can be made without compromising compatibility with other manufacturer's ZigBee HA ready devices.

    Regards,

    Rodrigo

     

  • Rodrigo,

     

    OK that's pretty simple. I'm doing almost the same thing.

    Did you read the HA code examples in the Zstack directory ? Check the Sample Light, you'll find a file named zcl_samplelight_data.c. In this file, there are HA declarations. You should start from this to define HA attributes and be compatible with other manufacturer's HA devices.

    For your application (device2), the interesting attribute is :

    // *** On/Off Cluster Attributes ***
      {
        ZCL_CLUSTER_ID_GEN_ON_OFF,
        { // Attribute record
          ATTRID_ON_OFF,
          ZCL_DATATYPE_UINT8,
          ACCESS_CONTROL_READ,
          (void *)&zclSampleLight_OnOff
        }
      },

    This defines the attribute "OnOff" of cluster "Generic On/Off" in read access and gives the pointer to the variable in which you can find the status.

    Below, there's the definition of clusters implemented in input and output :

    const cId_t zclSampleLight_InClusterList[ZCLSAMPLELIGHT_MAX_INCLUSTERS] =
    {
      ...
      ZCL_CLUSTER_ID_GEN_ON_OFF,
    };

    And below there's a SimpleDescriptionFormat_t structure that describe the device type and gives the in and out clusters list.

     

    May be you've already seen this so I'll directly jump to the read process (device1).

    In you main source file, you should have functions :

    zclyourapp_ProcessIncomingMsg

    zclyourapp_ProcessInReadRspCmd

    See the SampleLight example for the whole process.

     

    The only thing they don't show you in this example is how to read an attribute. Reading an attribute is done in an asynchronous way since you don't want Device1 to be stuck waiting for Device2 answer.

    For the read :

    afAddrType_t addr;
    addr.endPoint = APP_ENDPOINT;
    addr.addrMode = (afAddrMode_t) afAddr16Bit;
    addr.addr.shortAddr = device2_shortaddr;

    zclReadCmd_t readCmd;
    readCmd.numAttr = 1;
    readCmd.attrID[0] = 0;                // Attribute ID of OnOff in Cluster Gen On/Off is 0 (see ZigBee Cluster Library spec)
    zcl_SendRead(APP_ENDPOINT, &addr, ZCL_CLUSTER_ID_GEN_ON_OFF, &readCmd, ZCL_FRAME_CLIENT_SERVER_DIR, TRUE, 0);

     

    When the answer is received, the Zstack sends it to your ProcessIncomingMsg and your receive it through :

    static uint8 zclyourapp_ProcessInReadRspCmd(zclIncomingMsg_t *pInMsg)
    {
      zclReadRspCmd_t * readRspCmd;
      readRspCmd = (zclReadRspCmd_t *) pInMsg->attrCmd;
     
      switch(pInMsg->clusterId)
      {
      case ZCL_CLUSTER_ID_GEN_ON_OFF:
        {
          uint8 onoff = * ((uint8 *) readRspCmd->attrList[0].data);
          // And that's OK !
        }
      break;
      }
      return TRUE;
    }

     

    So basically, you just have to declare your attributes on device2 and the Zstack will handle the read process. For device1 you implement the two steps I show you and that should be OK.

    Pay attention that ZCL_READ should be defined in f8wZCL.cfg (-DZCL_READ).

     

    Tell me if you don't understand something. I know that's a lot of information ;)

    Good luck !

     

    Michaël

  • Hi Michael,

    Thanks a lot for this very usefull information.

    How could I create a manufacturer-specific atribute instead of using an already defined profile attribute as the ATTRIB_ON_OFF you described.

    The purpose is for example, to request from Device 2 which RELAY was selected to be actuated (RELAY 1 or 2). Also current power consumption from selected RELAY could be requested.

    Regards,

    Rodrigo

     

  • Dear Michael,

        This is a second reply. Please read my previous reply to your post.

        In the NXP_JENNIC "ZigBee Cluster Library User Guide" I found that they have a more complete function to deal with Attribute Read process. The function includes the bool_t bIsManufacturerSpecific and u16ManufacturerCode parameters, that can be used to tell whether we are dealing with a manufacturer specific attribute or not. Maybe in TI API this is supposed to be made in a different way or masked. I cannot find any different function (command) or code example from TI for manufacturer's specific attributes usage.

    # JENNIC SendReadAttributesRequest( ) function definition:

    teZCL_Status eZCL_SendReadAttributesRequest(
    uint8 u8SourceEndPointId,
    uint8 u8DestinationEndPointId,
    uint16 u16ClusterId,
    bool_t bDirectionIsServerToClient,
    tsZCL_Address *psDestinationAddress,
    uint8 *pu8TransactionSequenceNumber,
    uint8 u8NumberOfAttributesInRequest,
    bool_t bIsManufacturerSpecific,
    uint16 u16ManufacturerCode,
    uint16 *pu16AttributeRequestList);

     

        I also found a Power Point presentation from ZigBee Alliance where manufacturers specific profiles, commands and attributes are well explained and some Manufacturer's Specific attributes already implemented from Digi International and Ember.

    regards,

    Rodrigo

  • Hi Michael,

        Please read also previous replies.

        In zcl.c source code file I found that TI's implementation of the SendRead function left behind the possibility to use manufacturer specific attributes. See below:

    /*line:821

    status = zcl_SendCommand( srcEP, dstAddr, clusterID, ZCL_CMD_READ, FALSE,
                                  direction, disableDefaultRsp, 0, seqNum, dataLen, buf );

    You can see above that zcl_SendCommand function call inside zcl_SendRead function that the specific and manucode parameters are HARDCODED to FALSE and 0. This means that no specific commands can be send and no specific manufacturer codes can be used with zcl_SendRead function.

    /*line:650
    /*********************************************************************
     * @fn      zcl_SendCommand
     *
     * @brief   Used to send Profile and Cluster Specific Command messages.
     *
     *          NOTE: The calling application is responsible for incrementing
     *                the Sequence Number.
     *
     * @param   srcEp - source endpoint
     * @param   destAddr - destination address
     * @param   clusterID - cluster ID
     * @param   cmd - command ID
     * @param   specific - whether the command is Cluster Specific
     * @param   direction - client/server direction of the command
     * @param   disableDefaultRsp - disable Default Response command
     * @param   manuCode - manufacturer code for proprietary extensions to a profile
     * @param   seqNumber - identification number for the transaction
     * @param   cmdFormatLen - length of the command to be sent
     * @param   cmdFormat - command to be sent
     *
     * @return  ZSuccess if OK
     */
    ZStatus_t zcl_SendCommand( uint8 srcEP, afAddrType_t *destAddr,
                               uint16 clusterID, uint8 cmd, uint8 specific, uint8 direction,
                               uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
                               uint16 cmdFormatLen, uint8 *cmdFormat )

     

    Am I correct?

    regards,

    Rodrigo

  • Hi Rodrigo,

    I've just read all your answers. Yes I think you're correct in the last one. I've never used Manufacturer specific clusters but I would have told you that it's possible if you use directly the layer below the ZCL. The ZCL has it's name says is the generic clusters defined for cross manufacturer compatibility. So if you want to do manufacturer specific, use the layer below.

    You should also check the official Zigbee Cluster Library documentation. If I remember well, they give cluster IDs reserved for manufacturer specific.

     

    Glad to see you're moving forward ;)

    Regards,

    Michaël

     

  • Hi Michael,

     

    That's where the problem is. I don't want to use manufacturer specific cluster or profile. I must use ZigBee public HA profile. What I need is to use a manufacturer specific attribute because I must change some information from Device 2 to Device 1 every time a binding is established between two end-points.

    Have you crossed your eyes trough any sample code about this or implemented something similar?

    Regards,

    Rodrigo

     

  • Hi Rodrigo,

    I'm afraid I can't help you from this point.

    If you want to continue using Home Automation, I know that there are generic clusters like ZCL_CLUSTER_ID_GEN_BINARY_INPUT_BASIC. These clusters are defined in HA, they define a type of data in input or output and you can use them as you want. But if you want to keep compatibility with other manufacturers' devices, it won't work.

    You may also look whether it's possible or not to implement the same cluster in different applications/endpoints. This may be a way to deal with your two relays separately since they need the same cluster.

    Sorry, I can't help you more than that. Anyway, it doesn't seem that manufacturers are building fully compatible ZigBee products. In fact, everyone is doing its own implementation, running on different channels or with different security parameters. So that's difficult to build something fully compatible.

    Good luck,

    Michaël

     

  • HI Rodrigo, 

    i trying to design the ZED like you. I have problem also in the HA Profile. 

    i have a commercial ZC (Zigbee Gateway), i  found in the protocol that the ZED joined in the ZC network, after it i sent ZCL command :to on/of

    ZCL_HA_PROFILE_ID 0x0104

    ZCL_CLUSTER_ID_GEN_ON_OFF     0x0006

    but the ZED didnt answer the command. I think that you had a same problem in the past.

    You can share with me the solution that you found?

    Br

    Alex

  • Hi Michaël,

    I am having a similar issue as you had.  That is, he first time I make the call to zcl_SendRead, it works and I see the response, but any further calls to the exact same code (with exception of incremented sequence number) results in no read response.

    Different from you, the call to osal_mem_alloc did return memory okay, as opposed to your seeing NULL returned.

    Regardless, I tried increasing the amount of memory allocated to 14 instead of the initial 4 (uint8 numAttr, alignment byte, uint16 attrID array bytes, 10 extra bytes) and it is still failing to get a response for any call to zcl_SendRead after the first.

    Any thoughts, ideas?

    Jeff

  • Hi Jeff,
    This is an pretty old thread after it's original post. I don't see related issue in latest Z-Stack so can you specify which Z-Stack version and example you test this? By the way, it seems memory issue that causes your trouble so I suggest you to check if your application keep allocating memory without free it.
  • Hi All,

    I was going through this post and I have a similar requirement.

    I have a zigbee coordinator that runs HAgateway application given by TI. I have an ON/OFF switch. I am able to turn ON/OFF the switch using the HAgateway application on key press 'N/F'.

    Now, if I manually operate the switch ON/OFF, I want the current status to be displayed by HAgateway application. In the sniffer I can see some data being sent by the switch when I manually switch ON/OFF, I think the switch is sending the current status (I am assuming default behavior for HA 1.2 profile), but HA gateway code needs to be modified to display the current status.

    My question is If I just handle IncomingMsgRsp, will it be sufficient? Do I need to bind the endpoint in device with endpoint in Hagateway (coordinator). Also the first question is does the device send current status when it is manually operated.

    I also have a basic question, from the above replies, I read that we get IncomingMsg and IncomingMsgRsp and the attribute is read in IncomingMsgRsp instead of IncomingMsg. I am confused in this part.

    Thanks

    Sonal

  • Yes, you need to bind the endpoint in device with endpoint in Hagateway .
  • Thanks YK Chen,

    After I perform bind on endpoints, I will receive the current value of switch automatically from switch without sending command to read attribute. Is my understanding correct? Does it need any configuration done on switch?

    Thanks
    Sonal
  • Your understanding is correct and you shouldn't have to do any configuration on switch.