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.

CC2538: ZED to ZED command send

Part Number: CC2538
Other Parts Discussed in Thread: Z-STACK

Hi,

I am using CC2538 for development of Zigbee based automation, I am trying to send the existing cluster command from ZED to ZED. It seems it has only 2 directions "ZCL_FRAME_SERVER_CLIENT_DIR" and "ZCL_FRAME_CLIENT_SERVER_DIR" So, I confused about client to client communication.

Please any one clarify me how can I make the ZED to ZED device communication in a setup of  1 ZC and 2 ZED's in a network.

Thank you.

  • "ZCL_FRAME_SERVER_CLIENT_DIR" and "ZCL_FRAME_CLIENT_SERVER_DIR" is nothing to do with ZED to ZED message sent. You can configure SampleLight and SampleSwitch as ZED to join ZC. SampleSwitch still can send SampleLight on/off toggle command.
  • Hi Chen,
    Thank you for your reply and support.
    I tried this its working the toggle of Sample Light End Device from Sample Switch end device.
    Then I tried connecting few more Sample Light End Device to same network, every time its toggling the Same Device. So, I taught its blinded with that.
    But I want to send an ON/Of/Toggle command to different devices using Short Addr and Ext Addr, How can I achieve this?
  • Which Z-Stack version do you use?
  • I suggest you to use end device binding to do this. You can refer to end device binding implementation in SampleLight and SampleSwitch of Z-Stack Home 1.2.2a.
  • Is it possible to make more binding between device or is it only between 2 devices of network.
    I mean if i have 15 devices in my network like ZED1, ZED2,......ZED15, lets imagine ZED1 is binded with ZED2 so these 2 well communicating, now can I bind ZED1 with ZED3.
    I think its not possible I want confirmation.
  • Yes, it is possible.
  • Hi Chen,
    Thank you for clarify, then in the same above scenario can ZED1 bind with all other devices from ZED2, ZED3,..... ZED15. and what is the maximum number of binds an ZC, ZR and ZED individually support.
  • It’s defined by “-DNWK_MAX_BINDING_ENTRIES=4” in f8wconfig.cfg
  • ohooo ! nice, can make it to maximum number, like 200 or more is it support flexible
  • I don’t think it can be set to that high. It will run out of memory.
  • Ok, thanks for your support at least can I make it 10,.
    See Chen, my requirement is to access the end devices without binding between them. So I am feeling complex to configure can you please have any suggestions.
  • It should be fine to make binding entry as 10. If you don’t use binding, you have to know the destination short address and endpoint in your application.
  • Hi Chen,
    I know the short address of my Dst End Device and the Application End Device but again it toggling the Coordinator LED.

    zclSampleSw_DstAddr.addr.shortAddr = 0x7ae0; // Dset Short Addr
    zclSampleSw_DstAddr.endPoint = SAMPLESW_ENDPOINT; // Application End Point
    zclGeneral_SendOnOff_CmdToggle( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, bdb_getZCLFrameCounter() );

    Thank you.
  • What is your zclSampleSw_DstAddr.addrMode? Do you set it to Addr16Bit?

  • No its default as it is.
  • Do it and test again.
  • yes its worked out now, I set both to Addr16Bit thank you.
    How can I bind 2 End Devices?
    When I bind 10 ZED's "ZED2, ZED3,...ZED11" to "ZED1" How to access one by one?
    Thank you.
  • Send ZDP_EndDeviceBindReq from both devices would do the trick.
  • Hi chen,

    I can't bind devices, I tried by calling as like below but getting confuse on params can you please describe params

     uint8 retValue = 0;
          uint8 epInt, numInClusters, numOutClusters;
          zAddrType_t destAddr;
          uint16 shortAddr;
          uint16 profileID, inClusters[MAX_ED_BIND_CLUSTERS], outClusters[MAX_ED_BIND_CLUSTERS];
          
          // Defining riquirements for the Binding //
          epInt = zclSampleLight_DstAddr.endPoint;
          numInClusters = 0;
          numOutClusters = 0;
          
          destAddr.addrMode = zclSampleLight_DstAddr.addrMode;
          destAddr.addr.shortAddr = zclSampleLight_DstAddr.addr.shortAddr; //Coordinator
          destAddr.addr.extAddr[0] = macaddr[0];
          destAddr.addr.extAddr[1] = macaddr[1];
          destAddr.addr.extAddr[2] = macaddr[2];
          destAddr.addr.extAddr[3] = macaddr[3];
          destAddr.addr.extAddr[4] = macaddr[4];
          destAddr.addr.extAddr[5] = macaddr[5];
          destAddr.addr.extAddr[6] = macaddr[6];
          destAddr.addr.extAddr[7] = macaddr[7];
          
          shortAddr = 0x0000;
          
          profileID = ZCL_HA_PROFILE_ID;
          
          retValue = (uint8)ZDP_EndDeviceBindReq( &destAddr, shortAddr, epInt, profileID,
                                                 numInClusters, inClusters, numOutClusters, outClusters, 0); 

  • You cannot use 0 in number of in/out clusters. There must be some value.
  • Can I use "1" in place of "0"
    Thank you
  • Other than number of in/out cluster, you also have to put cluster ID into in/out cluster array.
  • Hi Chen,

    I tried to bind ZED - ZED and ZED - ZC but no one worked, in both the case nothing is happening. I tried as like below code

    uint8 retValue = 0;
          uint8 epInt, numInClusters, numOutClusters;
          zAddrType_t destAddr;
          uint16 shortAddr;
          uint16 profileID, inClusters[MAX_ED_BIND_CLUSTERS], outClusters[MAX_ED_BIND_CLUSTERS];
          
          // Defining riquirements for the Binding //
          
          destAddr.addrMode = zclSampleLight_DstAddr.addrMode;
          destAddr.addr.shortAddr = zclSampleLight_DstAddr.addr.shortAddr; //Coordinator
          destAddr.addr.extAddr[0] = macaddr[0];
          destAddr.addr.extAddr[1] = macaddr[1];
          destAddr.addr.extAddr[2] = macaddr[2];
          destAddr.addr.extAddr[3] = macaddr[3];
          destAddr.addr.extAddr[4] = macaddr[4];
          destAddr.addr.extAddr[5] = macaddr[5];
          destAddr.addr.extAddr[6] = macaddr[6];
          destAddr.addr.extAddr[7] = macaddr[7];
          
          shortAddr = 0x0000;
          
          epInt = zclSampleLight_DstAddr.endPoint;
          
          profileID = ZCL_HA_PROFILE_ID;
          
          numInClusters = 1;
    
          numOutClusters = 1;
          
          retValue = (uint8)ZDP_EndDeviceBindReq( &destAddr, shortAddr, epInt, profileID,
                                                 numInClusters, inClusters, numOutClusters, outClusters, 0); 

    Thank you

  • And I got confused with what inClusters and outClusters defined to be.
  • You can refer to"if ( keys & HAL_KEY_SW_2 ){...}" in zclSampleSw_HandleKeys and zclSampleLight_HandleKeys.
  • Hi Chen,
    I referred if ( keys & HAL_KEY_SW_2 ){...}" in zclSampleSw_HandleKeys but no use, it has no info on finding and binding. Can you please describe why to refer this
  • Check how it fills bindingInClusters in SampleLight and fills bindingOutClusters in SampleSwitch.
  • Hi Chen,

    "zclSampleSw_HandleKeys and zclSampleLight_HandleKeys" no inClusters and outClusters were filling.

    it is as below,

     UI_MainStateMachine(keys);

    and then

    void UI_MainStateMachine( uint16 current_keys ) //argument is uint16 to allow 8 bits for the keys (for future use), and another unique value to mark a re-press of the previous keys.

    {

     static byte PrevKeys = 0; //holds the keys that were pressed during the previous time this function was called. (Does not hold the keys that were released.)

     uint8 SavedLcdCursorLine = uiLcdCursorLine;

     bool LcdUpdateIsRequired = FALSE;

     uint16 keys; //will hold the bitmask of the currently pressed keys at the lower 8 bits, and the keys that have just been released at the higher 8 bits.

     if (uiResetInitiated)

     {

       return;

     }

     if (current_keys == UI_KEY_AUTO_PRESSED)

     {

       keys = PrevKeys;

     }

     else

     {

       keys = (current_keys | (((PrevKeys ^ current_keys) & PrevKeys) << 8));

     }

     uiLcdCursorLine = 0xFF;

     if ((keys & UI_KEY_SW_2_PRESSED) && (uiStates[uiCurrentState].next_state != UI_STATE_UNCHANGED))

     {

       if (uiStates[uiCurrentState].next_state == UI_STATE_DEFAULT_MOVE)

       {

         uiCurrentState++;

       }

       else

       {

         uiCurrentState = uiStates[uiCurrentState].next_state;

       }

       LcdUpdateIsRequired = TRUE;

     }

     else if ((keys & UI_KEY_SW_4_PRESSED) && (uiStates[uiCurrentState].prev_state != UI_STATE_UNCHANGED))

     {

       if (uiStates[uiCurrentState].prev_state == UI_STATE_DEFAULT_MOVE)

       {

         uiCurrentState--;

       }

       else

       {

         uiCurrentState = uiStates[uiCurrentState].prev_state;

       }

       LcdUpdateIsRequired = TRUE;

     }

     else if ((keys & uiStates[uiCurrentState].keys_mask) && (uiStates[uiCurrentState].state_func != NULL))

     {

       uiStates[uiCurrentState].state_func(keys);

       LcdUpdateIsRequired = TRUE;

     }

     if (LcdUpdateIsRequired)

     {

       UI_UpdateLcd();

     }

     else

     {

       uiLcdCursorLine = SavedLcdCursorLine;

     }

     PrevKeys = keys & 0xFF; //only remember the keys that are currently pressed. Released keys are irrelevant. the 0xFF is not needed, since the target is uint8, but it is there just so it is clear that this assignment of uint16 into uint8 is intentional.

    }

    So no clusters filling here looks.

     

    and in MT_ZDO it was filling in a function as like,

    static void MT_ZdoEndDevBindRequest(uint8 *pBuf)

    {

     uint8 cmdId;

     uint8 retValue = 0;

     uint8 i, epInt, numInClusters, numOutClusters;

     zAddrType_t destAddr;

     uint16 shortAddr;

     uint16 profileID, inClusters[MTZDO_MAX_ED_BIND_CLUSTERS], outClusters[MTZDO_MAX_ED_BIND_CLUSTERS];

     /* parse header */

     cmdId = pBuf[MT_RPC_POS_CMD1];

     pBuf += MT_RPC_FRAME_HDR_SZ;

     /* Dev address */

     destAddr.addrMode = Addr16Bit;

     destAddr.addr.shortAddr = osal_build_uint16( pBuf );

     pBuf += 2;

     /* Local coordinator of the binding */

     shortAddr = osal_build_uint16( pBuf );

     pBuf += 2;

     /* For now, skip past the extended address */

     pBuf += Z_EXTADDR_LEN;

     /* Endpoint */

     epInt = *pBuf++;

     /* Profile ID */

     profileID = osal_build_uint16( pBuf );

     pBuf += 2;

     /* NumInClusters */

     numInClusters = *pBuf++;

     if ( numInClusters <= MTZDO_MAX_ED_BIND_CLUSTERS )

     {

       for ( i = 0; i < numInClusters; i++ )

       {

         inClusters[i] = osal_build_uint16( pBuf );

         pBuf += 2;

       }

     }

     else

     {

       retValue = ZDP_INVALID_REQTYPE;

     }

     /* NumOutClusters */

     numOutClusters = *pBuf++;

     if ( numOutClusters <= MTZDO_MAX_ED_BIND_CLUSTERS )

     {

       for ( i = 0; i < numOutClusters; i++ )

       {

         outClusters[i] = osal_build_uint16( pBuf );

         pBuf += 2;

       }

     }

     else

     {

       retValue = ZDP_INVALID_REQTYPE;

     }

     if ( retValue == 0 )

     {

       retValue = (uint8)ZDP_EndDeviceBindReq( &destAddr, shortAddr, epInt, profileID,

                                             numInClusters, inClusters, numOutClusters, outClusters, 0);

     }

     MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);

    }

    So I made like this and tried to finding and binding

    char* Buf;
    uint8 cmdId;
    uint8 retValue = 0;
    uint8 i, epInt, numInClusters, numOutClusters;
    zAddrType_t destAddr;
    uint16 shortAddr;
    uint16 profileID, inClusters[MAX_ED_BIND_CLUSTERS], outClusters[MAX_ED_BIND_CLUSTERS];

    /* parse header */
    cmdId = Buf[MT_RPC_POS_CMD1];
    Buf += MT_RPC_FRAME_HDR_SZ;

    /* Dev address */
    destAddr.addrMode = Addr16Bit;
    destAddr.addr.shortAddr = osal_build_uint16( Buf );
    Buf += 2;

    /* Local coordinator of the binding */
    shortAddr = osal_build_uint16( Buf );
    Buf += 2;

    /* For now, skip past the extended address */
    Buf += Z_EXTADDR_LEN;

    /* Endpoint */
    epInt = *Buf++;

    /* Profile ID */
    profileID = osal_build_uint16( Buf );
    Buf += 2;

    /* NumInClusters */
    numInClusters = *Buf++;
    if ( numInClusters <= MAX_ED_BIND_CLUSTERS )
    {
    for ( i = 0; i < numInClusters; i++ )
    {
    inClusters[i] = osal_build_uint16( Buf );
    Buf += 2;
    }
    }
    else
    {
    retValue = ZDP_INVALID_REQTYPE;
    }

    /* NumOutClusters */
    numOutClusters = *Buf++;
    if ( numOutClusters <= MAX_ED_BIND_CLUSTERS )
    {
    for ( int i = 0; i < numOutClusters; i++ )
    {
    outClusters[i] = osal_build_uint16( Buf );
    Buf += 2;
    }
    }
    else
    {
    retValue = ZDP_INVALID_REQTYPE;
    }

    if ( retValue == 0 )
    {
    retValue = (uint8)ZDP_EndDeviceBindReq( &destAddr, shortAddr, epInt, profileID,
    numInClusters, inClusters, numOutClusters, outClusters, 0);
    }

    Both devices are stopping by this cal.

     

  • The example code is in SampleLight and SampleSwitch in Z-Stack Home 1.2.2a.
  • Hi Chain,
    I am trying in Z-Stack3.0 you have to tell the stack version, where can I get Z-Stack Home 1.2.2a.
    Thank you
  • Hi Chen,

    I was getting result "afStatus_SUCCESS" but I was not getting any cal back to  "zclSampleLight_ProcessCommissioningStatus" registered by calling  "bdb_RegisterCommissioningStatusCB( zclSampleLight_ProcessCommissioningStatus );"

    Is there any other way to confirm the "Finding and Binding" and also please look at my code followed by "Z-Stack Home 1.2.2a"

      uint16 bindingInClusters[] =
    {
      ZCL_CLUSTER_ID_GEN_ON_OFF
    #ifdef ZCL_LEVEL_CTRL
      , ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
    #endif
    };
    #define ZCLSAMPLELIGHT_BINDINGLIST (sizeof(bindingInClusters) / sizeof(bindingInClusters[0]))
    
    static cId_t bindingOutClusters[] =
    {
      ZCL_CLUSTER_ID_GEN_ON_OFF
    };
    
    #define ZCLSAMPLESW_BINDINGLIST   (sizeof(bindingOutClusters)/sizeof(bindingOutClusters[0]));
    
    zAddrType_t dstAddr;
          dstAddr.addrMode = afAddr16Bit;
          dstAddr.addr.shortAddr = 0;   // Coordinator makes the match
          
        uint8 newres = ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                               8,
                               ZCL_HA_PROFILE_ID,
                               ZCLSAMPLELIGHT_BINDINGLIST, bindingInClusters,   
                               ZCLSAMPLELIGHT_BINDINGLIST, bindingOutClusters, /*Using ZCLSAMPLELIGHT_BINDINGLIST instead of ZCLSAMPLESW_BINDINGLIST, because getting error and both looks one and same*/
                               TRUE );

    Thank you

  • ZDP_EndDeviceBindReq is nothing to do with BDB commissioning. If it returns success, you can use AddrNotPresent mode to send command.
  • How can I confirm that Binding was success between devices ?
    Thank you
  • You can check it in ZDO_SendEDBindRsp or use sniffer to verify it.
  • Hi Chen,

    AddrNotPresent mode is not working for me tried as below,

     afAddrType_t zclSampleSw_DstAddr;

     zclSampleSw_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;

     zclSampleSw_DstAddr.addr.shortAddr = 0X0000;

     zclSampleSw_DstAddr.endPoint = SAMPLELIGHT_ENDPOINT;

       zclSampleSw_DstAddr.panId = _NIB.nwkPanId;

     zclGeneral_SendOnOff_CmdToggle( SAMPLELIGHT_ENDPOINT, &zclSampleSw_DstAddr, FALSE, bdb_getZCLFrameCounter() );

    I made the  zclSampleSw_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent; during init of app also in both the application  ZC and ZED

    The same is working with Addr16Bit,  made the  zclSampleSw_DstAddr.addrMode = Addr16Bit; during init of app also in both the application  ZC and ZED

    tried as below,

     afAddrType_t zclSampleSw_DstAddr;

     zclSampleSw_DstAddr.addrMode = Addr16Bit;

     zclSampleSw_DstAddr.addr.shortAddr = 0X0000;

     zclSampleSw_DstAddr.endPoint = SAMPLELIGHT_ENDPOINT;

       zclSampleSw_DstAddr.panId = _NIB.nwkPanId;

     zclGeneral_SendOnOff_CmdToggle( SAMPLELIGHT_ENDPOINT, &zclSampleSw_DstAddr, FALSE, bdb_getZCLFrameCounter() );

    So, I feel binding is not done, can I check the binding list of device, I mean a particular devices as connected  to how many devices.

    Thank you

  • I suggest you to use Ubiqua Protocol Analyzer to check what happens over the air.
  • Hi Chen,

    I captured during finding and Binding using Ubiqua, It seems its not happening. Can you please look the attached capture.

    Thank you01.rar

  • I see there are binding requests and reponse are success.
  • Can I know what line of capture is doing this.

    Thank you
  • Line 110 is bind request and 114 is response.
  • Hi Chen,
    In Ubiqua I don't want to see the MAC Layer capture, I want to capture only ZCL and ZDP layer capture. How can I filter this, I am failing to set the filter to my need.
    Thank you
  • 02.rarHi Chen,

    I want bind the 2 end devices, but when I was requesting  finding and binding from ZED its getting binding response from ZC. I tried by requesting binding from 2 ZED both are getting response from ZC. you can look at captured attached.

    Thank you.

  • Can you specify which binding you want to use? ZDP_BindReq or ZDP_EndDeviceBindReq?
  • ZDP_EndDeviceBindReq
  • If you use ZDP_EndDeviceBindReq, both of two binding device should send ZDP_EndDeviceBindReq to coordinator in 15 seconds window. Otherwise, you will get end device binding time out like you see in packet number 291 of your sniffer log.
  • So the devices are not binded because of time out,
    I called binding only from ZED, not touched the ZC its is keep steering at the time as per last capture 02 you have.
    What is write way of calling Binding
    Thank you
  • Yes, the devices are not binding because of time out. Can you specify what devices (short address) you want to bind together?