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.

issue with AFData_request

Other Parts Discussed in Thread: CC2538

Hello all,

i am using cc2538 and zstack HA 1.20 and i am using sample Temp sensor and sample Thermostat projects for testing...... i want to send data by AF_DataRequest API in my project but i am getting few problems. ->

1) in my temp sensor side i am sending msg continuously after every 5sec but i am not able to recive that msg at thermostat side.

2)i am able to see my msg on temp sensor side lcd screen but not able to see any msg on thermostat side..

below is my code which i wrote ->

Temp sensor :=>

#define SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT              0x0020

// Send Message Timeout
#define SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT            5000

Under <>_event_loop () :=>

case ZDO_STATE_CHANGE:

..............

..............

// Start sending "the" message in a regular interval.
osal_start_timerEx ( zclSampleTemperatureSensor_TaskID,                              SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT,
SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT );

if ( events & SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT )
{
// Send "the" message
zclSampleTemperatureSensor_SendTheAFMessage();

// Setup to send message again
osal_start_timerEx( zclSampleTemperatureSensor_TaskID,
SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT,
SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT );

// return unprocessed events
return (events ^ SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT);
}

 

and =>

static void zclSampleTemperatureSensor_SendTheAFMessage( void )
{

char theMessageData[] = "Maneesh singh";

if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
(byte)osal_strlen( theMessageData ) + 1,
(byte *)&theMessageData,
&zclSampleTemperatureSensor_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
HalLcdWriteString ( theMessageData, HAL_LCD_LINE_2 );
// Successfully requested to be sent.
}
else
{
// Error occurred in request to send.
}


}

Thermostat side :=>

under <>_event_loop()

case AF_INCOMING_MSG_CMD:
zclSampleThermostat_MessageMSGCB( MSGpkt );
break;

static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
switch ( pkt->clusterId )
{
case ZCL_CLUSTER_ID_HVAC_THERMOSTAT:

UARTprintf("AF_msg_received_is => %s\n",(pkt->cmd.Data) );

break;
}
}

is there anyone who can help me to solve this problem..

any idea what i am doing wrong ?

plz tell me how can send and receive data with AF_dataRequest API..

Anyone plz reply...

Thanks & Regards,

Maneesh singh

 

  • Hello,

    is there anyone in this group who can suggest me what i am doing wrong ?

    how can i use AF_Datareguest() API...

    i already take reference from GenericApp project and did the same thing as suggested but its not working...

    anyone on this forum plz help me...

    any TI employee plz reply to my post....

    Thanks & Regards,

    Maneesh singh 

  • Hello,

    how AF_datarequest msg is working ?

    1) i mean to say if i want to send data from sample temp sensor to sample thermostat then what are the data i need to fill in the AF_datarequest fn() ? 

    2) i am filling following details ->

    AF_DataRequest ( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
    ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
    (byte)osal_strlen( theMessageData ) + 1,
    (byte *)&theMessageData,
    &zclSampleTemperatureSensor_TransID,
    AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

    is this correct ? or i am doing anything wrong...

    anyone plz help me to solve this.....plz reply..

  • Hello,

    is there anyone in this forum group who can reply to my previous post....

    i am totally stuck with this API and frustrated....

    since long time i am waiting but i am not getting  any reply for any of my post from this forum i dont know whats the reason but no zigbee expert or TI employee is helping me to solve this issue....

    at least any TI plz reply and tell me how can i solve this issue....

  • Do you use Ubiqua Oacket analyzer to check if the message is sent out from Sensor Temperature?

  • hello YiKai Chen sir,

    thanks for your reply...

    No i didnt check with ubique packet analyzer......

    i hav two events in my temp sensor code ->

    //sending current temp using  zcl_SendReportCmd() API

    #define SAMPLETEMPERATURESENSOR_REPORT_INTERVAL 25000 

    // Send Message using AF_DataRequest() API

    #define SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT 10000

    so after every 25 i am sending current temp which i am able to receive at thermostat side but msg which i am sending from temp side through AF_DataRequest is not getting transmitted and i am not able to receive at thermostat side....

    in temp side i did like this ->

    <> event_loop()

    char pstr[] = "sending fail" ;

    case AF_DATA_CONFIRM_CMD:
    // This message is received as a confirmation of a data packet sent.
    // The status is of ZStatus_t type [defined in ZComDef.h]
    // The message fields are defined in AF.h
    afDataConfirm = (afDataConfirm_t *)MSGpkt;

    sentEP = afDataConfirm->endpoint;
    (void)sentEP; // This info not used now
    sentTransID = afDataConfirm->transID;
    (void)sentTransID; // This info not used now

    sentStatus = afDataConfirm->hdr.status;
    // Action taken when confirmation is received.
    if ( sentStatus != ZSuccess )
    {
    HalLcdWriteString ( pstr, HAL_LCD_LINE_2 );
    // The data wasn't delivered -- Do something
    }
    break;

    and i am getting sending fail msg on screen......

     

    Thanks & Regards,

    maneesh

  • hello YiKai Chen sir will you plz verify my code which i wrote for AF_DataRequest...

    i am sending data from temp sensor to thermostat side.....so is my AF_datarequest() API field is correct or not ?

    temp side=>

    #define SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT              0x0020

    #define SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT          10000

    if ( events & SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT )
    {
    // Send "the" message
    zclSampleTemperatureSensor_SendTheAFMessage();

    // Setup to send message again
    osal_start_timerEx( zclSampleTemperatureSensor_TaskID,
    SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT,
    SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT );

    // return unprocessed events
    return (events ^ SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT);
    }

    static void zclSampleTemperatureSensor_SendTheAFMessage( void )
    {

    char theMessageData[] = "Maneesh Unizen ";

    if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
                                          ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                                          (byte)osal_strlen( theMessageData ) + 1,
                                          (byte *)&theMessageData,
                                          &zclSampleTemperatureSensor_TransID,
                                          AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    {
    HalLcdWriteString ( theMessageData, HAL_LCD_LINE_2 );
    // Successfully requested to be sent.
    }
    else
    {
    // Error occurred in request to send.
    }

  • I see no problem you use AF_datarequest so I suggest you to use Ubiqua Packet Analyzer to have a look.

  • Hello sir,

    i checked in data packet AF_dataRequest is not sending data packet... i detected following problems ->

    1) event for Af_DataRequest is not getting triggered. i defined the event like this ->

    #define SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT              0x0020

    #define SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT           10000

    if ( events & SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT )  ///// i set one breakpoint here but it never                                                                                                                                             hit here.. not triggering this event.

    {
    // Send "the" message
    zclSampleTemperatureSensor_SendTheAFMessage();

    // Setup to send message again
    osal_start_timerEx( zclSampleTemperatureSensor_TaskID,
    SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT,
    SAMPLETEMPERATURESENSOR_SEND_MSG_TIMEOUT );

    // return unprocessed events
    return (events ^ SAMPLETEMPERATURESENSOR_AF_MSG_SEND_EVT);
    }

    2) hence i used AF_DataRequest () API in send temp fn itself and put a breakpoint over there....... i noticed that it is hitting the breakpoints of AF_DataRequest but i think it is not sending the msg ....plz check the screen shot of Breakpoints.... here u can see instead of highligting whole AF fn only osal_strlen is highlighted in green color where as in case of zcl_sendreportcmd() whole fn was highlighted in green color... so i think problem is somewhere inside the AF_datarequest fn only...plz cheack my fn once again carefully.......... 

    3) in Temp sensor  under eventloop i kept like this -

    case AF_DATA_CONFIRM_CMD:
    // This message is received as a confirmation of a data packet sent.

    afDataConfirm = (afDataConfirm_t *)MSGpkt;

    sentEP = afDataConfirm->endpoint;
    (void)sentEP; // This info not used now
    sentTransID = afDataConfirm->transID;
    (void)sentTransID; // This info not used now

    sentStatus = afDataConfirm->hdr.status;
    // Action taken when confirmation is received.
    if ( sentStatus != ZSuccess )
    {
    HalLcdWriteString ( pstr, HAL_LCD_LINE_2 );   /////pstr => sending fails
    // The data wasn't delivered -- Do something
    }
    break;

    Now i am getting msg saying sending fails....

    4) so from all these points i am sure that AF_DataRequest is not sending the data but  dont understand why ? 

    Here is the code for sending Data from AF_DataRequest () API.

    if ( AF_DataRequest ( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
                                          ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                                          (byte)osal_strlen( theMessageData ) + 1,
                                          (byte *)&theMessageData,
                                          &zclSampleTemperatureSensor_TransID,
                                          AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

     

    plz tell me sir what i need to do to solve this problem....

    plz reply sir....

    Thanks & Regards,

    Maneesh singh

  • here is screenshot for zcl_SendReportcmd() API..... here you can see that whole API is marked in Green color but in case of AF_DataRequest only osal_strlen was marked in green.... is there any specific reason for it ?

  • 1. Check return value of AF_DataRequest and see if it is afStatus_SUCCESS.

    2. Check what are in your zclSampleTemperatureSensor_DstAddr and sampleTemperatureSensor_TestEp.

  • hello sir,

    as u suggested i did like this ->

    1) if ( AF_DataRequest() == afStatus_SUCCESS)

    {  print => success

    }

    else

    {  print => not success

    and it is printing success on LCD it means return value of AF_DataRequest is afStatus_SUCCESS .

    but in case AF_DATA_CONFIRM_CMD      i am getting sending fail....

    2)  zclSampleTemperatureSensor_DstAddr is afAddrType_t which is defined in AF.h file

    typedef struct
    {
    union
    {
    uint16 shortAddr;
    ZLongAddr_t extAddr;
    } addr;
    afAddrMode_t addrMode;
    uint8 endPoint;
    uint16 panId; // used for the INTER_PAN feature
    } afAddrType_t;

    and sampleTemperatureSensor_TestEp is 

    static endPointDesc_t sampleTemperatureSensor_TestEp =
    {
    20, // Test endpoint
    &zclSampleTemperatureSensor_TaskID,
    (SimpleDescriptionFormat_t *)NULL, // No Simple description for this test endpoint
    (afNetworkLatencyReq_t)0 // No Network Latency req
    };

    i checked in Generic APP also zclSampleTemperatureSensor_DstAddr is same but in  sampleTemperatureSensor_TestEp. i am defing my own as written above and in generic app they are definig it in <>init() fn.....

    / Fill out the endpoint description.
    GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
    GenericApp_epDesc.task_id = &GenericApp_TaskID;
    GenericApp_epDesc.simpleDesc
    = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
    GenericApp_epDesc.latencyReq = noLatencyReqs;

     

  • I guess the problem is in zclSampleTemperatureSensor_DstAddr and sampleTemperatureSensor_TestEp. When you set the breakpoint, I suggest you to check values in clSampleTemperatureSensor_DstAddr and sampleTemperatureSensor_TestEp.

  • Hello YiKai Chen sir as u suggested i checked the values of zclSampleTemperatureSensor_DstAddr and sampleTemperatureSensor_TestEp.....

    here is the screen shot which i captured and in quick watch windows u can see the values of both--->

    plz check the above detail and tell me what is going wrong ?

    and i notice that callback fn for AF_incoming data is also not getting called at thermostat side.... may be it is becoz temp sensor is not sending data.....

    i am sending you my source file plz check it if i am doing anything wrong ? 

    TempSensor Source file :-

    /**************************************************************************************************
      Filename:       zcl_sampletemperaturesensor.c
      Revised:        $Date: 2013-10-18 11:49:27 -0700 (Fri, 18 Oct 2013) $
      Revision:       $Revision: 35718 $
    
      Description:    Zigbee Cluster Library - sample device application.
    
    
      Copyright 2013 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
      This device will act as a temperature sensor. It updates the current
      temperature on the thermostat when the user sends the desired
      temperature using SW1.
    
      SCREEN MODES
      ----------------------------------------
      Main:
        - SW1: Send current temperature
        - SW2: Invoke EZMode
        - SW3: Adjust temperature
        - SW5: Go to Help screen
    
      Temperature:
        - SW1: Increase temperature
        - SW3: Decrease temperature
        - SW5: Enter temperature
      ----------------------------------------
    *********************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include "ZComDef.h"
    #include "OSAL.h"
    #include "AF.h"
    #include "ZDApp.h"
    #include "ZDObject.h"
    #include "ZDProfile.h"
    #include "MT_SYS.h"
    
    #include "zcl.h"
    #include "zcl_general.h"
    #include "zcl_ha.h"
    #include "zcl_ezmode.h"
    #include "zcl_ms.h"
    
    #include "zcl_sampletemperaturesensor.h"
    
    #include "onboard.h"
    
    /* HAL */
    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    
    /*********************************************************************
     * MACROS
     */
    
    // how often to report temperature
    #define SAMPLETEMPERATURESENSOR_REPORT_INTERVAL   10000
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    byte zclSampleTemperatureSensor_TaskID;
    
    uint8 zclSampleTemperatureSensorSeqNum;
    
    static byte gPermitDuration = 0x00;
    
    byte zclSampleTemperatureSensor_TransID;  // This is the unique message ID (counter)
    
    /*********************************************************************
     * GLOBAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    afAddrType_t zclSampleTemperatureSensor_DstAddr;
    
    #ifdef ZCL_EZMODE
    static void zclSampleTemperatureSensor_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
    static void zclSampleTemperatureSensor_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
    
    static const zclEZMode_RegisterData_t zclSampleTemperatureSensor_RegisterEZModeData =
    {
      &zclSampleTemperatureSensor_TaskID,
      SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT,
      SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT,
      &zclSampleTemperatureSensorSeqNum,
      zclSampleTemperatureSensor_EZModeCB
    };
    
    // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
    
    static cId_t bindingOutClusters[] =
    {
      ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT
    };
    #define ZCLSAMPLETEMPERATURESENSOR_BINDINGLIST        1
    #endif
    
    devStates_t zclSampleTemperatureSensor_NwkState = DEV_INIT;
    
    uint8 giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;   // display main screen mode first
    
    static uint8 aProcessCmd[] = { 1, 0, 0, 0 }; // used for reset command, { length + cmd0 + cmd1 + data }
    
    // Test Endpoint to allow SYS_APP_MSGs
    static endPointDesc_t sampleTemperatureSensor_TestEp =
    {
      20,                                 // Test endpoint
      &zclSampleTemperatureSensor_TaskID,
      (SimpleDescriptionFormat_t *)NULL,  // No Simple description for this test endpoint
      (afNetworkLatencyReq_t)0            // No Network Latency req
    };
    
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void zclSampleTemperatureSensor_HandleKeys( byte shift, byte keys );
    static void zclSampleTemperatureSensor_BasicResetCB( void );
    static void zclSampleTemperatureSensor_IdentifyCB( zclIdentify_t *pCmd );
    static void zclSampleTemperatureSensor_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
    static void zclSampleTemperatureSensor_ProcessIdentifyTimeChange( void );
    
    // app display functions
    void zclSampleTemperatureSensor_LcdDisplayUpdate(void);
    void zclSampleTemperatureSensor_LcdDisplayMainMode(void);
    void zclSampleTemperatureSensor_LcdDisplayTempMode(void);
    void zclSampleTemperatureSensor_LcdDisplayHelpMode(void);
    
    static void zclSampleTemperatureSensor_SendTemp(void);
    
    // Functions to process ZCL Foundation incoming Command/Response messages
    static void zclSampleTemperatureSensor_ProcessIncomingMsg( zclIncomingMsg_t *msg );
    #ifdef ZCL_READ
    static uint8 zclSampleTemperatureSensor_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_WRITE
    static uint8 zclSampleTemperatureSensor_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    static uint8 zclSampleTemperatureSensor_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
    #ifdef ZCL_DISCOVER
    static uint8 zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg );
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg );
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg );
    #endif // ZCL_DISCOVER
    
    /*********************************************************************
     * STATUS STRINGS
     */
    #ifdef LCD_SUPPORTED
    const char sClearLine[]    = " ";
    const char sDeviceName[]   = "  Temp Sensor";
    const char sSwTempUp[]     = "SW1: Raise Temp";
    const char sSwEZMode[]     = "SW2: EZ-Mode";
    const char sSwTempDown[]   = "SW3: Lower Temp";
    const char sSwHelp[]       = "SW5: Help";
    #endif
    
    /*********************************************************************
     * ZCL General Profile Callback table
     */
    static zclGeneral_AppCallbacks_t zclSampleTemperatureSensor_CmdCallbacks =
    {
      zclSampleTemperatureSensor_BasicResetCB,        // Basic Cluster Reset command
      zclSampleTemperatureSensor_IdentifyCB,          // Identify command
    #ifdef ZCL_EZMODE
      NULL,                                           // Identify EZ-Mode Invoke command
      NULL,                                           // Identify Update Commission State command
    #endif
      NULL,                                           // Identify Trigger Effect command
      zclSampleTemperatureSensor_IdentifyQueryRspCB,  // Identify Query Response command
      NULL,             				                      // On/Off cluster command
      NULL,                                           // On/Off cluster enhanced command Off with Effect
      NULL,                                           // On/Off cluster enhanced command On with Recall Global Scene
      NULL,                                           // On/Off cluster enhanced command On with Timed Off
    #ifdef ZCL_LEVEL_CTRL
      NULL,                                           // Level Control Move to Level command
      NULL,                                           // Level Control Move command
      NULL,                                           // Level Control Step command
      NULL,                                           // Level Control Stop command
    #endif
    #ifdef ZCL_GROUPS
      NULL,                                           // Group Response commands
    #endif
    #ifdef ZCL_SCENES
      NULL,                                           // Scene Store Request command
      NULL,                                           // Scene Recall Request command
      NULL,                                           // Scene Response command
    #endif
    #ifdef ZCL_ALARMS
      NULL,                                           // Alarm (Response) commands
    #endif
    #ifdef SE_UK_EXT
      NULL,                                           // Get Event Log command
      NULL,                                           // Publish Event Log command
    #endif
      NULL,                                           // RSSI Location command
      NULL                                            // RSSI Location Response command
    };
    
    /*********************************************************************
     * @fn          zclSampleTemperatureSensor_Init
     *
     * @brief       Initialization function for the zclGeneral layer.
     *
     * @param       none
     *
     * @return      none
     */
    void zclSampleTemperatureSensor_Init( byte task_id )
    {
      zclSampleTemperatureSensor_TaskID = task_id;
      zclSampleTemperatureSensor_TransID = 0;
    
      // Set destination address to indirect
      zclSampleTemperatureSensor_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
      zclSampleTemperatureSensor_DstAddr.endPoint = 0;
      zclSampleTemperatureSensor_DstAddr.addr.shortAddr = 0;
    
      // This app is part of the Home Automation Profile
      zclHA_Init( &zclSampleTemperatureSensor_SimpleDesc );
    
      // Register the ZCL General Cluster Library callback functions
      zclGeneral_RegisterCmdCallbacks( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_CmdCallbacks );
    
      // Register the application's attribute list
      zcl_registerAttrList( SAMPLETEMPERATURESENSOR_ENDPOINT, SAMPLETEMPERATURESENSOR_MAX_ATTRIBUTES, zclSampleTemperatureSensor_Attrs );
    
      // Register the Application to receive the unprocessed Foundation command/response messages
      zcl_registerForMsg( zclSampleTemperatureSensor_TaskID );
    
    #ifdef ZCL_EZMODE
      // Register EZ-Mode
      zcl_RegisterEZMode( &zclSampleTemperatureSensor_RegisterEZModeData );
    
      // Register with the ZDO to receive Match Descriptor Responses
      ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
    #endif
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( zclSampleTemperatureSensor_TaskID );
    
      // Register for a test endpoint
      afRegister( &sampleTemperatureSensor_TestEp );
    
    #ifdef LCD_SUPPORTED
      // display the device name
      HalLcdWriteString( (char *)sDeviceName, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn          zclSample_event_loop
     *
     * @brief       Event Loop Processor for zclGeneral.
     *
     * @param       none
     *
     * @return      none
     */
    uint16 zclSampleTemperatureSensor_event_loop( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
      afDataConfirm_t *afDataConfirm;
      char pstr[] = "sending fail" ;
      
      // Data Confirmation message fields
      byte sentEP;
      ZStatus_t sentStatus;
      byte sentTransID;       // This should match the value sent
    
      (void)task_id;  // Intentionally unreferenced parameter
    
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleTemperatureSensor_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
    #ifdef ZCL_EZMODE
            case ZDO_CB_MSG:
              zclSampleTemperatureSensor_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
              break;
    #endif
    
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclSampleTemperatureSensor_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
    
            case KEY_CHANGE:
              zclSampleTemperatureSensor_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
              case AF_DATA_CONFIRM_CMD:
              // This message is received as a confirmation of a data packet sent.
              // The status is of ZStatus_t type [defined in ZComDef.h]
              // The message fields are defined in AF.h
              afDataConfirm = (afDataConfirm_t *)MSGpkt;
    
              sentEP = afDataConfirm->endpoint;
              (void)sentEP;  // This info not used now
              sentTransID = afDataConfirm->transID;
              (void)sentTransID;  // This info not used now
    
              sentStatus = afDataConfirm->hdr.status;
              // Action taken when confirmation is received.
              if ( sentStatus != ZSuccess )
              {
                 HalLcdWriteString ( pstr, HAL_LCD_LINE_2 );
                // The data wasn't delivered -- Do something
              }
              break;
              
              
            case ZDO_STATE_CHANGE:
              zclSampleTemperatureSensor_NwkState = (devStates_t)(MSGpkt->hdr.status);
    
    
              // now on the network
              if ( (zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD) ||
                   (zclSampleTemperatureSensor_NwkState == DEV_ROUTER)   ||
                   (zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE) )
              {
    #ifndef HOLD_AUTO_START
                giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
                zclSampleTemperatureSensor_LcdDisplayUpdate();
    #endif
    #ifdef ZCL_EZMODE
                zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
    #endif // ZCL_EZMODE
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT )
      {
        if ( zclSampleTemperatureSensor_IdentifyTime > 0 )
          zclSampleTemperatureSensor_IdentifyTime--;
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    
        return ( events ^ SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT );
      }
    
    #ifdef ZCL_EZMODE
      // going on to next state
      if ( events & SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL );   // going on to next state
        return ( events ^ SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT );
      }
    
      // the overall EZMode timer expired, so we timed out
      if ( events & SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
        return ( events ^ SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT );
      }
    #endif // ZLC_EZMODE
    
      if ( events & SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
        zclSampleTemperatureSensor_LcdDisplayUpdate();
    
        return ( events ^ SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT );
      }
    
      if ( events & SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT )
      {
        zclSampleTemperatureSensor_SendTemp();
    
        // report current temperature reading every 10 seconds
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT, SAMPLETEMPERATURESENSOR_REPORT_INTERVAL );
    
        return ( events ^ SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT );
      }
    
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_5
     *                 HAL_KEY_SW_4
     *                 HAL_KEY_SW_3
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_HandleKeys( byte shift, byte keys )
    {
      if ( keys & HAL_KEY_SW_1 )
      {
        // increase temperature
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        if ( zclSampleTemperatureSensor_MeasuredValue < zclSampleTemperatureSensor_MaxMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MeasuredValue + 100;  // considering using whole number value
        }
        else if ( zclSampleTemperatureSensor_MeasuredValue >= zclSampleTemperatureSensor_MaxMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MaxMeasuredValue;
        }
    
        // Send temperature information
        zclSampleTemperatureSensor_SendTemp();
      }
    
      if ( keys & HAL_KEY_SW_2 )
      {
        if ( ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE ) ||
            ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE ) )
        {
          giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
    #ifdef ZCL_EZMODE
          zclEZMode_InvokeData_t ezModeData;
          static uint16 clusterIDs[] = { ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT };   // only bind on the Temperature Measurement cluster
    
          // Invoke EZ-Mode
          ezModeData.endpoint = SAMPLETEMPERATURESENSOR_ENDPOINT; // endpoint on which to invoke EZ-Mode
          if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
               ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER )   ||
               ( zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE ) )
          {
            ezModeData.onNetwork = TRUE;      // node is already on the network
          }
          else
          {
            ezModeData.onNetwork = FALSE;     // node is not yet on the network
          }
          ezModeData.initiator = TRUE;        // Temperature Sensor is an initiator
          ezModeData.numActiveInClusters = 1;
          ezModeData.pActiveInClusterIDs = clusterIDs;
          ezModeData.numActiveOutClusters = 0;   // active output cluster
          ezModeData.pActiveOutClusterIDs = NULL;
          zcl_InvokeEZMode( &ezModeData );
    
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
    #endif
    
          // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
          {
            zAddrType_t dstAddr;
            dstAddr.addrMode = Addr16Bit;
            dstAddr.addr.shortAddr = 0;   // Coordinator makes the EDB match
    
            // Initiate an End Device Bind Request, this bind request will
            // only use a cluster list that is important to binding.
            HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
            ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                                  SAMPLETEMPERATURESENSOR_ENDPOINT,
                                  ZCL_HA_PROFILE_ID,
                                  0, NULL,
                                  ZCLSAMPLETEMPERATURESENSOR_BINDINGLIST, bindingOutClusters,
                                  FALSE );
          }
    #endif // ZCL_EZMODE
        }
      }
    
      if ( keys & HAL_KEY_SW_3 )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        // decrease the temperature
        if ( zclSampleTemperatureSensor_MeasuredValue > zclSampleTemperatureSensor_MinMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MeasuredValue - 100;  // considering using whole number value
        }
        else if ( zclSampleTemperatureSensor_MeasuredValue >= zclSampleTemperatureSensor_MinMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MinMeasuredValue;
        }
    
        // Send temperature information
        zclSampleTemperatureSensor_SendTemp();
      }
    
      if ( keys & HAL_KEY_SW_4 )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
             ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER ) )
        {
          // toggle permit join
          gPermitDuration = gPermitDuration ? 0 : 0xff;
          NLME_PermitJoiningRequest( gPermitDuration );
        }
      }
    
      if ( shift && ( keys & HAL_KEY_SW_5 ) )
      {
        zclSampleTemperatureSensor_BasicResetCB();
      }
      else if ( keys & HAL_KEY_SW_5 )
      {
        if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
        {
          giTemperatureSensorScreenMode = TEMPSENSE_HELPMODE;
        }
        else if ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE )
        {
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( (char *)sClearLine, HAL_LCD_LINE_2 );
    #endif
          giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
        }
      }
    
      // update display
      zclSampleTemperatureSensor_LcdDisplayUpdate();
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayUpdate
     *
     * @brief   Called to update the LCD display.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayUpdate( void )
    {
      // turn on red LED for temperatures >= 24.00C
      if ( zclSampleTemperatureSensor_MeasuredValue >= 2400 )
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
      }
      // turn on green LED for temperatures <= 20.00C
      else if ( zclSampleTemperatureSensor_MeasuredValue <= 2000 )
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
      }
      // turn on both red and green LEDs for temperatures between 20.00C and 24.00C
      else
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
      }
    
      if ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE )
      {
        zclSampleTemperatureSensor_LcdDisplayHelpMode();
      }
      else
      {
        zclSampleTemperatureSensor_LcdDisplayMainMode();
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayMainMode
     *
     * @brief   Called to display the main screen on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayMainMode( void )
    {
      char sDisplayTemp[16];
    
      if ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD )
      {
        zclHA_LcdStatusLine1( 0 );
      }
      else if ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER )
      {
        zclHA_LcdStatusLine1( 1 );
      }
      else if ( zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE )
      {
        zclHA_LcdStatusLine1( 2 );
      }
    
      // display current temperature
      osal_memcpy(sDisplayTemp, "TEMP: ", 6);
      _ltoa( ( zclSampleTemperatureSensor_MeasuredValue / 100 ), (void *)(&sDisplayTemp[6]), 10 );   // convert temperature to whole number
      osal_memcpy( &sDisplayTemp[8], "C", 2 );
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_2 );
    #endif
    
    #ifdef LCD_SUPPORTED
      if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
           ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER ) )
      {
        // display help key with permit join status
        if ( gPermitDuration )
        {
          HalLcdWriteString( "SW5: Help      *", HAL_LCD_LINE_3 );
        }
        else
        {
          HalLcdWriteString( "SW5: Help       ", HAL_LCD_LINE_3 );
        }
      }
      else
      {
        // display help key
        HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
      }
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayHelpMode
     *
     * @brief   Called to display the SW options on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayHelpMode( void )
    {
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sSwTempUp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sSwTempDown, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_SendTemp
     *
     * @brief   Called to send current temperature information to the thermostat
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_SendTemp( void )
    {
    #ifdef ZCL_REPORT
      zclReportCmd_t *pReportCmd;
      char *theMessageData = "Hello i am temp Sensor";
    
      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = ATTRID_MS_TEMPERATURE_MEASURED_VALUE;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_INT16;
        pReportCmd->attrList[0].attrData = (void *)(&zclSampleTemperatureSensor_MeasuredValue);
    
        zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
                           ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                           pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );
      }
      
      if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
                        ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                        (byte)osal_strlen( theMessageData ) + 1,
                        (byte *)&theMessageData,
                        &zclSampleTemperatureSensor_TransID,
                        AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
        theMessageData = "success" ;
        HalLcdWriteString ( theMessageData, HAL_LCD_LINE_2 );
      // Successfully requested to be sent.
      }
      else
      {
         theMessageData = "not success" ; 
          HalLcdWriteString ( theMessageData, HAL_LCD_LINE_2 );
      // Error occurred in request to send.
      }
    
      osal_mem_free( pReportCmd );
    #endif  // ZCL_REPORT
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessIdentifyTimeChange
     *
     * @brief   Called to process any change to the IdentifyTime attribute.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_ProcessIdentifyTimeChange( void )
    {
      if ( zclSampleTemperatureSensor_IdentifyTime > 0 )
      {
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT, 1000 );
        HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
      }
      else
      {
        if ( zclSampleTemperatureSensor_OnOff )
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
        }
        else
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
        }
    
        osal_stop_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_BasicResetCB
     *
     * @brief   Callback from the ZCL General Cluster Library
     *          to set all the Basic Cluster attributes to default values.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_BasicResetCB( void )
    {
      // Put device back to factory default settings
      zgWriteStartupOptions( ZG_STARTUP_SET, 3 );   // bit set both default configuration and default network
    
      // restart device
      MT_SysCommandProcessing( aProcessCmd );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_IdentifyCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Command for this application.
     *
     * @param   srcAddr - source address and endpoint of the response message
     * @param   identifyTime - the number of seconds to identify yourself
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_IdentifyCB( zclIdentify_t *pCmd )
    {
      zclSampleTemperatureSensor_IdentifyTime = pCmd->identifyTime;
      zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_IdentifyQueryRspCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Query Response Command for this application.
     *
     * @param   srcAddr - requestor's address
     * @param   timeout - number of seconds to identify yourself (valid for query response)
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
    {
      (void)pRsp;
    #ifdef ZCL_EZMODE
      {
        zclEZMode_ActionData_t data;
        data.pIdentifyQueryRsp = pRsp;
        zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
      }
    #endif
    }
    
    /******************************************************************************
     *
     *  Functions for processing ZCL Foundation incoming Command/Response messages
     *
     *****************************************************************************/
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessIncomingMsg
     *
     * @brief   Process ZCL Foundation incoming message
     *
     * @param   pInMsg - pointer to the received message
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg)
    {
      switch ( pInMsg->zclHdr.commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ_RSP:
          zclSampleTemperatureSensor_ProcessInReadRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE_RSP:
          zclSampleTemperatureSensor_ProcessInWriteRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_REPORT
        // See ZCL Test Applicaiton (zcl_testapp.c) for sample code on Attribute Reporting
        case ZCL_CMD_CONFIG_REPORT:
          //zclSampleTemperatureSensor_ProcessInConfigReportCmd( pInMsg );
          break;
    
        case ZCL_CMD_CONFIG_REPORT_RSP:
          //zclSampleTemperatureSensor_ProcessInConfigReportRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          //zclSampleTemperatureSensor_ProcessInReadReportCfgCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG_RSP:
          //zclSampleTemperatureSensor_ProcessInReadReportCfgRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_REPORT:
          //zclSampleTemperatureSensor_ProcessInReportCmd( pInMsg );
          break;
    #endif
        case ZCL_CMD_DEFAULT_RSP:
          zclSampleTemperatureSensor_ProcessInDefaultRspCmd( pInMsg );
          break;
    #ifdef ZCL_DISCOVER
        case ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP:
          zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_CMDS_GEN_RSP:
          zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_ATTRS_RSP:
          zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_ATTRS_EXT_RSP:
          zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( pInMsg );
          break;
    #endif
        default:
          break;
      }
    
      if ( pInMsg->attrCmd )
      {
        osal_mem_free( pInMsg->attrCmd );
      }
    }
    
    #ifdef ZCL_READ
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInReadRspCmd
     *
     * @brief   Process the "Profile" Read Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReadRspCmd_t *readRspCmd;
      uint8 i;
    
      readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < readRspCmd->numAttr; i++ )
      {
        // Notify the originator of the results of the original read attributes
        // attempt and, for each successfull request, the value of the requested
        // attribute
      }
    
      return ( TRUE );
    }
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInWriteRspCmd
     *
     * @brief   Process the "Profile" Write Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclWriteRspCmd_t *writeRspCmd;
      uint8 i;
    
      writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < writeRspCmd->numAttr; i++ )
      {
        // Notify the device of the results of the its original write attributes
        // command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_WRITE
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDefaultRspCmd
     *
     * @brief   Process the "Profile" Default Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
    {
      // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
    
      // Device is notified of the Default Response command.
      (void)pInMsg;
    
      return ( TRUE );
    }
    
    #ifdef ZCL_DISCOVER
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd
     *
     * @brief   Process the Discover Commands Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numCmd; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd
     *
     * @brief   Process the "Profile" Discover Attributes Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverAttrsRspCmd_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverAttrsRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numAttr; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd
     *
     * @brief   Process the "Profile" Discover Attributes Extended Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverAttrsExtRsp_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverAttrsExtRsp_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numAttr; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_DISCOVER
    
    #ifdef ZCL_EZMODE
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessZDOMsgs
     *
     * @brief   Called when this node receives a ZDO/ZDP response.
     *
     * @param   none
     *
     * @return  status
     */
    static void zclSampleTemperatureSensor_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
    {
      zclEZMode_ActionData_t data;
      ZDO_MatchDescRsp_t *pMatchDescRsp;
    
      // Let EZ-Mode know of the Match Descriptor Response
      if ( pMsg->clusterID == Match_Desc_rsp )
      {
        pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
        data.pMatchDescRsp = pMatchDescRsp;
        zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
        osal_mem_free( pMatchDescRsp );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_EZModeCB
     *
     * @brief   The Application is informed of events. This can be used to show on the UI what is
    *           going on during EZ-Mode steering/finding/binding.
     *
     * @param   state - an
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
    {
    #ifdef LCD_SUPPORTED
      char szLine[20];
      char *pStr;
      uint8 err;
    #endif
    
      // time to go into identify mode
      if ( state == EZMODE_STATE_IDENTIFYING )
      {
        zclSampleTemperatureSensor_IdentifyTime = ( EZMODE_TIME / 1000 );  // convert to seconds
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
      }
    
      // autoclosing, show what happened (success, cancelled, etc...)
      if( state == EZMODE_STATE_AUTOCLOSE )
      {
    #ifdef LCD_SUPPORTED
        pStr = NULL;
        err = pData->sAutoClose.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          pStr = "EZMode: Success";
        }
        else if ( err == EZMODE_ERR_NOMATCH )
        {
          pStr = "EZMode: NoMatch"; // not a match made in heaven
        }
        if ( pStr )
        {
          if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif
      }
    
      // finished, either show DstAddr/EP, or nothing (depending on success or not)
      if( state == EZMODE_STATE_FINISH )
      {
        // turn off identify mode
        zclSampleTemperatureSensor_IdentifyTime = 0;
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    
    #ifdef LCD_SUPPORTED
        // if successful, inform user which nwkaddr/ep we bound to
        pStr = NULL;
        err = pData->sFinish.err;
        if( err == EZMODE_ERR_SUCCESS )
        {
          // "EZDst:1234 EP:34"
          osal_memcpy( szLine, "EZDst:", 6 );
          zclHA_uint16toa( pData->sFinish.nwkaddr, &szLine[6] );
          osal_memcpy( &szLine[10], " EP:", 4 );
          _ltoa( pData->sFinish.ep, (void *)(&szLine[14]), 16 );  // _ltoa NULL terminates
          pStr = szLine;
        }
        else if ( err == EZMODE_ERR_BAD_PARAMETER )
        {
          pStr = "EZMode: BadParm";
        }
        else if ( err == EZMODE_ERR_CANCELLED )
        {
          pStr = "EZMode: Cancel";
        }
        else
        {
          pStr = "EZMode: TimeOut";
        }
        if ( pStr )
        {
          if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif  // LCD_SUPPORTED
    
        // show main UI screen 3 seconds after joining network
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT, 3000 );
    
        // report current temperature reading 15 seconds after joinging the network
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT, SAMPLETEMPERATURESENSOR_REPORT_INTERVAL );
      }
    }
    #endif // ZCL_EZMODE
    
    /****************************************************************************
    ****************************************************************************/
    
    
    

    Thermostat Source file :-

    /**************************************************************************************************
      Filename:       zcl_samplethermostat.c
      Revised:        $Date: 2013-10-18 17:02:21 -0700 (Fri, 18 Oct 2013) $
      Revision:       $Revision: 35724 $
    
      Description:    Zigbee Cluster Library - sample device application.
    
    
      Copyright 2013 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
      This device will act as a thermostat.
    
      SCREEN MODES
      ----------------------------------------
      Main:
        - SW1: Set heating setpoint
        - SW2: Invoke EZMode
        - SW3: Set cooling setpoint
        - SW4: Enable/Disable Permit Join
        - SW5: Go to Help screen
    
      Heating Setpoint or Cooling Setpoint:
        - SW1: Increase temperature
        - SW3: Decrease temperature
        - SW5: Save temperature
      ----------------------------------------
    *********************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include "ZComDef.h"
    #include "OSAL.h"
    #include "AF.h"
    #include "ZDApp.h"
    #include "ZDObject.h"
    #include "MT_APP.h"
    #include "MT_SYS.h"
    
    #include "zcl.h"
    #include "zcl_general.h"
    #include "zcl_ha.h"
    #include "zcl_ezmode.h"
    #include "zcl_hvac.h"
    #include "zcl_ms.h"
    
    #include "zcl_samplethermostat.h"
    
    #include "onboard.h"
    
    /* HAL */
    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    byte zclSampleThermostat_TaskID;
    uint8 zclSampleThermostatSeqNum;
    
    static byte gPermitDuration = 0x00;
    
    // Number of recieved messages
    static uint16 rxMsgCount;
    
    /*********************************************************************
     * GLOBAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    afAddrType_t zclSampleThermostat_DstAddr;
    
    #ifdef ZCL_EZMODE
    static void zclSampleThermostat_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
    static void zclSampleThermostat_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
    
    static const zclEZMode_RegisterData_t zclSampleThermostat_RegisterEZModeData =
    {
      &zclSampleThermostat_TaskID,
      SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT,
      SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT,
      &zclSampleThermostatSeqNum,
      zclSampleThermostat_EZModeCB
    };
    
    // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
    
    static cId_t bindingOutClusters[] =
    {
      ZCL_CLUSTER_ID_HVAC_THERMOSTAT
    };
    #define ZCLSAMPLETHERMOSTAT_BINDINGLIST_OUT     1
    
    static cId_t bindingInClusters[] =
    {
      ZCL_CLUSTER_ID_HVAC_THERMOSTAT,
      ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT
    };
    #define ZCLSAMPLETHERMOSTAT_BINDINGLIST_IN      2
    #endif
    
    uint8 giThermostatScreenMode = THERMOSTAT_MAINMODE;   // display the main screen mode first
    
    devStates_t zclSampleThermostat_NwkState = DEV_INIT;
    
    static uint8 aProcessCmd[] = { 1, 0, 0, 0 }; // used for reset command, { length + cmd0 + cmd1 + data }
    
    // Test Endpoint to allow SYS_APP_MSGs
    static endPointDesc_t sampleThermostat_TestEp =
    {
      20,                                 // Test endpoint
      &zclSampleThermostat_TaskID,
      (SimpleDescriptionFormat_t *)NULL,  // No Simple description for this test endpoint
      (afNetworkLatencyReq_t)0            // No Network Latency req
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void zclSampleThermostat_HandleKeys( byte shift, byte keys );
    static void zclSampleThermostat_BasicResetCB( void );
    static void zclSampleThermostat_IdentifyCB( zclIdentify_t *pCmd );
    static void zclSampleThermostat_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
    static void zclSampleThermostat_ProcessIdentifyTimeChange( void );
    static void zclSampleThermostat_ProcessAppMsg( uint8 srcEP, uint8 len, uint8 *msg );
    static void zclSampleThermostat_ProcessFoundationMsg( afAddrType_t *dstAddr, uint16 clusterID,
                                                          zclFrameHdr_t *hdr, zclParseCmd_t *pParseCmd );
    
    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pckt );
    
    // app display functions
    void zclSampleThermostat_LcdDisplayUpdate(void);
    void zclSampleThermostat_LcdDisplayMainMode(void);
    void zclSampleThermostat_LcdDisplayHeatMode(void);
    void zclSampleThermostat_LcdDisplayCoolMode(void);
    void zclSampleThermostat_LcdDisplayHelpMode(void);
    
    // Functions to process ZCL Foundation incoming Command/Response messages
    static void zclSampleThermostat_ProcessIncomingMsg( zclIncomingMsg_t *msg );
    #ifdef ZCL_READ
    static uint8 zclSampleThermostat_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_WRITE
    static uint8 zclSampleThermostat_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_REPORT
    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg );
    #endif  // ZCL_REPORT
    static uint8 zclSampleThermostat_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
    
    /*********************************************************************
     * STATUS STRINGS
     */
    #ifdef LCD_SUPPORTED
    const char sClearLine[]     = " ";
    const char sDeviceName[]    = "   Thermostat";
    const char sSwHeatSet[]     = "SW1: Set Heating";
    const char sSwEZMode[]      = "SW2: EZ-Mode";
    const char sSwCoolSet[]     = "SW3: Set Cooling";
    const char sTempLine2[]     = "SW1:+";
    const char sTempLine3[]     = "SW3:-  SW5:Enter";
    const char sSwHelp[]        = "SW5: Help";
    const char sStoreHeatTemp[] = "HEAT TEMP SAVED";
    const char sStoreCoolTemp[] = "COOL TEMP SAVED";
    #endif
    
    /*********************************************************************
     * ZCL General Profile Callback table
     */
    static zclGeneral_AppCallbacks_t zclSampleThermostat_CmdCallbacks =
    {
      zclSampleThermostat_BasicResetCB,            // Basic Cluster Reset command
      zclSampleThermostat_IdentifyCB,              // Identify command
    #ifdef ZCL_EZMODE
      NULL,                                        // Identify EZ-Mode Invoke command
      NULL,                                        // Identify Update Commission State command
    #endif
      NULL,                                        // Identify Trigger Effect command
      zclSampleThermostat_IdentifyQueryRspCB,      // Identify Query Response command
      NULL,             				                   // On/Off cluster command
      NULL,                                        // On/Off cluster enhanced command Off with Effect
      NULL,                                        // On/Off cluster enhanced command On with Recall Global Scene
      NULL,                                        // On/Off cluster enhanced command On with Timed Off
    #ifdef ZCL_LEVEL_CTRL
      NULL,                                        // Level Control Move to Level command
      NULL,                                        // Level Control Move command
      NULL,                                        // Level Control Step command
      NULL,                                        // Level Control Stop command
    #endif
    #ifdef ZCL_GROUPS
      NULL,                                        // Group Response commands
    #endif
    #ifdef ZCL_SCENES
      NULL,                                        // Scene Store Request command
      NULL,                                        // Scene Recall Request command
      NULL,                                        // Scene Response command
    #endif
    #ifdef ZCL_ALARMS
      NULL,                                        // Alarm (Response) commands
    #endif
    #ifdef SE_UK_EXT
      NULL,                                        // Get Event Log command
      NULL,                                        // Publish Event Log command
    #endif
      NULL,                                        // RSSI Location command
      NULL                                         // RSSI Location Response command
    };
    
    /*********************************************************************
     * @fn          zclSampleThermostat_Init
     *
     * @brief       Initialization function for the zclGeneral layer.
     *
     * @param       none
     *
     * @return      none
     */
    void zclSampleThermostat_Init( byte task_id )
    {
      zclSampleThermostat_TaskID = task_id;
    
      // Set destination address to indirect
      zclSampleThermostat_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
      zclSampleThermostat_DstAddr.endPoint = 0;
      zclSampleThermostat_DstAddr.addr.shortAddr = 0;
    
      // This app is part of the Home Automation Profile
      zclHA_Init( &zclSampleThermostat_SimpleDesc );
    
      // Register the ZCL General Cluster Library callback functions
      zclGeneral_RegisterCmdCallbacks( SAMPLETHERMOSTAT_ENDPOINT, &zclSampleThermostat_CmdCallbacks );
    
      // Register the application's attribute list
      zcl_registerAttrList( SAMPLETHERMOSTAT_ENDPOINT, SAMPLETHERMOSTAT_MAX_ATTRIBUTES, zclSampleThermostat_Attrs );
    
      // Register the Application to receive the unprocessed Foundation command/response messages
      zcl_registerForMsg( zclSampleThermostat_TaskID );
    
    #ifdef ZCL_EZMODE
      // Register EZ-Mode
      zcl_RegisterEZMode( &zclSampleThermostat_RegisterEZModeData );
    
      // Register with the ZDO to receive Match Descriptor Responses
      ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
    #endif
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( zclSampleThermostat_TaskID );
    
      // Register for a test endpoint
      afRegister( &sampleThermostat_TestEp );
    
      ZDO_RegisterForZDOMsg( zclSampleThermostat_TaskID, End_Device_Bind_rsp );
      ZDO_RegisterForZDOMsg( zclSampleThermostat_TaskID, Match_Desc_rsp );
    
    #ifdef LCD_SUPPORTED
      // display the device name
      HalLcdWriteString( (char *)sDeviceName, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn          zclSample_event_loop
     *
     * @brief       Event Loop Processor for zclGeneral.
     *
     * @param       none
     *
     * @return      none
     */
    uint16 zclSampleThermostat_event_loop( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
    
      (void)task_id;  // Intentionally unreferenced parameter
    
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleThermostat_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
    #ifdef ZCL_EZMODE
            case ZDO_CB_MSG:
              zclSampleThermostat_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
              break;
    #endif
    
            case MT_SYS_APP_MSG:
              // Message received from MT
              zclSampleThermostat_ProcessAppMsg( ((mtSysAppMsg_t *)MSGpkt)->endpoint,
                                              ((mtSysAppMsg_t *)MSGpkt)->appDataLen,
                                              ((mtSysAppMsg_t *)MSGpkt)->appData );
              break;
    
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclSampleThermostat_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
              
             case AF_INCOMING_MSG_CMD:
               //UARTprintf("AF_INCOMING_MSG_CMD event \n" );
              zclSampleThermostat_MessageMSGCB( MSGpkt );
              break;
    
            case KEY_CHANGE:
              zclSampleThermostat_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
            case ZDO_STATE_CHANGE:
              zclSampleThermostat_NwkState = (devStates_t)(MSGpkt->hdr.status);
    
    
              // now on the network
              if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
                   ( zclSampleThermostat_NwkState == DEV_ROUTER )   ||
                   ( zclSampleThermostat_NwkState == DEV_END_DEVICE ) )
              {
    #ifndef HOLD_AUTO_START
                // display main mode
                giThermostatScreenMode = THERMOSTAT_MAINMODE;
                zclSampleThermostat_LcdDisplayUpdate();
    #endif
    #ifdef ZCL_EZMODE
                zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
    #endif  // ZCL_EZMODE
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT )
      {
        if ( zclSampleThermostat_IdentifyTime > 0 )
        {
          zclSampleThermostat_IdentifyTime--;
        }
        zclSampleThermostat_ProcessIdentifyTimeChange();
    
        return ( events ^ SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT );
      }
    
      if ( events & SAMPLETHERMOSTAT_MAIN_SCREEN_EVT )
      {
        giThermostatScreenMode = THERMOSTAT_MAINMODE;
        zclSampleThermostat_LcdDisplayUpdate();
    
        return ( events ^ SAMPLETHERMOSTAT_MAIN_SCREEN_EVT );
      }
    
    #ifdef ZCL_EZMODE
      // going on to next state
      if ( events & SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL );   // going on to next state
        return ( events ^ SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT );
      }
    
      // the overall EZMode timer expired, so we timed out
      if ( events & SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
        return ( events ^ SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT );
      }
    #endif // ZLC_EZMODE
    
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_5
     *                 HAL_KEY_SW_4
     *                 HAL_KEY_SW_3
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void zclSampleThermostat_HandleKeys( byte shift, byte keys )
    {
      if ( keys & HAL_KEY_SW_1 )
      {
        // in heating mode
        if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
        {
          // increase heating setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedHeatingSetpoint < zclSampleThermostat_MaxHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_OccupiedHeatingSetpoint + 100;
          }
          else if ( zclSampleThermostat_OccupiedHeatingSetpoint >= zclSampleThermostat_MaxHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_MaxHeatSetpointLimit;
          }
        }
        // in cooling mode
        else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
        {
          // increase cooling setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedCoolingSetpoint < zclSampleThermostat_MaxCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_OccupiedCoolingSetpoint + 100;
          }
          else if ( zclSampleThermostat_OccupiedCoolingSetpoint >= zclSampleThermostat_MaxCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_MaxCoolSetpointLimit;
          }
        }
        // set screen mode to heat mode
        else
        {
          giThermostatScreenMode = THERMOSTAT_HEATMODE;
        }
      }
    
      if ( keys & HAL_KEY_SW_2 )
      {
        if ( ( giThermostatScreenMode == THERMOSTAT_MAINMODE ) ||
             ( giThermostatScreenMode == THERMOSTAT_HELPMODE ) )
        {
          giThermostatScreenMode = THERMOSTAT_MAINMODE;
    
    #ifdef ZCL_EZMODE
          zclEZMode_InvokeData_t ezModeData;
          static uint16 clusterIDs[] = { ZCL_CLUSTER_ID_HVAC_THERMOSTAT };   // only bind on the Thermostat cluster
    
          // Invoke EZ-Mode
          ezModeData.endpoint = SAMPLETHERMOSTAT_ENDPOINT; // endpoint on which to invoke EZ-Mode
          if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
               ( zclSampleThermostat_NwkState == DEV_ROUTER )   ||
               ( zclSampleThermostat_NwkState == DEV_END_DEVICE ) )
          {
            ezModeData.onNetwork = TRUE;      // node is already on the network
          }
          else
          {
            ezModeData.onNetwork = FALSE;     // node is not yet on the network
          }
          ezModeData.initiator = TRUE;        // Thermostat is an initiator
          ezModeData.numActiveInClusters = 0;
          ezModeData.pActiveInClusterIDs = NULL;
          ezModeData.numActiveOutClusters = 1;   // active output cluster
          ezModeData.pActiveOutClusterIDs = clusterIDs;
          zcl_InvokeEZMode( &ezModeData );
    
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
    #endif
    
          // NOT ZCL_EZMODE, use EndDeviceBind
    #else
          zAddrType_t dstAddr;
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
    
          // Initiate an End Device Bind Request, this bind request will
          // only use a cluster list that is important to binding.
          dstAddr.addrMode = afAddr16Bit;
          dstAddr.addr.shortAddr = 0;   // Coordinator makes the match
          ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                                SAMPLETHERMOSTAT_ENDPOINT,
                                ZCL_HA_PROFILE_ID,
                                ZCLSAMPLETHERMOSTAT_BINDINGLIST_IN, bindingInClusters,
                                ZCLSAMPLETHERMOSTAT_BINDINGLIST_OUT, bindingOutClusters,
                                TRUE );
    #endif // ZCL_EZMODE
        }
      }
    
      if ( keys & HAL_KEY_SW_3 )
      {
        if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
        {
          // decrease cooling setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedCoolingSetpoint > zclSampleThermostat_MinCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_OccupiedCoolingSetpoint - 100;
          }
          else if ( zclSampleThermostat_OccupiedCoolingSetpoint <= zclSampleThermostat_MinCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_MinCoolSetpointLimit;
          }
        }
        // in heating mode
        else if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
        {
          // decrease heating setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedHeatingSetpoint > zclSampleThermostat_MinHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_OccupiedHeatingSetpoint - 100;
          }
          else if ( zclSampleThermostat_OccupiedHeatingSetpoint <= zclSampleThermostat_MinHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_MinHeatSetpointLimit;
          }
        }
        // set screen mode to cool mode
        else
        {
          giThermostatScreenMode = THERMOSTAT_COOLMODE;
        }
      }
    
      if ( keys & HAL_KEY_SW_4 )
      {
        giThermostatScreenMode = THERMOSTAT_MAINMODE;
    
        if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
             ( zclSampleThermostat_NwkState == DEV_ROUTER ) )
        {
          // toggle permit join
          gPermitDuration = gPermitDuration ? 0 : 0xff;
          NLME_PermitJoiningRequest( gPermitDuration  );
        }
      }
    
      if ( shift && ( keys & HAL_KEY_SW_5 ) )
      {
        zclSampleThermostat_BasicResetCB();
      }
      else if ( keys & HAL_KEY_SW_5 )
      {
        if ( keys & HAL_KEY_SW_5 )
        {
          // in heating or cooling setpoint mode
          if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
          {
    #ifdef LCD_SUPPORTED
            // save current heat setpoint temperature
            HalLcdWriteString( (char *)sStoreHeatTemp, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
          {
    #ifdef LCD_SUPPORTED
            // save current cool setpoint temperature
            HalLcdWriteString( (char *)sStoreCoolTemp, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
          {
            giThermostatScreenMode = THERMOSTAT_HELPMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_HELPMODE )
          {
    #ifdef LCD_SUPPORTED
            HalLcdWriteString( (char *)sClearLine, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
        }
      }
    
      // update display
      zclSampleThermostat_LcdDisplayUpdate();
    }
    
    
    /*********************************************************************
     * @fn      zclSampleThermostat_MessageMSGCB
     *
     * @brief   Data message processor callback.  This function processes
     *          any incoming data - probably from other devices.  So, based
     *          on cluster ID, perform the intended action.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )
    {  HalLcdWriteString("AF_msg_callback_fn", HAL_LCD_LINE_1 );
      switch ( pkt->clusterId )
      {
        case ZCL_CLUSTER_ID_HVAC_THERMOSTAT:
    
          rxMsgCount += 1;  // Count this message
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_BLINK );  // Blink an LED
    
          HalLcdWriteString( (char*)pkt->cmd.Data, HAL_LCD_LINE_2 );
          HalLcdWriteStringValue( "Rcvd:", rxMsgCount, 10, HAL_LCD_LINE_3 );
    
          break;
      }
    }
    
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayUpdate
     *
     * @brief   Called to update the LCD display.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayUpdate( void )
    {
      // use LEDs to show heating or cooling cycles based off local temperature
      if ( zclSampleThermostat_LocalTemperature != NULL )
      {
        if ( zclSampleThermostat_LocalTemperature <= zclSampleThermostat_OccupiedHeatingSetpoint )
        {
          // turn on heating
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_HEAT;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
        }
        else if ( zclSampleThermostat_LocalTemperature >= zclSampleThermostat_OccupiedCoolingSetpoint )
        {
          // turn on cooling
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_COOL;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
        }
        else
        {
          // turn off heating/cooling
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_OFF;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
        }
      }
    
      if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
      {
        zclSampleThermostat_LcdDisplayHeatMode();
      }
      else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
      {
        zclSampleThermostat_LcdDisplayCoolMode();
      }
      else if ( giThermostatScreenMode == THERMOSTAT_HELPMODE )
      {
        zclSampleThermostat_LcdDisplayHelpMode();
      }
      else
      {
        zclSampleThermostat_LcdDisplayMainMode();
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayMainMode
     *
     * @brief   Called to display the main screen on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayMainMode( void )
    {
      char sDisplayTemp[16];
    
      if ( zclSampleThermostat_NwkState == DEV_ZB_COORD )
      {
        zclHA_LcdStatusLine1( 0 );
      }
      else if ( zclSampleThermostat_NwkState == DEV_ROUTER )
      {
        zclHA_LcdStatusLine1( 1 );
      }
      else if ( zclSampleThermostat_NwkState == DEV_END_DEVICE )
      {
        zclHA_LcdStatusLine1( 2 );
      }
    
      osal_memcpy( sDisplayTemp, "TEMP: ", 6 );
    
      // if local temperature has not been set, make note on display
      if ( zclSampleThermostat_LocalTemperature == NULL )
      {
        osal_memcpy( &sDisplayTemp[6], "N/A", 4 );
      }
      else
      {
        _ltoa( ( zclSampleThermostat_LocalTemperature / 100 ), (void *)(&sDisplayTemp[6]), 10 ); // only use whole number
        osal_memcpy( &sDisplayTemp[8], "C", 2 );
      }
    #ifdef LCD_SUPPORTED
      // display current temperature
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_2 );
    #endif
    
    #ifdef LCD_SUPPORTED
      if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
           ( zclSampleThermostat_NwkState == DEV_ROUTER ) )
      {
        // display help key with permit join status
        if ( gPermitDuration )
        {
          HalLcdWriteString( "SW5: Help      *", HAL_LCD_LINE_3 );
        }
        else
        {
          HalLcdWriteString( "SW5: Help       ", HAL_LCD_LINE_3 );
        }
      }
      else
      {
        // display help key
        HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3);
      }
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayHelpMode
     *
     * @brief   Called to display the SW options on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayHelpMode( void )
    {
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sSwHeatSet, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sSwCoolSet, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayHeatMode
     *
     * @brief   Called to display the heating setpoint temperature on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayHeatMode( void )
    {
    #ifdef LCD_SUPPORTED
      char sDisplayTemp[16];
    
      osal_memcpy( sDisplayTemp, "HEAT TEMP: ", 11 );
      _ltoa( ( zclSampleThermostat_OccupiedHeatingSetpoint / 100 ), (void *)(&sDisplayTemp[11]), 10 ); // only use whole number
      osal_memcpy( &sDisplayTemp[13], "C", 2 );
    
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sTempLine2, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sTempLine3, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayCoolMode
     *
     * @brief   Called to display the cooling setpoint temperature on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayCoolMode( void )
    {
    #ifdef LCD_SUPPORTED
      char sDisplayTemp[16];
    
      osal_memcpy(sDisplayTemp, "COOL TEMP: ", 11);
      _ltoa( ( zclSampleThermostat_OccupiedCoolingSetpoint / 100 ), (void *)(&sDisplayTemp[11]), 10 ); // only use whole number
      osal_memcpy( &sDisplayTemp[13], "C", 2 );
    
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sTempLine2, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sTempLine3, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessIdentifyTimeChange
     *
     * @brief   Called to process any change to the IdentifyTime attribute.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessIdentifyTimeChange( void )
    {
      if ( zclSampleThermostat_IdentifyTime > 0 )
      {
        osal_start_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT, 1000 );
        HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
      }
      else
      {
        if ( zclSampleThermostat_OnOff )
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
        }
        else
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
        }
    
        osal_stop_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessAppMsg
     *
     * @brief   Process DoorLock messages
     *
     * @param   srcEP - Sending Apps endpoint
     * @param   len - number of bytes
     * @param   msg - pointer to message
     *          0 - lo byte destination address
     *          1 - hi byte destination address
     *          2 - destination endpoint
     *          3 - lo byte cluster ID
     *          4 - hi byte cluster ID
     *          5 - message length
     *          6 - destination address mode (first byte of data)
     *          7 - zcl command frame
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessAppMsg( uint8 srcEP, uint8 len, uint8 *msg )
    {
      afAddrType_t dstAddr;
      uint16 clusterID;
      zclFrameHdr_t hdr;
      uint8 *pData;
      uint8 dataLen;
    
      dstAddr.addr.shortAddr = BUILD_UINT16( msg[0], msg[1] );
      msg += 2;
      dstAddr.endPoint = *msg++;
      clusterID = BUILD_UINT16( msg[0], msg[1] );
      msg += 2;
      dataLen = *msg++; // Length of message (Z-Tool can support up to 255 octets)
      dstAddr.addrMode = (afAddrMode_t)(*msg++);
      dataLen--; // Length of ZCL frame
    
      // Begining of ZCL frame
      pData = zclParseHdr( &hdr, msg );
      dataLen -= (uint8)( pData - msg );
    
      // Is this a foundation type message?
      if ( zcl_ProfileCmd( hdr.fc.type ) )
      {
        if ( hdr.fc.manuSpecific )
        {
          // We don't support any manufacturer specific command -- just forward it.
          zcl_SendCommand( srcEP, &dstAddr, clusterID, hdr.commandID, FALSE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr.fc.disableDefaultRsp, hdr.manuCode, hdr.transSeqNum, dataLen, pData );
        }
        else
        {
          zclParseCmd_t cmd;
    
          cmd.endpoint = srcEP;
          cmd.dataLen = dataLen;
          cmd.pData = pData;
    
          zclSampleThermostat_ProcessFoundationMsg( &dstAddr, clusterID, &hdr, &cmd );
        }
      }
      else
      {
        // Nope, must be specific to the cluster ID
        if ( hdr.fc.manuSpecific )
        {
          // We don't support any manufacturer specific command -- just forward it.
          zcl_SendCommand( srcEP, &dstAddr, clusterID, hdr.commandID, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr.fc.disableDefaultRsp, hdr.manuCode, hdr.transSeqNum, dataLen, pData );
        }
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessFoundationMsg
     *
     * @brief   Process Foundation message
     *
     * @param   srcEP - Sending Apps endpoint
     * @param   dstAddr - where to send the request
     * @param   clusterID - real cluster ID
     * @param   hdr - pointer to the message header
     * @param   len - length of the received message
     * @param   data - received message
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessFoundationMsg( afAddrType_t *dstAddr, uint16 clusterID,
                                                    zclFrameHdr_t *hdr, zclParseCmd_t *pParseCmd )
    {
    #if defined(ZCL_READ) || defined(ZCL_WRITE) || defined(ZCL_REPORT) || defined(ZCL_DISCOVER)
      void *cmd;
    #endif
    
      switch ( hdr->commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ:
          cmd = zclParseInReadCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendRead( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReadCmd_t *)cmd,
                          ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWrite( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                           ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_WRITE_UNDIVIDED:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWriteUndivided( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                                    ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_WRITE_NO_RSP:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWriteNoRsp( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                                ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_WRITE
    
    #ifdef ZCL_REPORT
        case ZCL_CMD_CONFIG_REPORT:
          cmd = zclParseInConfigReportCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendConfigReportCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr,  clusterID, (zclCfgReportCmd_t *)cmd,
                                     ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          cmd = zclParseInReadReportCfgCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendReadReportCfgCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReadReportCfgCmd_t *)cmd,
                                      ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_REPORT:
          cmd = zclParseInReportCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendReportCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReportCmd_t *)cmd,
                               ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_REPORT
    #ifdef ZCL_DISCOVER
        case ZCL_CMD_DISCOVER_ATTRS:
          cmd = zclParseInDiscAttrsCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendDiscoverAttrsCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclDiscoverAttrsCmd_t *)cmd,
                                      ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_DISCOVER
    
        default:
          // Unsupported command -- just forward it.
          zcl_SendCommand( pParseCmd->endpoint, dstAddr, clusterID, hdr->commandID, FALSE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr->fc.disableDefaultRsp, 0, hdr->transSeqNum, pParseCmd->dataLen, pParseCmd->pData );
          break;
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_BasicResetCB
     *
     * @brief   Callback from the ZCL General Cluster Library
     *          to set all the Basic Cluster attributes to default values.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_BasicResetCB( void )
    {
      // Put device back to factory default settings
      zgWriteStartupOptions( ZG_STARTUP_SET, 3 );   // bit set both default configuration and default network
    
      // restart device
      MT_SysCommandProcessing( aProcessCmd );
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_IdentifyCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Command for this application.
     *
     * @param   srcAddr - source address and endpoint of the response message
     * @param   identifyTime - the number of seconds to identify yourself
     *
     * @return  none
     */
    static void zclSampleThermostat_IdentifyCB( zclIdentify_t *pCmd )
    {
      zclSampleThermostat_IdentifyTime = pCmd->identifyTime;
      zclSampleThermostat_ProcessIdentifyTimeChange();
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_IdentifyQueryRspCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Query Response Command for this application.
     *
     * @param   srcAddr - requestor's address
     * @param   timeout - number of seconds to identify yourself (valid for query response)
     *
     * @return  none
     */
    static void zclSampleThermostat_IdentifyQueryRspCB(  zclIdentifyQueryRsp_t *pRsp )
    {
      (void)pRsp;
    #ifdef ZCL_EZMODE
      {
        zclEZMode_ActionData_t data;
        data.pIdentifyQueryRsp = pRsp;
        zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
      }
    #endif
    }
    
    /******************************************************************************
     *
     *  Functions for processing ZCL Foundation incoming Command/Response messages
     *
     *****************************************************************************/
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessIncomingMsg
     *
     * @brief   Process ZCL Foundation incoming message
     *
     * @param   pInMsg - pointer to the received message
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg)
    {
      switch ( pInMsg->zclHdr.commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ_RSP:
          zclSampleThermostat_ProcessInReadRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE_RSP:
          zclSampleThermostat_ProcessInWriteRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_REPORT
        case ZCL_CMD_CONFIG_REPORT:
          //zclSampleThermostat_ProcessInConfigReportCmd( pInMsg );
          break;
    
        case ZCL_CMD_CONFIG_REPORT_RSP:
          //zclSampleThermostat_ProcessInConfigReportRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          //zclSampleThermostat_ProcessInReadReportCfgCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG_RSP:
          //zclSampleThermostat_ProcessInReadReportCfgRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_REPORT:
          zclSampleThermostat_ProcessInReportCmd( pInMsg );
          break;
    #endif
        case ZCL_CMD_DEFAULT_RSP:
          zclSampleThermostat_ProcessInDefaultRspCmd( pInMsg );
          break;
    
        default:
          break;
      }
    
      if ( pInMsg->attrCmd )
      {
        osal_mem_free( pInMsg->attrCmd );
      }
    }
    
    #ifdef ZCL_READ
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInReadRspCmd
     *
     * @brief   Process the "Profile" Read Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReadRspCmd_t *readRspCmd;
      uint8 i;
    
      readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
      for (i = 0; i < readRspCmd->numAttr; i++)
      {
        // Notify the originator of the results of the original read attributes
        // attempt and, for each successfull request, the value of the requested
        // attribute
      }
    
      return ( TRUE );
    }
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInWriteRspCmd
     *
     * @brief   Process the "Profile" Write Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclWriteRspCmd_t *writeRspCmd;
      uint8 i;
    
      writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
      for (i = 0; i < writeRspCmd->numAttr; i++)
      {
        // Notify the device of the results of the its original write attributes
        // command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_WRITE
    
    #ifdef ZCL_REPORT
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInReportCmd
     *
     * @brief   Process the "Profile" Report Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReportCmd_t *pInTempSensorReport;
      zclReportCmd_t *pOutDemandReport;
      uint8 outDemandBuffer[sizeof( zclReportCmd_t ) + ( 2 * sizeof( zclReport_t ) )];
      bool send = TRUE;
    
      pInTempSensorReport = (zclReportCmd_t *)pInMsg->attrCmd;
    
      if ( pInTempSensorReport->attrList[0].attrID != ATTRID_MS_TEMPERATURE_MEASURED_VALUE )
      {
        return;
      }
    
      pOutDemandReport = (zclReportCmd_t *)outDemandBuffer;
    
      // store the current temperature value sent over the air from temperature sensor
      zclSampleThermostat_LocalTemperature = BUILD_UINT16(pInTempSensorReport->attrList[0].attrData[0], pInTempSensorReport->attrList[0].attrData[1]);
    
      // update display with current temperature information, set current mode
      zclSampleThermostat_LcdDisplayUpdate();
    
      pOutDemandReport->numAttr = 2;
      pOutDemandReport->attrList[0].attrID = ATTRID_HVAC_THERMOSTAT_PI_HEATING_DEMAND;
      pOutDemandReport->attrList[0].dataType = ZCL_DATATYPE_UINT8;
      pOutDemandReport->attrList[1].attrID = ATTRID_HVAC_THERMOSTAT_PI_COOLING_DEMAND;
      pOutDemandReport->attrList[1].dataType = ZCL_DATATYPE_UINT8;
    
      // send heating demand to heating/cooling unit
      if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_HEAT )
      {
        zclSampleThermostat_HeatingDemand = 100; // 100%
        zclSampleThermostat_CoolingDemand = 0;  // off
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      // send cooling demand to heating/cooling unit
      else if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_COOL )
      {
        zclSampleThermostat_HeatingDemand = 0;  // off
        zclSampleThermostat_CoolingDemand = 100;  // 100%
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      // turn heating/cooling unit off
      else if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_OFF )
      {
        zclSampleThermostat_HeatingDemand = 0;  // off
        zclSampleThermostat_CoolingDemand = 0;  // off
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      else
      {
        send = FALSE;
      }
    
      if ( send )
      {
        zcl_SendReportCmd( SAMPLETHERMOSTAT_ENDPOINT, &zclSampleThermostat_DstAddr,
                          ZCL_CLUSTER_ID_HVAC_THERMOSTAT,
                          pOutDemandReport, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleThermostatSeqNum++ );
      }
    }
    #endif  // ZCL_REPORT
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInDefaultRspCmd
     *
     * @brief   Process the "Profile" Default Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
    {
      // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
    
      // Device is notified of the Default Response command.
      (void)pInMsg;
    
      return ( TRUE );
    }
    
    #ifdef ZCL_EZMODE
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessZDOMsgs
     *
     * @brief   Called when this node receives a ZDO/ZDP response.
     *
     * @param   none
     *
     * @return  status
     */
    static void zclSampleThermostat_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
    {
      zclEZMode_ActionData_t data;
      ZDO_MatchDescRsp_t *pMatchDescRsp;
    
      // Let EZ-Mode know of the Match Descriptor Response
      if ( pMsg->clusterID == Match_Desc_rsp )
      {
        pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
        data.pMatchDescRsp = pMatchDescRsp;
        zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
        osal_mem_free( pMatchDescRsp );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_EZModeCB
     *
     * @brief   The Application is informed of events. This can be used to show on the UI what is
    *           going on during EZ-Mode steering/finding/binding.
     *
     * @param   state - EZ-Mode state
     *          pData - data appropriate to state
     *
     * @return  none
     */
    static void zclSampleThermostat_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
    {
    #ifdef LCD_SUPPORTED
      char szLine[20];
      char *pStr;
      uint8 err;
    #endif
    
      // time to go into identify mode
      if ( state == EZMODE_STATE_IDENTIFYING )
      {
        zclSampleThermostat_IdentifyTime = (EZMODE_TIME / 1000);  // convert to seconds
        zclSampleThermostat_ProcessIdentifyTimeChange();
      }
    
      // autoclosing, show what happened (success, cancelled, etc...)
      if( state == EZMODE_STATE_AUTOCLOSE )
      {
    #ifdef LCD_SUPPORTED
        pStr = NULL;
        err = pData->sAutoClose.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          pStr = "EZMode: Success";
        }
        if ( pStr )
        {
          if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
        }
    #endif
      }
    
      // finished, either show DstAddr/EP, or nothing (depending on success or not)
      if ( state == EZMODE_STATE_FINISH )
      {
        // turn off identify mode
        zclSampleThermostat_IdentifyTime = 0;
        zclSampleThermostat_ProcessIdentifyTimeChange();
    
    #ifdef LCD_SUPPORTED
        // if successful, inform user which nwkaddr/ep we bound to
        pStr = NULL;
        err = pData->sFinish.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          // "EZDst:1234 EP:34"
          osal_memcpy(szLine, "EZDst:", 6);
          zclHA_uint16toa( pData->sFinish.nwkaddr, &szLine[6]);
          osal_memcpy(&szLine[10], " EP:", 4);
          _ltoa( pData->sFinish.ep, (void *)(&szLine[14]), 16 );  // _ltoa NULL terminates
          pStr = szLine;
        }
        else if ( err == EZMODE_ERR_BAD_PARAMETER )
        {
          pStr = "EZMode: BadParm";
        }
        else if ( err == EZMODE_ERR_CANCELLED )
        {
          pStr = "EZMode: Cancel";
        }
        else if ( err == EZMODE_ERR_NOMATCH )
        {
          pStr = "EZMode: NoMatch"; // not a match made in heaven
        }
        else
        {
          pStr = "EZMode: TimeOut";
        }
        if ( pStr )
        {
          if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif  // LCD_SUPPORTED
    
        // show main UI screen 3 seconds after completing EZ-Mode
        osal_start_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_MAIN_SCREEN_EVT, 3000 );
      }
    }
    #endif // ZCL_EZMODE
    
    /****************************************************************************
    ****************************************************************************/
    
    
    

    plz help me to make this work and to solve this problem......

    Thanks & Regards,

    Maneesh singh

  • Hello YiKai Chen Sir,

    one more thing i want share that in packet analyser i found that ->

    1) in Generic APP sample code -> it is sending the data from AF (profile)layer but

    when i tried with Temp sensor i found that there is no such packet which shows AF data is being transmitted from temp sensor.....

    so what i understand is that data is not being transmitted from Temp sensor i dont know what is the reason ? thats why in my previous post i attached my source file so that once u hav look at it if i am doing anything wrong.....

    plz sir once hav a look at my source file which i send u in previous post....plz sir..

    here is captured packet detail ->

    GenericApp which is sending Msg properly with AF_datarequest API ->

    Temp Sensor(successfully sending temp data but not sending msg by AF_DataRequest) Packet Detail ->

      

    NOTE :- since my Evolution Licence for Ubique Packet Analyzer is Expired so i am using another packet analyzer and sending screenshot of it......sorry for inconvenience......

    Plz hav alook at it and suggest me what i need to do to make AF_DataRequest to work.....

    plz help me sir....

    Thanks & Regards,

    Maneesh 

  • In your zcl_sampletemperaturesensor.c, you can't call AF_DataRequest right after zcl_SendReportCmd. If you send message right after another immediately, the second one won't be sent. Try to remove zcl_SendReportCmd and only call AF_DataRequest.

  • hello sir,

    As u suggested i did the same ->

    in sample temp sensor in commented out the zcl_SendReportCmd like below :-

    static void zclSampleTemperatureSensor_SendTemp( void )
    {

    /*  zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
    ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
    pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );  */

    if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
    ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
    (byte)osal_strlen( theMessageData ) + 1,
    (byte *)&theMessageData,
    &zclSampleTemperatureSensor_TransID,
    AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )


    {
    theMessageData = "success" ;
    HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
    // Successfully requested to be sent.
    }
    else
    {
    theMessageData = "not success" ;
    HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
    // Error occurred in request to send.
    }

    osal_mem_free( pReportCmd );
    #endif // ZCL_REPORT
    }

    but still it is not working.... i didnt did any change in thermostat side it is same like which i send u in previous post...

    i am sending u packet detail and breakpoint data detail.....

     

    in this screen shot also u can see how i commented out zcl_SendReportCmd API and values of AF_DatRequest API during breakpoints....

    in temp sensor i kept breakpoint at 3 places ->

    1) in event loop at SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT condition

    2) in send_temp fn at AF_dataRequest cmd

    3) at case AF_DATA_CONFIRM_CMD in eventloop

    and breakpoint is hitting all the 3 places..

    but in thermostat side i kept breakpoints at following places ->

    1) at case AF_INCOMING_MSG_CMD in event loop

    2) at af_incmoing msg callback fn i.e 

    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )

    {

    }

    3) at 

    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )  fn

    but unfortunately breakpoint is not hitting any place......

    i dont understand what is reason why temp sensor is not sending msg from AF_DataRequest

    plz help me to solve this issue sir...

    NOTE :- For sending msg from AF_DataRequest i am not doing any changes in ->

    zcl_sampletemperaturesensor.h ,  zcl_sampletemperaturesensor_Data.h and  <>osal.c file

    i am doing changes in zcl_sampletemperaturesensor.c file which i already send u in my previous post....

    the only change i am doing in <>.c file is ->

    1) in eventloop fn i added  case AF_DATA_CONFIRM_CMD and few other line (same as in GenericApp)

    2) using AF_DataRequest API in send temp fn as described u earlier and as shown in pics above....

    for receiving this msg at thermostat side i am adding only following lines in <>.c file except that i am not doing any changes in any other files... ->

    1) in event loop        

    case AF_INCOMING_MSG_CMD:
    zclSampleThermostat_MessageMSGCB( MSGpkt );  //calling calback fn for priniting msg on screen
    break;

    2) and implement callback as given in GenericAPP.....

    is there any thing i am missing ? or i am not implementing ? plz help me sir....

    Waiting for ur reply.......

    Thanks and Regards,

    Maneeesh singh

  • Hello YiKai Chen sir,

    any solution sir for above mention problem.....

    Thanks & Regards,

    Maneesh singh

  • Hello YiKai Chen sir,

    plz reply sir.....

  • Hello YiKai Chen sir,

    plz reply sir how can i solve this issue....

     i removed the zcl_sendreportcmd and used only Af_DataRequst API.....but still it is not working... in my previous post i send u screenshot of breakpoint and packet detail of that testing...

    plz hav a look at it and suggest me what i am doing wrong and why it is not working ?

    plz help me sir.....plz reply...

    Thanks & Regards,

    Maneesh Singh 

  • Hello YiKai Chen sir,

    As u suggested i did the same ->

    in sample temp sensor in commented out the zcl_SendReportCmd like below :-

    static void zclSampleTemperatureSensor_SendTemp( void )
    {

    /*  zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
    ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
    pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );  */

    if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
    ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
    (byte)osal_strlen( theMessageData ) + 1,
    (byte *)&theMessageData,
    &zclSampleTemperatureSensor_TransID,
    AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )


    {
    theMessageData = "success" ;
    HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
    // Successfully requested to be sent.
    }
    else
    {
    theMessageData = "not success" ; 
    HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
    // Error occurred in request to send.
    }

    osal_mem_free( pReportCmd );
    #endif // ZCL_REPORT
    }

    but still it is not working.... i didnt did any change in thermostat side it is same like which i send u in previous post...

    i am sending u packet detail and breakpoint data detail.....

     

    in this screen shot also u can see how i commented out zcl_SendReportCmd API and values of AF_DatRequest API during breakpoints....

    in temp sensor i kept breakpoint at 3 places ->

    1) in event loop at SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT condition

    2) in send_temp fn at AF_dataRequest cmd

    3) at case AF_DATA_CONFIRM_CMD in eventloop

    and breakpoint is hitting all the 3 places..

    but in thermostat side i kept breakpoints at following places ->

    1) at case AF_INCOMING_MSG_CMD in event loop

    2) at af_incmoing msg callback fn i.e 

    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )

    {

    }

    3) at 

    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )  fn

    but unfortunately breakpoint is not hitting any place......

    i dont understand what is reason why temp sensor is not sending msg from AF_DataRequest

    plz help me to solve this issue sir...

    NOTE :- For sending msg from AF_DataRequest i am not doing any changes in ->

    zcl_sampletemperaturesensor.h ,  zcl_sampletemperaturesensor_Data.h and  <>osal.c file

    i am doing changes in zcl_sampletemperaturesensor.c file which i already send u in my previous post....

    the only change i am doing in <>.c file is ->

    1) in eventloop fn i added  case AF_DATA_CONFIRM_CMD and few other line (same as in GenericApp)

    2) using AF_DataRequest API in send temp fn as described u earlier and as shown in pics above....

    for receiving this msg at thermostat side i am adding only following lines in <>.c file except that i am not doing any changes in any other files... ->

    1) in event loop        

    case AF_INCOMING_MSG_CMD:
    zclSampleThermostat_MessageMSGCB( MSGpkt );  //calling calback fn for priniting msg on screen
    break;

    2) and implement callback as given in GenericAPP.....

    is there any thing i am missing ? or i am not implementing ? plz help me sir....

    Waiting for ur reply.......

    Thanks and Regards,

    Maneeesh singh

  • I don't know where your problem is. However, if I modify my sampletemperaturesensor and samplethermostat as the followings, I can send string.

    In sampletemperaturesensor, you can revise zclSampleTemperatureSensor_SendTemp().

    char *theMessageData = "Hello i am temp Sensor";
    static void zclSampleTemperatureSensor_SendTemp( void )
    {
    #ifdef ZCL_REPORT
      zclReportCmd_t *pReportCmd;

      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = 0x0020;//ATTRID_MS_TEMPERATURE_MEASURED_VALUE;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_CHAR_STR;
        pReportCmd->attrList[0].attrData = (void *)theMessageData;//(&zclSampleTemperatureSensor_MeasuredValue);

        zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
                           ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                           pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );
      }

      osal_mem_free( pReportCmd );
    #endif  // ZCL_REPORT
    }

    In samplethermostat, you can revise zclSampleThermostat_ProcessInReportCmd().

    uint8 *ppp=NULL;
    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReportCmd_t *pInTempSensorReport;
      zclReportCmd_t *pOutDemandReport;
      uint8 outDemandBuffer[sizeof( zclReportCmd_t ) + ( 2 * sizeof( zclReport_t ) )];
      bool send = TRUE;

      pInTempSensorReport = (zclReportCmd_t *)pInMsg->attrCmd;
      TclusterId=pInMsg->clusterId;
      TsrcAddr=pInMsg->srcAddr;
      TendPoint=pInMsg->endPoint;

      zclGeneral_SendOnOff_CmdToggle( TendPoint, &TsrcAddr, FALSE, 0 );
      /*if ( pInTempSensorReport->attrList[0].attrID != ATTRID_MS_TEMPERATURE_MEASURED_VALUE )
      {
        return;
      }*/

      pOutDemandReport = (zclReportCmd_t *)outDemandBuffer;

      // store the current temperature value sent over the air from temperature sensor
      zclSampleThermostat_LocalTemperature = BUILD_UINT16(pInTempSensorReport->attrList[0].attrData[0], pInTempSensorReport->attrList[0].attrData[1]);
      _dataLen = zclSampleThermostat_LocalTemperature;

      ppp=&pInTempSensorReport->attrList[0].attrData[0]; //ppp has the string!!!

  • The result on CC2530DK is attached for your reference.

  • Hello YiKai Chen sir,

    Thanks for your effort and support !!!!!!!!!

    1) if u remember in one of my previous post u only help me and guided me how to send string with zcl_sendreport  API Cmd.... and i am also able to send string properly with zcl_sendreport cmd.... (i am  also able to send int array  with this API but only upto 10-12 byte of data ). 

    2) after that i asked u that i want to stream real-time audio data over the zigbee and u only suggested me  to use  AF_datarequest API cmd.... and i tested AF_datarequest API in Generic app project and i am able to transfer 70-80 byte of data successfully.....

    3) but now i want to use same AF_datarequest API in my project so that here in my project i can test transfer of data bytes and if it is successful i'll move forward and implement some logic to send audio data as suggested by you.....

    4) but now i got stuck becoz this AF_datarequest API is working fine in Generic APP but not working in my code.... for that reason i requested your help and did the changes as u suggested me but still it is not working..... reason is unknown ?

    5) i am requesting you if possible will you plz try to compile and run the source code which i am attaching here at your side and will you plz check is this working there or  what is the problem ? 

    6) i did changes in only <>.c files and rest of the file is untouched so here i am sending you only <>.c file....

    /**************************************************************************************************
      Filename:       zcl_sampletemperaturesensor.c
      Revised:        $Date: 2013-10-18 11:49:27 -0700 (Fri, 18 Oct 2013) $
      Revision:       $Revision: 35718 $
    
      Description:    Zigbee Cluster Library - sample device application.
    
    
      Copyright 2013 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
      This device will act as a temperature sensor. It updates the current
      temperature on the thermostat when the user sends the desired
      temperature using SW1.
    
      SCREEN MODES
      ----------------------------------------
      Main:
        - SW1: Send current temperature
        - SW2: Invoke EZMode
        - SW3: Adjust temperature
        - SW5: Go to Help screen
    
      Temperature:
        - SW1: Increase temperature
        - SW3: Decrease temperature
        - SW5: Enter temperature
      ----------------------------------------
    *********************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include "ZComDef.h"
    #include "OSAL.h"
    #include "AF.h"
    #include "ZDApp.h"
    #include "ZDObject.h"
    #include "ZDProfile.h"
    #include "MT_SYS.h"
    
    #include "zcl.h"
    #include "zcl_general.h"
    #include "zcl_ha.h"
    #include "zcl_ezmode.h"
    #include "zcl_ms.h"
    
    #include "zcl_sampletemperaturesensor.h"
    
    #include "onboard.h"
    
    /* HAL */
    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    
    /*********************************************************************
     * MACROS
     */
    
    // how often to report temperature
    #define SAMPLETEMPERATURESENSOR_REPORT_INTERVAL   10000
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    byte zclSampleTemperatureSensor_TaskID;
    
    uint8 zclSampleTemperatureSensorSeqNum;
    
    static byte gPermitDuration = 0x00;
    
    byte zclSampleTemperatureSensor_TransID;  // This is the unique message ID (counter) as given in Generic App project
    
    /*********************************************************************
     * GLOBAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    afAddrType_t zclSampleTemperatureSensor_DstAddr;
    
    #ifdef ZCL_EZMODE
    static void zclSampleTemperatureSensor_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
    static void zclSampleTemperatureSensor_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
    
    static const zclEZMode_RegisterData_t zclSampleTemperatureSensor_RegisterEZModeData =
    {
      &zclSampleTemperatureSensor_TaskID,
      SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT,
      SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT,
      &zclSampleTemperatureSensorSeqNum,
      zclSampleTemperatureSensor_EZModeCB
    };
    
    // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
    
    static cId_t bindingOutClusters[] =
    {
      ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT
    };
    #define ZCLSAMPLETEMPERATURESENSOR_BINDINGLIST        1
    #endif
    
    devStates_t zclSampleTemperatureSensor_NwkState = DEV_INIT;
    
    uint8 giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;   // display main screen mode first
    
    static uint8 aProcessCmd[] = { 1, 0, 0, 0 }; // used for reset command, { length + cmd0 + cmd1 + data }
    
    // Test Endpoint to allow SYS_APP_MSGs
    static endPointDesc_t sampleTemperatureSensor_TestEp =
    {
      20,                                 // Test endpoint
      &zclSampleTemperatureSensor_TaskID,
      (SimpleDescriptionFormat_t *)NULL,  // No Simple description for this test endpoint
      (afNetworkLatencyReq_t)0            // No Network Latency req
    };
    
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void zclSampleTemperatureSensor_HandleKeys( byte shift, byte keys );
    static void zclSampleTemperatureSensor_BasicResetCB( void );
    static void zclSampleTemperatureSensor_IdentifyCB( zclIdentify_t *pCmd );
    static void zclSampleTemperatureSensor_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
    static void zclSampleTemperatureSensor_ProcessIdentifyTimeChange( void );
    
    // app display functions
    void zclSampleTemperatureSensor_LcdDisplayUpdate(void);
    void zclSampleTemperatureSensor_LcdDisplayMainMode(void);
    void zclSampleTemperatureSensor_LcdDisplayTempMode(void);
    void zclSampleTemperatureSensor_LcdDisplayHelpMode(void);
    
    static void zclSampleTemperatureSensor_SendTemp(void);
    
    // Functions to process ZCL Foundation incoming Command/Response messages
    static void zclSampleTemperatureSensor_ProcessIncomingMsg( zclIncomingMsg_t *msg );
    #ifdef ZCL_READ
    static uint8 zclSampleTemperatureSensor_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_WRITE
    static uint8 zclSampleTemperatureSensor_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    static uint8 zclSampleTemperatureSensor_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
    #ifdef ZCL_DISCOVER
    static uint8 zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg );
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg );
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg );
    #endif // ZCL_DISCOVER
    
    /*********************************************************************
     * STATUS STRINGS
     */
    #ifdef LCD_SUPPORTED
    const char sClearLine[]    = " ";
    const char sDeviceName[]   = "  Temp Sensor";
    const char sSwTempUp[]     = "SW1: Raise Temp";
    const char sSwEZMode[]     = "SW2: EZ-Mode";
    const char sSwTempDown[]   = "SW3: Lower Temp";
    const char sSwHelp[]       = "SW5: Help";
    #endif
    
    /*********************************************************************
     * ZCL General Profile Callback table
     */
    static zclGeneral_AppCallbacks_t zclSampleTemperatureSensor_CmdCallbacks =
    {
      zclSampleTemperatureSensor_BasicResetCB,        // Basic Cluster Reset command
      zclSampleTemperatureSensor_IdentifyCB,          // Identify command
    #ifdef ZCL_EZMODE
      NULL,                                           // Identify EZ-Mode Invoke command
      NULL,                                           // Identify Update Commission State command
    #endif
      NULL,                                           // Identify Trigger Effect command
      zclSampleTemperatureSensor_IdentifyQueryRspCB,  // Identify Query Response command
      NULL,             				                      // On/Off cluster command
      NULL,                                           // On/Off cluster enhanced command Off with Effect
      NULL,                                           // On/Off cluster enhanced command On with Recall Global Scene
      NULL,                                           // On/Off cluster enhanced command On with Timed Off
    #ifdef ZCL_LEVEL_CTRL
      NULL,                                           // Level Control Move to Level command
      NULL,                                           // Level Control Move command
      NULL,                                           // Level Control Step command
      NULL,                                           // Level Control Stop command
    #endif
    #ifdef ZCL_GROUPS
      NULL,                                           // Group Response commands
    #endif
    #ifdef ZCL_SCENES
      NULL,                                           // Scene Store Request command
      NULL,                                           // Scene Recall Request command
      NULL,                                           // Scene Response command
    #endif
    #ifdef ZCL_ALARMS
      NULL,                                           // Alarm (Response) commands
    #endif
    #ifdef SE_UK_EXT
      NULL,                                           // Get Event Log command
      NULL,                                           // Publish Event Log command
    #endif
      NULL,                                           // RSSI Location command
      NULL                                            // RSSI Location Response command
    };
    
    /*********************************************************************
     * @fn          zclSampleTemperatureSensor_Init
     *
     * @brief       Initialization function for the zclGeneral layer.
     *
     * @param       none
     *
     * @return      none
     */
    void zclSampleTemperatureSensor_Init( byte task_id )
    {
      zclSampleTemperatureSensor_TaskID = task_id;
      zclSampleTemperatureSensor_TransID = 0;
    
      // Set destination address to indirect
      zclSampleTemperatureSensor_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
      zclSampleTemperatureSensor_DstAddr.endPoint = 0;
      zclSampleTemperatureSensor_DstAddr.addr.shortAddr = 0;
    
      // This app is part of the Home Automation Profile
      zclHA_Init( &zclSampleTemperatureSensor_SimpleDesc );
    
      // Register the ZCL General Cluster Library callback functions
      zclGeneral_RegisterCmdCallbacks( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_CmdCallbacks );
    
      // Register the application's attribute list
      zcl_registerAttrList( SAMPLETEMPERATURESENSOR_ENDPOINT, SAMPLETEMPERATURESENSOR_MAX_ATTRIBUTES, zclSampleTemperatureSensor_Attrs );
    
      // Register the Application to receive the unprocessed Foundation command/response messages
      zcl_registerForMsg( zclSampleTemperatureSensor_TaskID );
    
    #ifdef ZCL_EZMODE
      // Register EZ-Mode
      zcl_RegisterEZMode( &zclSampleTemperatureSensor_RegisterEZModeData );
    
      // Register with the ZDO to receive Match Descriptor Responses
      ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
    #endif
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( zclSampleTemperatureSensor_TaskID );
    
      // Register for a test endpoint
      afRegister( &sampleTemperatureSensor_TestEp );
    
    #ifdef LCD_SUPPORTED
      // display the device name
      HalLcdWriteString( (char *)sDeviceName, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn          zclSample_event_loop
     *
     * @brief       Event Loop Processor for zclGeneral.
     *
     * @param       none
     *
     * @return      none
     */
    uint16 zclSampleTemperatureSensor_event_loop( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
      afDataConfirm_t *afDataConfirm;
      char pstr[] = "sending fail" ;
      
      // Data Confirmation message fields
      byte sentEP;
      ZStatus_t sentStatus;
      byte sentTransID;       // This should match the value sent
    
      (void)task_id;  // Intentionally unreferenced parameter
    
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleTemperatureSensor_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
    #ifdef ZCL_EZMODE
            case ZDO_CB_MSG:
              zclSampleTemperatureSensor_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
              break;
    #endif
    
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclSampleTemperatureSensor_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
    
            case KEY_CHANGE:
              zclSampleTemperatureSensor_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
              case AF_DATA_CONFIRM_CMD:
              // This message is received as a confirmation of a data packet sent.
              // The status is of ZStatus_t type [defined in ZComDef.h]
              // The message fields are defined in AF.h
              afDataConfirm = (afDataConfirm_t *)MSGpkt;
    
              sentEP = afDataConfirm->endpoint;
              (void)sentEP;  // This info not used now
              sentTransID = afDataConfirm->transID;
              (void)sentTransID;  // This info not used now
    
              sentStatus = afDataConfirm->hdr.status;
              // Action taken when confirmation is received.
              if ( sentStatus != ZSuccess )
              {
                 HalLcdWriteString ( pstr, HAL_LCD_LINE_2 );
                // The data wasn't delivered -- Do something
              }
              break;
              
              
            case ZDO_STATE_CHANGE:
              zclSampleTemperatureSensor_NwkState = (devStates_t)(MSGpkt->hdr.status);
    
    
              // now on the network
              if ( (zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD) ||
                   (zclSampleTemperatureSensor_NwkState == DEV_ROUTER)   ||
                   (zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE) )
              {
    #ifndef HOLD_AUTO_START
                giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
                zclSampleTemperatureSensor_LcdDisplayUpdate();
    #endif
    #ifdef ZCL_EZMODE
                zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
    #endif // ZCL_EZMODE
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT )
      {
        if ( zclSampleTemperatureSensor_IdentifyTime > 0 )
          zclSampleTemperatureSensor_IdentifyTime--;
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    
        return ( events ^ SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT );
      }
    
    #ifdef ZCL_EZMODE
      // going on to next state
      if ( events & SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL );   // going on to next state
        return ( events ^ SAMPLETEMPERATURESENSOR_EZMODE_NEXTSTATE_EVT );
      }
    
      // the overall EZMode timer expired, so we timed out
      if ( events & SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
        return ( events ^ SAMPLETEMPERATURESENSOR_EZMODE_TIMEOUT_EVT );
      }
    #endif // ZLC_EZMODE
    
      if ( events & SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
        zclSampleTemperatureSensor_LcdDisplayUpdate();
    
        return ( events ^ SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT );
      }
    
      if ( events & SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT )
      {
        zclSampleTemperatureSensor_SendTemp();
    
        // report current temperature reading every 10 seconds
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT, SAMPLETEMPERATURESENSOR_REPORT_INTERVAL );
    
        return ( events ^ SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT );
      }
    
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_5
     *                 HAL_KEY_SW_4
     *                 HAL_KEY_SW_3
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_HandleKeys( byte shift, byte keys )
    {
      if ( keys & HAL_KEY_SW_1 )
      {
        // increase temperature
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        if ( zclSampleTemperatureSensor_MeasuredValue < zclSampleTemperatureSensor_MaxMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MeasuredValue + 100;  // considering using whole number value
        }
        else if ( zclSampleTemperatureSensor_MeasuredValue >= zclSampleTemperatureSensor_MaxMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MaxMeasuredValue;
        }
    
        // Send temperature information
        zclSampleTemperatureSensor_SendTemp();
      }
    
      if ( keys & HAL_KEY_SW_2 )
      {
        if ( ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE ) ||
            ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE ) )
        {
          giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
    #ifdef ZCL_EZMODE
          zclEZMode_InvokeData_t ezModeData;
          static uint16 clusterIDs[] = { ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT };   // only bind on the Temperature Measurement cluster
    
          // Invoke EZ-Mode
          ezModeData.endpoint = SAMPLETEMPERATURESENSOR_ENDPOINT; // endpoint on which to invoke EZ-Mode
          if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
               ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER )   ||
               ( zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE ) )
          {
            ezModeData.onNetwork = TRUE;      // node is already on the network
          }
          else
          {
            ezModeData.onNetwork = FALSE;     // node is not yet on the network
          }
          ezModeData.initiator = TRUE;        // Temperature Sensor is an initiator
          ezModeData.numActiveInClusters = 1;
          ezModeData.pActiveInClusterIDs = clusterIDs;
          ezModeData.numActiveOutClusters = 0;   // active output cluster
          ezModeData.pActiveOutClusterIDs = NULL;
          zcl_InvokeEZMode( &ezModeData );
    
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
    #endif
    
          // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
          {
            zAddrType_t dstAddr;
            dstAddr.addrMode = Addr16Bit;
            dstAddr.addr.shortAddr = 0;   // Coordinator makes the EDB match
    
            // Initiate an End Device Bind Request, this bind request will
            // only use a cluster list that is important to binding.
            HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
            ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                                  SAMPLETEMPERATURESENSOR_ENDPOINT,
                                  ZCL_HA_PROFILE_ID,
                                  0, NULL,
                                  ZCLSAMPLETEMPERATURESENSOR_BINDINGLIST, bindingOutClusters,
                                  FALSE );
          }
    #endif // ZCL_EZMODE
        }
      }
    
      if ( keys & HAL_KEY_SW_3 )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        // decrease the temperature
        if ( zclSampleTemperatureSensor_MeasuredValue > zclSampleTemperatureSensor_MinMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MeasuredValue - 100;  // considering using whole number value
        }
        else if ( zclSampleTemperatureSensor_MeasuredValue >= zclSampleTemperatureSensor_MinMeasuredValue )
        {
          zclSampleTemperatureSensor_MeasuredValue = zclSampleTemperatureSensor_MinMeasuredValue;
        }
    
        // Send temperature information
        zclSampleTemperatureSensor_SendTemp();
      }
    
      if ( keys & HAL_KEY_SW_4 )
      {
        giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
    
        if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
             ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER ) )
        {
          // toggle permit join
          gPermitDuration = gPermitDuration ? 0 : 0xff;
          NLME_PermitJoiningRequest( gPermitDuration );
        }
      }
    
      if ( shift && ( keys & HAL_KEY_SW_5 ) )
      {
        zclSampleTemperatureSensor_BasicResetCB();
      }
      else if ( keys & HAL_KEY_SW_5 )
      {
        if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
        {
          giTemperatureSensorScreenMode = TEMPSENSE_HELPMODE;
        }
        else if ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE )
        {
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( (char *)sClearLine, HAL_LCD_LINE_2 );
    #endif
          giTemperatureSensorScreenMode = TEMPSENSE_MAINMODE;
        }
      }
    
      // update display
      zclSampleTemperatureSensor_LcdDisplayUpdate();
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayUpdate
     *
     * @brief   Called to update the LCD display.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayUpdate( void )
    {
      // turn on red LED for temperatures >= 24.00C
      if ( zclSampleTemperatureSensor_MeasuredValue >= 2400 )
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
      }
      // turn on green LED for temperatures <= 20.00C
      else if ( zclSampleTemperatureSensor_MeasuredValue <= 2000 )
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
      }
      // turn on both red and green LEDs for temperatures between 20.00C and 24.00C
      else
      {
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
        HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
      }
    
      if ( giTemperatureSensorScreenMode == TEMPSENSE_HELPMODE )
      {
        zclSampleTemperatureSensor_LcdDisplayHelpMode();
      }
      else
      {
        zclSampleTemperatureSensor_LcdDisplayMainMode();
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayMainMode
     *
     * @brief   Called to display the main screen on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayMainMode( void )
    {
      char sDisplayTemp[16];
    
      if ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD )
      {
        zclHA_LcdStatusLine1( 0 );
      }
      else if ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER )
      {
        zclHA_LcdStatusLine1( 1 );
      }
      else if ( zclSampleTemperatureSensor_NwkState == DEV_END_DEVICE )
      {
        zclHA_LcdStatusLine1( 2 );
      }
    
      // display current temperature
      osal_memcpy(sDisplayTemp, "TEMP: ", 6);
      _ltoa( ( zclSampleTemperatureSensor_MeasuredValue / 100 ), (void *)(&sDisplayTemp[6]), 10 );   // convert temperature to whole number
      osal_memcpy( &sDisplayTemp[8], "C", 2 );
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_2 );
    #endif
    
    #ifdef LCD_SUPPORTED
      if ( ( zclSampleTemperatureSensor_NwkState == DEV_ZB_COORD ) ||
           ( zclSampleTemperatureSensor_NwkState == DEV_ROUTER ) )
      {
        // display help key with permit join status
        if ( gPermitDuration )
        {
          HalLcdWriteString( "SW5: Help      *", HAL_LCD_LINE_3 );
        }
        else
        {
          HalLcdWriteString( "SW5: Help       ", HAL_LCD_LINE_3 );
        }
      }
      else
      {
        // display help key
        HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
      }
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_LcdDisplayHelpMode
     *
     * @brief   Called to display the SW options on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleTemperatureSensor_LcdDisplayHelpMode( void )
    {
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sSwTempUp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sSwTempDown, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_SendTemp
     *
     * @brief   Called to send current temperature information to the thermostat
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_SendTemp( void )
    {
    #ifdef ZCL_REPORT
      zclReportCmd_t *pReportCmd;
      char *theMessageData = "Hello i am temp Sensor";
    
      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = ATTRID_MS_TEMPERATURE_MEASURED_VALUE;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_INT16;
        pReportCmd->attrList[0].attrData = (void *)(&zclSampleTemperatureSensor_MeasuredValue);
    
     /*  zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
                           ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                           pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );  */
      }
      
      if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
                        ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                        (byte)osal_strlen( theMessageData ) + 1,
                        (byte *)&theMessageData,
                        &zclSampleTemperatureSensor_TransID,
                        AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
        theMessageData = "success" ;
        HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
      // Successfully requested to be sent.
      }
      else
      {
         theMessageData = "not success" ; 
          HalLcdWriteString ( theMessageData, HAL_LCD_LINE_4 );
      // Error occurred in request to send.
      }
    
      osal_mem_free( pReportCmd );
    #endif  // ZCL_REPORT
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessIdentifyTimeChange
     *
     * @brief   Called to process any change to the IdentifyTime attribute.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_ProcessIdentifyTimeChange( void )
    {
      if ( zclSampleTemperatureSensor_IdentifyTime > 0 )
      {
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT, 1000 );
        HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
      }
      else
      {
        if ( zclSampleTemperatureSensor_OnOff )
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
        }
        else
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
        }
    
        osal_stop_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_IDENTIFY_TIMEOUT_EVT );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_BasicResetCB
     *
     * @brief   Callback from the ZCL General Cluster Library
     *          to set all the Basic Cluster attributes to default values.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_BasicResetCB( void )
    {
      // Put device back to factory default settings
      zgWriteStartupOptions( ZG_STARTUP_SET, 3 );   // bit set both default configuration and default network
    
      // restart device
      MT_SysCommandProcessing( aProcessCmd );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_IdentifyCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Command for this application.
     *
     * @param   srcAddr - source address and endpoint of the response message
     * @param   identifyTime - the number of seconds to identify yourself
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_IdentifyCB( zclIdentify_t *pCmd )
    {
      zclSampleTemperatureSensor_IdentifyTime = pCmd->identifyTime;
      zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_IdentifyQueryRspCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Query Response Command for this application.
     *
     * @param   srcAddr - requestor's address
     * @param   timeout - number of seconds to identify yourself (valid for query response)
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
    {
      (void)pRsp;
    #ifdef ZCL_EZMODE
      {
        zclEZMode_ActionData_t data;
        data.pIdentifyQueryRsp = pRsp;
        zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
      }
    #endif
    }
    
    /******************************************************************************
     *
     *  Functions for processing ZCL Foundation incoming Command/Response messages
     *
     *****************************************************************************/
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessIncomingMsg
     *
     * @brief   Process ZCL Foundation incoming message
     *
     * @param   pInMsg - pointer to the received message
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg)
    {
      switch ( pInMsg->zclHdr.commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ_RSP:
          zclSampleTemperatureSensor_ProcessInReadRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE_RSP:
          zclSampleTemperatureSensor_ProcessInWriteRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_REPORT
        // See ZCL Test Applicaiton (zcl_testapp.c) for sample code on Attribute Reporting
        case ZCL_CMD_CONFIG_REPORT:
          //zclSampleTemperatureSensor_ProcessInConfigReportCmd( pInMsg );
          break;
    
        case ZCL_CMD_CONFIG_REPORT_RSP:
          //zclSampleTemperatureSensor_ProcessInConfigReportRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          //zclSampleTemperatureSensor_ProcessInReadReportCfgCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG_RSP:
          //zclSampleTemperatureSensor_ProcessInReadReportCfgRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_REPORT:
          //zclSampleTemperatureSensor_ProcessInReportCmd( pInMsg );
          break;
    #endif
        case ZCL_CMD_DEFAULT_RSP:
          zclSampleTemperatureSensor_ProcessInDefaultRspCmd( pInMsg );
          break;
    #ifdef ZCL_DISCOVER
        case ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP:
          zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_CMDS_GEN_RSP:
          zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_ATTRS_RSP:
          zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_DISCOVER_ATTRS_EXT_RSP:
          zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( pInMsg );
          break;
    #endif
        default:
          break;
      }
    
      if ( pInMsg->attrCmd )
      {
        osal_mem_free( pInMsg->attrCmd );
      }
    }
    
    #ifdef ZCL_READ
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInReadRspCmd
     *
     * @brief   Process the "Profile" Read Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReadRspCmd_t *readRspCmd;
      uint8 i;
    
      readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < readRspCmd->numAttr; i++ )
      {
        // Notify the originator of the results of the original read attributes
        // attempt and, for each successfull request, the value of the requested
        // attribute
      }
    
      return ( TRUE );
    }
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInWriteRspCmd
     *
     * @brief   Process the "Profile" Write Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclWriteRspCmd_t *writeRspCmd;
      uint8 i;
    
      writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < writeRspCmd->numAttr; i++ )
      {
        // Notify the device of the results of the its original write attributes
        // command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_WRITE
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDefaultRspCmd
     *
     * @brief   Process the "Profile" Default Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
    {
      // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
    
      // Device is notified of the Default Response command.
      (void)pInMsg;
    
      return ( TRUE );
    }
    
    #ifdef ZCL_DISCOVER
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd
     *
     * @brief   Process the Discover Commands Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numCmd; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd
     *
     * @brief   Process the "Profile" Discover Attributes Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverAttrsRspCmd_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverAttrsRspCmd_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numAttr; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd
     *
     * @brief   Process the "Profile" Discover Attributes Extended Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleTemperatureSensor_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclDiscoverAttrsExtRsp_t *discoverRspCmd;
      uint8 i;
    
      discoverRspCmd = (zclDiscoverAttrsExtRsp_t *)pInMsg->attrCmd;
      for ( i = 0; i < discoverRspCmd->numAttr; i++ )
      {
        // Device is notified of the result of its attribute discovery command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_DISCOVER
    
    #ifdef ZCL_EZMODE
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_ProcessZDOMsgs
     *
     * @brief   Called when this node receives a ZDO/ZDP response.
     *
     * @param   none
     *
     * @return  status
     */
    static void zclSampleTemperatureSensor_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
    {
      zclEZMode_ActionData_t data;
      ZDO_MatchDescRsp_t *pMatchDescRsp;
    
      // Let EZ-Mode know of the Match Descriptor Response
      if ( pMsg->clusterID == Match_Desc_rsp )
      {
        pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
        data.pMatchDescRsp = pMatchDescRsp;
        zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
        osal_mem_free( pMatchDescRsp );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleTemperatureSensor_EZModeCB
     *
     * @brief   The Application is informed of events. This can be used to show on the UI what is
    *           going on during EZ-Mode steering/finding/binding.
     *
     * @param   state - an
     *
     * @return  none
     */
    static void zclSampleTemperatureSensor_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
    {
    #ifdef LCD_SUPPORTED
      char szLine[20];
      char *pStr;
      uint8 err;
    #endif
    
      // time to go into identify mode
      if ( state == EZMODE_STATE_IDENTIFYING )
      {
        zclSampleTemperatureSensor_IdentifyTime = ( EZMODE_TIME / 1000 );  // convert to seconds
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
      }
    
      // autoclosing, show what happened (success, cancelled, etc...)
      if( state == EZMODE_STATE_AUTOCLOSE )
      {
    #ifdef LCD_SUPPORTED
        pStr = NULL;
        err = pData->sAutoClose.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          pStr = "EZMode: Success";
        }
        else if ( err == EZMODE_ERR_NOMATCH )
        {
          pStr = "EZMode: NoMatch"; // not a match made in heaven
        }
        if ( pStr )
        {
          if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif
      }
    
      // finished, either show DstAddr/EP, or nothing (depending on success or not)
      if( state == EZMODE_STATE_FINISH )
      {
        // turn off identify mode
        zclSampleTemperatureSensor_IdentifyTime = 0;
        zclSampleTemperatureSensor_ProcessIdentifyTimeChange();
    
    #ifdef LCD_SUPPORTED
        // if successful, inform user which nwkaddr/ep we bound to
        pStr = NULL;
        err = pData->sFinish.err;
        if( err == EZMODE_ERR_SUCCESS )
        {
          // "EZDst:1234 EP:34"
          osal_memcpy( szLine, "EZDst:", 6 );
          zclHA_uint16toa( pData->sFinish.nwkaddr, &szLine[6] );
          osal_memcpy( &szLine[10], " EP:", 4 );
          _ltoa( pData->sFinish.ep, (void *)(&szLine[14]), 16 );  // _ltoa NULL terminates
          pStr = szLine;
        }
        else if ( err == EZMODE_ERR_BAD_PARAMETER )
        {
          pStr = "EZMode: BadParm";
        }
        else if ( err == EZMODE_ERR_CANCELLED )
        {
          pStr = "EZMode: Cancel";
        }
        else
        {
          pStr = "EZMode: TimeOut";
        }
        if ( pStr )
        {
          if ( giTemperatureSensorScreenMode == TEMPSENSE_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif  // LCD_SUPPORTED
    
        // show main UI screen 3 seconds after joining network
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_MAIN_SCREEN_EVT, 3000 );
    
        // report current temperature reading 15 seconds after joinging the network
        osal_start_timerEx( zclSampleTemperatureSensor_TaskID, SAMPLETEMPERATURESENSOR_TEMP_SEND_EVT, SAMPLETEMPERATURESENSOR_REPORT_INTERVAL );
      }
    }
    #endif // ZCL_EZMODE
    
    /****************************************************************************
    ****************************************************************************/
    
    
    

    /**************************************************************************************************
      Filename:       zcl_samplethermostat.c
      Revised:        $Date: 2013-10-18 17:02:21 -0700 (Fri, 18 Oct 2013) $
      Revision:       $Revision: 35724 $
    
      Description:    Zigbee Cluster Library - sample device application.
    
    
      Copyright 2013 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
      This device will act as a thermostat.
    
      SCREEN MODES
      ----------------------------------------
      Main:
        - SW1: Set heating setpoint
        - SW2: Invoke EZMode
        - SW3: Set cooling setpoint
        - SW4: Enable/Disable Permit Join
        - SW5: Go to Help screen
    
      Heating Setpoint or Cooling Setpoint:
        - SW1: Increase temperature
        - SW3: Decrease temperature
        - SW5: Save temperature
      ----------------------------------------
    *********************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include "ZComDef.h"
    #include "OSAL.h"
    #include "AF.h"
    #include "ZDApp.h"
    #include "ZDObject.h"
    #include "MT_APP.h"
    #include "MT_SYS.h"
    
    #include "zcl.h"
    #include "zcl_general.h"
    #include "zcl_ha.h"
    #include "zcl_ezmode.h"
    #include "zcl_hvac.h"
    #include "zcl_ms.h"
    
    #include "zcl_samplethermostat.h"
    
    #include "onboard.h"
    
    /* HAL */
    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    byte zclSampleThermostat_TaskID;
    uint8 zclSampleThermostatSeqNum;
    
    static byte gPermitDuration = 0x00;
    
    // Number of recieved messages
    static uint16 rxMsgCount   //as given in generic app
    
    /*********************************************************************
     * GLOBAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    afAddrType_t zclSampleThermostat_DstAddr;
    
    #ifdef ZCL_EZMODE
    static void zclSampleThermostat_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
    static void zclSampleThermostat_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
    
    static const zclEZMode_RegisterData_t zclSampleThermostat_RegisterEZModeData =
    {
      &zclSampleThermostat_TaskID,
      SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT,
      SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT,
      &zclSampleThermostatSeqNum,
      zclSampleThermostat_EZModeCB
    };
    
    // NOT ZCL_EZMODE, Use EndDeviceBind
    #else
    
    static cId_t bindingOutClusters[] =
    {
      ZCL_CLUSTER_ID_HVAC_THERMOSTAT
    };
    #define ZCLSAMPLETHERMOSTAT_BINDINGLIST_OUT     1
    
    static cId_t bindingInClusters[] =
    {
      ZCL_CLUSTER_ID_HVAC_THERMOSTAT,
      ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT
    };
    #define ZCLSAMPLETHERMOSTAT_BINDINGLIST_IN      2
    #endif
    
    uint8 giThermostatScreenMode = THERMOSTAT_MAINMODE;   // display the main screen mode first
    
    devStates_t zclSampleThermostat_NwkState = DEV_INIT;
    
    static uint8 aProcessCmd[] = { 1, 0, 0, 0 }; // used for reset command, { length + cmd0 + cmd1 + data }
    
    // Test Endpoint to allow SYS_APP_MSGs
    static endPointDesc_t sampleThermostat_TestEp =
    {
      20,                                 // Test endpoint
      &zclSampleThermostat_TaskID,
      (SimpleDescriptionFormat_t *)NULL,  // No Simple description for this test endpoint
      (afNetworkLatencyReq_t)0            // No Network Latency req
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void zclSampleThermostat_HandleKeys( byte shift, byte keys );
    static void zclSampleThermostat_BasicResetCB( void );
    static void zclSampleThermostat_IdentifyCB( zclIdentify_t *pCmd );
    static void zclSampleThermostat_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
    static void zclSampleThermostat_ProcessIdentifyTimeChange( void );
    static void zclSampleThermostat_ProcessAppMsg( uint8 srcEP, uint8 len, uint8 *msg );
    static void zclSampleThermostat_ProcessFoundationMsg( afAddrType_t *dstAddr, uint16 clusterID,
                                                          zclFrameHdr_t *hdr, zclParseCmd_t *pParseCmd );
    
    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pckt ); // callback fn for AF msg sent from temp sensor
    
    // app display functions
    void zclSampleThermostat_LcdDisplayUpdate(void);
    void zclSampleThermostat_LcdDisplayMainMode(void);
    void zclSampleThermostat_LcdDisplayHeatMode(void);
    void zclSampleThermostat_LcdDisplayCoolMode(void);
    void zclSampleThermostat_LcdDisplayHelpMode(void);
    
    // Functions to process ZCL Foundation incoming Command/Response messages
    static void zclSampleThermostat_ProcessIncomingMsg( zclIncomingMsg_t *msg );
    #ifdef ZCL_READ
    static uint8 zclSampleThermostat_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_WRITE
    static uint8 zclSampleThermostat_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
    #endif
    #ifdef ZCL_REPORT
    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg );
    #endif  // ZCL_REPORT
    static uint8 zclSampleThermostat_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
    
    /*********************************************************************
     * STATUS STRINGS
     */
    #ifdef LCD_SUPPORTED
    const char sClearLine[]     = " ";
    const char sDeviceName[]    = "   Thermostat";
    const char sSwHeatSet[]     = "SW1: Set Heating";
    const char sSwEZMode[]      = "SW2: EZ-Mode";
    const char sSwCoolSet[]     = "SW3: Set Cooling";
    const char sTempLine2[]     = "SW1:+";
    const char sTempLine3[]     = "SW3:-  SW5:Enter";
    const char sSwHelp[]        = "SW5: Help";
    const char sStoreHeatTemp[] = "HEAT TEMP SAVED";
    const char sStoreCoolTemp[] = "COOL TEMP SAVED";
    #endif
    
    /*********************************************************************
     * ZCL General Profile Callback table
     */
    static zclGeneral_AppCallbacks_t zclSampleThermostat_CmdCallbacks =
    {
      zclSampleThermostat_BasicResetCB,            // Basic Cluster Reset command
      zclSampleThermostat_IdentifyCB,              // Identify command
    #ifdef ZCL_EZMODE
      NULL,                                        // Identify EZ-Mode Invoke command
      NULL,                                        // Identify Update Commission State command
    #endif
      NULL,                                        // Identify Trigger Effect command
      zclSampleThermostat_IdentifyQueryRspCB,      // Identify Query Response command
      NULL,             				                   // On/Off cluster command
      NULL,                                        // On/Off cluster enhanced command Off with Effect
      NULL,                                        // On/Off cluster enhanced command On with Recall Global Scene
      NULL,                                        // On/Off cluster enhanced command On with Timed Off
    #ifdef ZCL_LEVEL_CTRL
      NULL,                                        // Level Control Move to Level command
      NULL,                                        // Level Control Move command
      NULL,                                        // Level Control Step command
      NULL,                                        // Level Control Stop command
    #endif
    #ifdef ZCL_GROUPS
      NULL,                                        // Group Response commands
    #endif
    #ifdef ZCL_SCENES
      NULL,                                        // Scene Store Request command
      NULL,                                        // Scene Recall Request command
      NULL,                                        // Scene Response command
    #endif
    #ifdef ZCL_ALARMS
      NULL,                                        // Alarm (Response) commands
    #endif
    #ifdef SE_UK_EXT
      NULL,                                        // Get Event Log command
      NULL,                                        // Publish Event Log command
    #endif
      NULL,                                        // RSSI Location command
      NULL                                         // RSSI Location Response command
    };
    
    /*********************************************************************
     * @fn          zclSampleThermostat_Init
     *
     * @brief       Initialization function for the zclGeneral layer.
     *
     * @param       none
     *
     * @return      none
     */
    void zclSampleThermostat_Init( byte task_id )
    {
      zclSampleThermostat_TaskID = task_id;
    
      // Set destination address to indirect
      zclSampleThermostat_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
      zclSampleThermostat_DstAddr.endPoint = 0;
      zclSampleThermostat_DstAddr.addr.shortAddr = 0;
    
      // This app is part of the Home Automation Profile
      zclHA_Init( &zclSampleThermostat_SimpleDesc );
    
      // Register the ZCL General Cluster Library callback functions
      zclGeneral_RegisterCmdCallbacks( SAMPLETHERMOSTAT_ENDPOINT, &zclSampleThermostat_CmdCallbacks );
    
      // Register the application's attribute list
      zcl_registerAttrList( SAMPLETHERMOSTAT_ENDPOINT, SAMPLETHERMOSTAT_MAX_ATTRIBUTES, zclSampleThermostat_Attrs );
    
      // Register the Application to receive the unprocessed Foundation command/response messages
      zcl_registerForMsg( zclSampleThermostat_TaskID );
    
    #ifdef ZCL_EZMODE
      // Register EZ-Mode
      zcl_RegisterEZMode( &zclSampleThermostat_RegisterEZModeData );
    
      // Register with the ZDO to receive Match Descriptor Responses
      ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
    #endif
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( zclSampleThermostat_TaskID );
    
      // Register for a test endpoint
      afRegister( &sampleThermostat_TestEp );
    
      ZDO_RegisterForZDOMsg( zclSampleThermostat_TaskID, End_Device_Bind_rsp );
      ZDO_RegisterForZDOMsg( zclSampleThermostat_TaskID, Match_Desc_rsp );
    
    #ifdef LCD_SUPPORTED
      // display the device name
      HalLcdWriteString( (char *)sDeviceName, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn          zclSample_event_loop
     *
     * @brief       Event Loop Processor for zclGeneral.
     *
     * @param       none
     *
     * @return      none
     */
    uint16 zclSampleThermostat_event_loop( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
      char *msg = NULL;
      (void)task_id;  // Intentionally unreferenced parameter
    
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleThermostat_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
    #ifdef ZCL_EZMODE
            case ZDO_CB_MSG:
              zclSampleThermostat_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
              break;
    #endif
    
            case MT_SYS_APP_MSG:
              // Message received from MT
              zclSampleThermostat_ProcessAppMsg( ((mtSysAppMsg_t *)MSGpkt)->endpoint,
                                              ((mtSysAppMsg_t *)MSGpkt)->appDataLen,
                                              ((mtSysAppMsg_t *)MSGpkt)->appData );
              break;
    
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclSampleThermostat_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
              
             case AF_INCOMING_MSG_CMD:    // callback fn for AF msg sent from temp sensor
               msg = "AF_INCONING_CBS";
               //UARTprintf("AF_INCOMING_MSG_CMD event \n" );
               HalLcdWriteString( msg, HAL_LCD_LINE_4 );
              zclSampleThermostat_MessageMSGCB( MSGpkt );
              break;
    
            case KEY_CHANGE:
              zclSampleThermostat_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
            case ZDO_STATE_CHANGE:
              zclSampleThermostat_NwkState = (devStates_t)(MSGpkt->hdr.status);
    
    
              // now on the network
              if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
                   ( zclSampleThermostat_NwkState == DEV_ROUTER )   ||
                   ( zclSampleThermostat_NwkState == DEV_END_DEVICE ) )
              {
    #ifndef HOLD_AUTO_START
                // display main mode
                giThermostatScreenMode = THERMOSTAT_MAINMODE;
                zclSampleThermostat_LcdDisplayUpdate();
    #endif
    #ifdef ZCL_EZMODE
                zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
    #endif  // ZCL_EZMODE
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT )
      {
        if ( zclSampleThermostat_IdentifyTime > 0 )
        {
          zclSampleThermostat_IdentifyTime--;
        }
        zclSampleThermostat_ProcessIdentifyTimeChange();
    
        return ( events ^ SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT );
      }
    
      if ( events & SAMPLETHERMOSTAT_MAIN_SCREEN_EVT )
      {
        giThermostatScreenMode = THERMOSTAT_MAINMODE;
        zclSampleThermostat_LcdDisplayUpdate();
    
        return ( events ^ SAMPLETHERMOSTAT_MAIN_SCREEN_EVT );
      }
    
    #ifdef ZCL_EZMODE
      // going on to next state
      if ( events & SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL );   // going on to next state
        return ( events ^ SAMPLETHERMOSTAT_EZMODE_NEXTSTATE_EVT );
      }
    
      // the overall EZMode timer expired, so we timed out
      if ( events & SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT )
      {
        zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
        return ( events ^ SAMPLETHERMOSTAT_EZMODE_TIMEOUT_EVT );
      }
    #endif // ZLC_EZMODE
    
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_5
     *                 HAL_KEY_SW_4
     *                 HAL_KEY_SW_3
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void zclSampleThermostat_HandleKeys( byte shift, byte keys )
    {
      if ( keys & HAL_KEY_SW_1 )
      {
        // in heating mode
        if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
        {
          // increase heating setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedHeatingSetpoint < zclSampleThermostat_MaxHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_OccupiedHeatingSetpoint + 100;
          }
          else if ( zclSampleThermostat_OccupiedHeatingSetpoint >= zclSampleThermostat_MaxHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_MaxHeatSetpointLimit;
          }
        }
        // in cooling mode
        else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
        {
          // increase cooling setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedCoolingSetpoint < zclSampleThermostat_MaxCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_OccupiedCoolingSetpoint + 100;
          }
          else if ( zclSampleThermostat_OccupiedCoolingSetpoint >= zclSampleThermostat_MaxCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_MaxCoolSetpointLimit;
          }
        }
        // set screen mode to heat mode
        else
        {
          giThermostatScreenMode = THERMOSTAT_HEATMODE;
        }
      }
    
      if ( keys & HAL_KEY_SW_2 )
      {
        if ( ( giThermostatScreenMode == THERMOSTAT_MAINMODE ) ||
             ( giThermostatScreenMode == THERMOSTAT_HELPMODE ) )
        {
          giThermostatScreenMode = THERMOSTAT_MAINMODE;
    
    #ifdef ZCL_EZMODE
          zclEZMode_InvokeData_t ezModeData;
          static uint16 clusterIDs[] = { ZCL_CLUSTER_ID_HVAC_THERMOSTAT };   // only bind on the Thermostat cluster
    
          // Invoke EZ-Mode
          ezModeData.endpoint = SAMPLETHERMOSTAT_ENDPOINT; // endpoint on which to invoke EZ-Mode
          if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
               ( zclSampleThermostat_NwkState == DEV_ROUTER )   ||
               ( zclSampleThermostat_NwkState == DEV_END_DEVICE ) )
          {
            ezModeData.onNetwork = TRUE;      // node is already on the network
          }
          else
          {
            ezModeData.onNetwork = FALSE;     // node is not yet on the network
          }
          ezModeData.initiator = TRUE;        // Thermostat is an initiator
          ezModeData.numActiveInClusters = 0;
          ezModeData.pActiveInClusterIDs = NULL;
          ezModeData.numActiveOutClusters = 1;   // active output cluster
          ezModeData.pActiveOutClusterIDs = clusterIDs;
          zcl_InvokeEZMode( &ezModeData );
    
    #ifdef LCD_SUPPORTED
          HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
    #endif
    
          // NOT ZCL_EZMODE, use EndDeviceBind
    #else
          zAddrType_t dstAddr;
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
    
          // Initiate an End Device Bind Request, this bind request will
          // only use a cluster list that is important to binding.
          dstAddr.addrMode = afAddr16Bit;
          dstAddr.addr.shortAddr = 0;   // Coordinator makes the match
          ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                                SAMPLETHERMOSTAT_ENDPOINT,
                                ZCL_HA_PROFILE_ID,
                                ZCLSAMPLETHERMOSTAT_BINDINGLIST_IN, bindingInClusters,
                                ZCLSAMPLETHERMOSTAT_BINDINGLIST_OUT, bindingOutClusters,
                                TRUE );
    #endif // ZCL_EZMODE
        }
      }
    
      if ( keys & HAL_KEY_SW_3 )
      {
        if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
        {
          // decrease cooling setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedCoolingSetpoint > zclSampleThermostat_MinCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_OccupiedCoolingSetpoint - 100;
          }
          else if ( zclSampleThermostat_OccupiedCoolingSetpoint <= zclSampleThermostat_MinCoolSetpointLimit )
          {
            zclSampleThermostat_OccupiedCoolingSetpoint = zclSampleThermostat_MinCoolSetpointLimit;
          }
        }
        // in heating mode
        else if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
        {
          // decrease heating setpoint, considering whole numbers where necessary
          if ( zclSampleThermostat_OccupiedHeatingSetpoint > zclSampleThermostat_MinHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_OccupiedHeatingSetpoint - 100;
          }
          else if ( zclSampleThermostat_OccupiedHeatingSetpoint <= zclSampleThermostat_MinHeatSetpointLimit )
          {
            zclSampleThermostat_OccupiedHeatingSetpoint = zclSampleThermostat_MinHeatSetpointLimit;
          }
        }
        // set screen mode to cool mode
        else
        {
          giThermostatScreenMode = THERMOSTAT_COOLMODE;
        }
      }
    
      if ( keys & HAL_KEY_SW_4 )
      {
        giThermostatScreenMode = THERMOSTAT_MAINMODE;
    
        if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
             ( zclSampleThermostat_NwkState == DEV_ROUTER ) )
        {
          // toggle permit join
          gPermitDuration = gPermitDuration ? 0 : 0xff;
          NLME_PermitJoiningRequest( gPermitDuration  );
        }
      }
    
      if ( shift && ( keys & HAL_KEY_SW_5 ) )
      {
        zclSampleThermostat_BasicResetCB();
      }
      else if ( keys & HAL_KEY_SW_5 )
      {
        if ( keys & HAL_KEY_SW_5 )
        {
          // in heating or cooling setpoint mode
          if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
          {
    #ifdef LCD_SUPPORTED
            // save current heat setpoint temperature
            HalLcdWriteString( (char *)sStoreHeatTemp, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
          {
    #ifdef LCD_SUPPORTED
            // save current cool setpoint temperature
            HalLcdWriteString( (char *)sStoreCoolTemp, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
          {
            giThermostatScreenMode = THERMOSTAT_HELPMODE;
          }
          else if ( giThermostatScreenMode == THERMOSTAT_HELPMODE )
          {
    #ifdef LCD_SUPPORTED
            HalLcdWriteString( (char *)sClearLine, HAL_LCD_LINE_2 );
    #endif
            giThermostatScreenMode = THERMOSTAT_MAINMODE;
          }
        }
      }
    
      // update display
      zclSampleThermostat_LcdDisplayUpdate();
    }
    
    
    /*********************************************************************
     * @fn      zclSampleThermostat_MessageMSGCB
     *
     * @brief   Data message processor callback.  This function processes
     *          any incoming data - probably from other devices.  So, based
     *          on cluster ID, perform the intended action.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )
    {  HalLcdWriteString("AF_msg_callback_fn", HAL_LCD_LINE_5 );
      switch ( pkt->clusterId )
      {
        case ZCL_CLUSTER_ID_HVAC_THERMOSTAT:
    
          rxMsgCount += 1;  // Count this message
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_BLINK );  // Blink an LED
    
          HalLcdWriteString( (char*)pkt->cmd.Data, HAL_LCD_LINE_6 );
          HalLcdWriteStringValue( "Rcvd:", rxMsgCount, 10, HAL_LCD_LINE_7 );
    
          break;
      }
    }
    
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayUpdate
     *
     * @brief   Called to update the LCD display.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayUpdate( void )
    {
      // use LEDs to show heating or cooling cycles based off local temperature
      if ( zclSampleThermostat_LocalTemperature != NULL )
      {
        if ( zclSampleThermostat_LocalTemperature <= zclSampleThermostat_OccupiedHeatingSetpoint )
        {
          // turn on heating
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_HEAT;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
        }
        else if ( zclSampleThermostat_LocalTemperature >= zclSampleThermostat_OccupiedCoolingSetpoint )
        {
          // turn on cooling
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_COOL;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
        }
        else
        {
          // turn off heating/cooling
          zclSampleThermostat_SystemMode = HVAC_THERMOSTAT_SYSTEM_MODE_OFF;
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
          HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
        }
      }
    
      if ( giThermostatScreenMode == THERMOSTAT_HEATMODE )
      {
        zclSampleThermostat_LcdDisplayHeatMode();
      }
      else if ( giThermostatScreenMode == THERMOSTAT_COOLMODE )
      {
        zclSampleThermostat_LcdDisplayCoolMode();
      }
      else if ( giThermostatScreenMode == THERMOSTAT_HELPMODE )
      {
        zclSampleThermostat_LcdDisplayHelpMode();
      }
      else
      {
        zclSampleThermostat_LcdDisplayMainMode();
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayMainMode
     *
     * @brief   Called to display the main screen on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayMainMode( void )
    {
      char sDisplayTemp[16];
    
      if ( zclSampleThermostat_NwkState == DEV_ZB_COORD )
      {
        zclHA_LcdStatusLine1( 0 );
      }
      else if ( zclSampleThermostat_NwkState == DEV_ROUTER )
      {
        zclHA_LcdStatusLine1( 1 );
      }
      else if ( zclSampleThermostat_NwkState == DEV_END_DEVICE )
      {
        zclHA_LcdStatusLine1( 2 );
      }
    
      osal_memcpy( sDisplayTemp, "TEMP: ", 6 );
    
      // if local temperature has not been set, make note on display
      if ( zclSampleThermostat_LocalTemperature == NULL )
      {
        osal_memcpy( &sDisplayTemp[6], "N/A", 4 );
      }
      else
      {
        _ltoa( ( zclSampleThermostat_LocalTemperature / 100 ), (void *)(&sDisplayTemp[6]), 10 ); // only use whole number
        osal_memcpy( &sDisplayTemp[8], "C", 2 );
      }
    #ifdef LCD_SUPPORTED
      // display current temperature
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_2 );
    #endif
    
    #ifdef LCD_SUPPORTED
      if ( ( zclSampleThermostat_NwkState == DEV_ZB_COORD ) ||
           ( zclSampleThermostat_NwkState == DEV_ROUTER ) )
      {
        // display help key with permit join status
        if ( gPermitDuration )
        {
          HalLcdWriteString( "SW5: Help      *", HAL_LCD_LINE_3 );
        }
        else
        {
          HalLcdWriteString( "SW5: Help       ", HAL_LCD_LINE_3 );
        }
      }
      else
      {
        // display help key
        HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3);
      }
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayHelpMode
     *
     * @brief   Called to display the SW options on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayHelpMode( void )
    {
    #ifdef LCD_SUPPORTED
      HalLcdWriteString( (char *)sSwHeatSet, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sSwCoolSet, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayHeatMode
     *
     * @brief   Called to display the heating setpoint temperature on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayHeatMode( void )
    {
    #ifdef LCD_SUPPORTED
      char sDisplayTemp[16];
    
      osal_memcpy( sDisplayTemp, "HEAT TEMP: ", 11 );
      _ltoa( ( zclSampleThermostat_OccupiedHeatingSetpoint / 100 ), (void *)(&sDisplayTemp[11]), 10 ); // only use whole number
      osal_memcpy( &sDisplayTemp[13], "C", 2 );
    
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sTempLine2, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sTempLine3, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_LcdDisplayCoolMode
     *
     * @brief   Called to display the cooling setpoint temperature on the LCD.
     *
     * @param   none
     *
     * @return  none
     */
    void zclSampleThermostat_LcdDisplayCoolMode( void )
    {
    #ifdef LCD_SUPPORTED
      char sDisplayTemp[16];
    
      osal_memcpy(sDisplayTemp, "COOL TEMP: ", 11);
      _ltoa( ( zclSampleThermostat_OccupiedCoolingSetpoint / 100 ), (void *)(&sDisplayTemp[11]), 10 ); // only use whole number
      osal_memcpy( &sDisplayTemp[13], "C", 2 );
    
      HalLcdWriteString( (char *)sDisplayTemp, HAL_LCD_LINE_1 );
      HalLcdWriteString( (char *)sTempLine2, HAL_LCD_LINE_2 );
      HalLcdWriteString( (char *)sTempLine3, HAL_LCD_LINE_3 );
    #endif
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessIdentifyTimeChange
     *
     * @brief   Called to process any change to the IdentifyTime attribute.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessIdentifyTimeChange( void )
    {
      if ( zclSampleThermostat_IdentifyTime > 0 )
      {
        osal_start_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT, 1000 );
        HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
      }
      else
      {
        if ( zclSampleThermostat_OnOff )
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
        }
        else
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
        }
    
        osal_stop_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_IDENTIFY_TIMEOUT_EVT );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessAppMsg
     *
     * @brief   Process DoorLock messages
     *
     * @param   srcEP - Sending Apps endpoint
     * @param   len - number of bytes
     * @param   msg - pointer to message
     *          0 - lo byte destination address
     *          1 - hi byte destination address
     *          2 - destination endpoint
     *          3 - lo byte cluster ID
     *          4 - hi byte cluster ID
     *          5 - message length
     *          6 - destination address mode (first byte of data)
     *          7 - zcl command frame
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessAppMsg( uint8 srcEP, uint8 len, uint8 *msg )
    {
      afAddrType_t dstAddr;
      uint16 clusterID;
      zclFrameHdr_t hdr;
      uint8 *pData;
      uint8 dataLen;
    
      dstAddr.addr.shortAddr = BUILD_UINT16( msg[0], msg[1] );
      msg += 2;
      dstAddr.endPoint = *msg++;
      clusterID = BUILD_UINT16( msg[0], msg[1] );
      msg += 2;
      dataLen = *msg++; // Length of message (Z-Tool can support up to 255 octets)
      dstAddr.addrMode = (afAddrMode_t)(*msg++);
      dataLen--; // Length of ZCL frame
    
      // Begining of ZCL frame
      pData = zclParseHdr( &hdr, msg );
      dataLen -= (uint8)( pData - msg );
    
      // Is this a foundation type message?
      if ( zcl_ProfileCmd( hdr.fc.type ) )
      {
        if ( hdr.fc.manuSpecific )
        {
          // We don't support any manufacturer specific command -- just forward it.
          zcl_SendCommand( srcEP, &dstAddr, clusterID, hdr.commandID, FALSE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr.fc.disableDefaultRsp, hdr.manuCode, hdr.transSeqNum, dataLen, pData );
        }
        else
        {
          zclParseCmd_t cmd;
    
          cmd.endpoint = srcEP;
          cmd.dataLen = dataLen;
          cmd.pData = pData;
    
          zclSampleThermostat_ProcessFoundationMsg( &dstAddr, clusterID, &hdr, &cmd );
        }
      }
      else
      {
        // Nope, must be specific to the cluster ID
        if ( hdr.fc.manuSpecific )
        {
          // We don't support any manufacturer specific command -- just forward it.
          zcl_SendCommand( srcEP, &dstAddr, clusterID, hdr.commandID, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr.fc.disableDefaultRsp, hdr.manuCode, hdr.transSeqNum, dataLen, pData );
        }
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessFoundationMsg
     *
     * @brief   Process Foundation message
     *
     * @param   srcEP - Sending Apps endpoint
     * @param   dstAddr - where to send the request
     * @param   clusterID - real cluster ID
     * @param   hdr - pointer to the message header
     * @param   len - length of the received message
     * @param   data - received message
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessFoundationMsg( afAddrType_t *dstAddr, uint16 clusterID,
                                                    zclFrameHdr_t *hdr, zclParseCmd_t *pParseCmd )
    {
    #if defined(ZCL_READ) || defined(ZCL_WRITE) || defined(ZCL_REPORT) || defined(ZCL_DISCOVER)
      void *cmd;
    #endif
    
      switch ( hdr->commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ:
          cmd = zclParseInReadCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendRead( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReadCmd_t *)cmd,
                          ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWrite( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                           ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_WRITE_UNDIVIDED:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWriteUndivided( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                                    ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_WRITE_NO_RSP:
          cmd = zclParseInWriteCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendWriteNoRsp( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclWriteCmd_t *)cmd,
                                ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_WRITE
    
    #ifdef ZCL_REPORT
        case ZCL_CMD_CONFIG_REPORT:
          cmd = zclParseInConfigReportCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendConfigReportCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr,  clusterID, (zclCfgReportCmd_t *)cmd,
                                     ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          cmd = zclParseInReadReportCfgCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendReadReportCfgCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReadReportCfgCmd_t *)cmd,
                                      ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    
        case ZCL_CMD_REPORT:
          cmd = zclParseInReportCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendReportCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclReportCmd_t *)cmd,
                               ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_REPORT
    #ifdef ZCL_DISCOVER
        case ZCL_CMD_DISCOVER_ATTRS:
          cmd = zclParseInDiscAttrsCmd( pParseCmd );
          if ( cmd )
          {
            zcl_SendDiscoverAttrsCmd( SAMPLETHERMOSTAT_ENDPOINT, dstAddr, clusterID, (zclDiscoverAttrsCmd_t *)cmd,
                                      ZCL_FRAME_CLIENT_SERVER_DIR, hdr->fc.disableDefaultRsp, hdr->transSeqNum );
            osal_mem_free( cmd );
          }
          break;
    #endif // ZCL_DISCOVER
    
        default:
          // Unsupported command -- just forward it.
          zcl_SendCommand( pParseCmd->endpoint, dstAddr, clusterID, hdr->commandID, FALSE, ZCL_FRAME_CLIENT_SERVER_DIR,
                           hdr->fc.disableDefaultRsp, 0, hdr->transSeqNum, pParseCmd->dataLen, pParseCmd->pData );
          break;
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_BasicResetCB
     *
     * @brief   Callback from the ZCL General Cluster Library
     *          to set all the Basic Cluster attributes to default values.
     *
     * @param   none
     *
     * @return  none
     */
    static void zclSampleThermostat_BasicResetCB( void )
    {
      // Put device back to factory default settings
      zgWriteStartupOptions( ZG_STARTUP_SET, 3 );   // bit set both default configuration and default network
    
      // restart device
      MT_SysCommandProcessing( aProcessCmd );
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_IdentifyCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Command for this application.
     *
     * @param   srcAddr - source address and endpoint of the response message
     * @param   identifyTime - the number of seconds to identify yourself
     *
     * @return  none
     */
    static void zclSampleThermostat_IdentifyCB( zclIdentify_t *pCmd )
    {
      zclSampleThermostat_IdentifyTime = pCmd->identifyTime;
      zclSampleThermostat_ProcessIdentifyTimeChange();
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_IdentifyQueryRspCB
     *
     * @brief   Callback from the ZCL General Cluster Library when
     *          it received an Identity Query Response Command for this application.
     *
     * @param   srcAddr - requestor's address
     * @param   timeout - number of seconds to identify yourself (valid for query response)
     *
     * @return  none
     */
    static void zclSampleThermostat_IdentifyQueryRspCB(  zclIdentifyQueryRsp_t *pRsp )
    {
      (void)pRsp;
    #ifdef ZCL_EZMODE
      {
        zclEZMode_ActionData_t data;
        data.pIdentifyQueryRsp = pRsp;
        zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
      }
    #endif
    }
    
    /******************************************************************************
     *
     *  Functions for processing ZCL Foundation incoming Command/Response messages
     *
     *****************************************************************************/
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessIncomingMsg
     *
     * @brief   Process ZCL Foundation incoming message
     *
     * @param   pInMsg - pointer to the received message
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg)
    {
      switch ( pInMsg->zclHdr.commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ_RSP:
          zclSampleThermostat_ProcessInReadRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE_RSP:
          zclSampleThermostat_ProcessInWriteRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_REPORT
        case ZCL_CMD_CONFIG_REPORT:
          //zclSampleThermostat_ProcessInConfigReportCmd( pInMsg );
          break;
    
        case ZCL_CMD_CONFIG_REPORT_RSP:
          //zclSampleThermostat_ProcessInConfigReportRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG:
          //zclSampleThermostat_ProcessInReadReportCfgCmd( pInMsg );
          break;
    
        case ZCL_CMD_READ_REPORT_CFG_RSP:
          //zclSampleThermostat_ProcessInReadReportCfgRspCmd( pInMsg );
          break;
    
        case ZCL_CMD_REPORT:
          zclSampleThermostat_ProcessInReportCmd( pInMsg );
          break;
    #endif
        case ZCL_CMD_DEFAULT_RSP:
          zclSampleThermostat_ProcessInDefaultRspCmd( pInMsg );
          break;
    
        default:
          break;
      }
    
      if ( pInMsg->attrCmd )
      {
        osal_mem_free( pInMsg->attrCmd );
      }
    }
    
    #ifdef ZCL_READ
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInReadRspCmd
     *
     * @brief   Process the "Profile" Read Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReadRspCmd_t *readRspCmd;
      uint8 i;
    
      readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
      for (i = 0; i < readRspCmd->numAttr; i++)
      {
        // Notify the originator of the results of the original read attributes
        // attempt and, for each successfull request, the value of the requested
        // attribute
      }
    
      return ( TRUE );
    }
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInWriteRspCmd
     *
     * @brief   Process the "Profile" Write Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
    {
      zclWriteRspCmd_t *writeRspCmd;
      uint8 i;
    
      writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
      for (i = 0; i < writeRspCmd->numAttr; i++)
      {
        // Notify the device of the results of the its original write attributes
        // command.
      }
    
      return ( TRUE );
    }
    #endif // ZCL_WRITE
    
    #ifdef ZCL_REPORT
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInReportCmd
     *
     * @brief   Process the "Profile" Report Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static void zclSampleThermostat_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
    {
      zclReportCmd_t *pInTempSensorReport;
      zclReportCmd_t *pOutDemandReport;
      uint8 outDemandBuffer[sizeof( zclReportCmd_t ) + ( 2 * sizeof( zclReport_t ) )];
      bool send = TRUE;
    
      pInTempSensorReport = (zclReportCmd_t *)pInMsg->attrCmd;
    
      if ( pInTempSensorReport->attrList[0].attrID != ATTRID_MS_TEMPERATURE_MEASURED_VALUE )
      {
        return;
      }
    
      pOutDemandReport = (zclReportCmd_t *)outDemandBuffer;
    
      // store the current temperature value sent over the air from temperature sensor
      zclSampleThermostat_LocalTemperature = BUILD_UINT16(pInTempSensorReport->attrList[0].attrData[0], pInTempSensorReport->attrList[0].attrData[1]);
    
      // update display with current temperature information, set current mode
      zclSampleThermostat_LcdDisplayUpdate();
    
      pOutDemandReport->numAttr = 2;
      pOutDemandReport->attrList[0].attrID = ATTRID_HVAC_THERMOSTAT_PI_HEATING_DEMAND;
      pOutDemandReport->attrList[0].dataType = ZCL_DATATYPE_UINT8;
      pOutDemandReport->attrList[1].attrID = ATTRID_HVAC_THERMOSTAT_PI_COOLING_DEMAND;
      pOutDemandReport->attrList[1].dataType = ZCL_DATATYPE_UINT8;
    
      // send heating demand to heating/cooling unit
      if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_HEAT )
      {
        zclSampleThermostat_HeatingDemand = 100; // 100%
        zclSampleThermostat_CoolingDemand = 0;  // off
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      // send cooling demand to heating/cooling unit
      else if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_COOL )
      {
        zclSampleThermostat_HeatingDemand = 0;  // off
        zclSampleThermostat_CoolingDemand = 100;  // 100%
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      // turn heating/cooling unit off
      else if ( zclSampleThermostat_SystemMode == HVAC_THERMOSTAT_SYSTEM_MODE_OFF )
      {
        zclSampleThermostat_HeatingDemand = 0;  // off
        zclSampleThermostat_CoolingDemand = 0;  // off
    
        pOutDemandReport->attrList[0].attrData = &zclSampleThermostat_HeatingDemand;
        pOutDemandReport->attrList[1].attrData = &zclSampleThermostat_CoolingDemand;
      }
      else
      {
        send = FALSE;
      }
    
      if ( send )
      {
        zcl_SendReportCmd( SAMPLETHERMOSTAT_ENDPOINT, &zclSampleThermostat_DstAddr,
                          ZCL_CLUSTER_ID_HVAC_THERMOSTAT,
                          pOutDemandReport, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleThermostatSeqNum++ );
      }
    }
    #endif  // ZCL_REPORT
    
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessInDefaultRspCmd
     *
     * @brief   Process the "Profile" Default Response Command
     *
     * @param   pInMsg - incoming message to process
     *
     * @return  none
     */
    static uint8 zclSampleThermostat_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
    {
      // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
    
      // Device is notified of the Default Response command.
      (void)pInMsg;
    
      return ( TRUE );
    }
    
    #ifdef ZCL_EZMODE
    /*********************************************************************
     * @fn      zclSampleThermostat_ProcessZDOMsgs
     *
     * @brief   Called when this node receives a ZDO/ZDP response.
     *
     * @param   none
     *
     * @return  status
     */
    static void zclSampleThermostat_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
    {
      zclEZMode_ActionData_t data;
      ZDO_MatchDescRsp_t *pMatchDescRsp;
    
      // Let EZ-Mode know of the Match Descriptor Response
      if ( pMsg->clusterID == Match_Desc_rsp )
      {
        pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
        data.pMatchDescRsp = pMatchDescRsp;
        zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
        osal_mem_free( pMatchDescRsp );
      }
    }
    
    /*********************************************************************
     * @fn      zclSampleThermostat_EZModeCB
     *
     * @brief   The Application is informed of events. This can be used to show on the UI what is
    *           going on during EZ-Mode steering/finding/binding.
     *
     * @param   state - EZ-Mode state
     *          pData - data appropriate to state
     *
     * @return  none
     */
    static void zclSampleThermostat_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
    {
    #ifdef LCD_SUPPORTED
      char szLine[20];
      char *pStr;
      uint8 err;
    #endif
    
      // time to go into identify mode
      if ( state == EZMODE_STATE_IDENTIFYING )
      {
        zclSampleThermostat_IdentifyTime = (EZMODE_TIME / 1000);  // convert to seconds
        zclSampleThermostat_ProcessIdentifyTimeChange();
      }
    
      // autoclosing, show what happened (success, cancelled, etc...)
      if( state == EZMODE_STATE_AUTOCLOSE )
      {
    #ifdef LCD_SUPPORTED
        pStr = NULL;
        err = pData->sAutoClose.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          pStr = "EZMode: Success";
        }
        if ( pStr )
        {
          if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
        }
    #endif
      }
    
      // finished, either show DstAddr/EP, or nothing (depending on success or not)
      if ( state == EZMODE_STATE_FINISH )
      {
        // turn off identify mode
        zclSampleThermostat_IdentifyTime = 0;
        zclSampleThermostat_ProcessIdentifyTimeChange();
    
    #ifdef LCD_SUPPORTED
        // if successful, inform user which nwkaddr/ep we bound to
        pStr = NULL;
        err = pData->sFinish.err;
        if ( err == EZMODE_ERR_SUCCESS )
        {
          // "EZDst:1234 EP:34"
          osal_memcpy(szLine, "EZDst:", 6);
          zclHA_uint16toa( pData->sFinish.nwkaddr, &szLine[6]);
          osal_memcpy(&szLine[10], " EP:", 4);
          _ltoa( pData->sFinish.ep, (void *)(&szLine[14]), 16 );  // _ltoa NULL terminates
          pStr = szLine;
        }
        else if ( err == EZMODE_ERR_BAD_PARAMETER )
        {
          pStr = "EZMode: BadParm";
        }
        else if ( err == EZMODE_ERR_CANCELLED )
        {
          pStr = "EZMode: Cancel";
        }
        else if ( err == EZMODE_ERR_NOMATCH )
        {
          pStr = "EZMode: NoMatch"; // not a match made in heaven
        }
        else
        {
          pStr = "EZMode: TimeOut";
        }
        if ( pStr )
        {
          if ( giThermostatScreenMode == THERMOSTAT_MAINMODE )
          {
            HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
          }
        }
    #endif  // LCD_SUPPORTED
    
        // show main UI screen 3 seconds after completing EZ-Mode
        osal_start_timerEx( zclSampleThermostat_TaskID, SAMPLETHERMOSTAT_MAIN_SCREEN_EVT, 3000 );
      }
    }
    #endif // ZCL_EZMODE
    
    /****************************************************************************
    ****************************************************************************/
    
    
    

    i want to implement only 2 thing ->

    1) i want to stream real-time audio data over the zigbee .

    2) i want to transfer text files (say1 mb file store on SD-CARD ) over the zigbee.

    and as per your suggestion i came to know that AF_DataRequest is a API to transfer bulk amount of data over zigbee and that's what we are struggling to make it work......

    i hope u understand my points and my problems...

    i requesting you to help me solve these issue so that i can complete my task.....

    plz help me sir.....

    waiting for your reply...............

    Thanks & Regards,

    Maneesh singh 

  • When you use AF_datarequest with ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT as cluster ID on sender, the receiver will process it in zcl_event_loop and goes to zcl_ProcessMessageMSG. In zcl_ProcessMessageMSG(), it would find that your data doesn't follow ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT format and return unsupport message status from it. That's why you can't receive it in zclSampleThermostat_ProcessInReportCmd. If you use AF_datarequest, please use extended cluster ID which is not defined by Zigbee spec. Otherwise, you will have the same problem.

  • Hello YiKai Chen,

    thanks for your reply...

    i understand what ur trying to explain me but i didnt understand this line which u said -.

    1) If you use AF_datarequest, please use extended cluster ID which is not defined by Zigbee spec. Otherwise, you will have the same problem.

    what this means?

    2) in Generic APP clusterID is defined like this ->  #define GENERICAPP_CLUSTERID          1

    & in temp sensor it is  -> #define ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT        0x0402

     so what is the problem ? what is the difference ? 

    3) what is extended cluster ID ?

    4) and if it is not defined by Zigbee spec then how AF_DataRequest API is working in GenericAPP ?

    5) so now what will be the solution for this ? how i can use this API ?

    Thanks & Regards,

    Maneesh singh

  • In Zigbee HA profile, there are definition about different cluster IDs. You can refer to zcl.h and map them with Zigbee HA profile. If you use those cluster ID in zcl.h with AF_DataRequest, you will have the problem that I explain to you in previous post. So, I suggest you to extend Cluster ID in zcl.h, which mean use a new cluster ID that is not presented in zcl.h. Since GenericAPP use private profile (#define GENERICAPP_PROFID 0x0104) not HA profile, it doesn't have this problem.

  • Hello YiKai Chen sir,

    so u mean to say i should do like this ->

    Temp side :-

    1) like GenericAPP define clusterID -->  #define GENERICAPP_CLUSTERID          1

    2) add this cluster in inclusterlist

    3) now use this clusterID in my code -->

    if ( AF_DataRequest( &zclSampleTemperatureSensor_DstAddr, &sampleTemperatureSensor_TestEp,
           GENERICAPP_CLUSTERID,   ////// here i am using my own defined cluster
    (byte)osal_strlen( theMessageData ) + 1,
    (byte *)&theMessageData,
    &zclSampleTemperatureSensor_TransID,
    AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

    Thermostat side :-

    4) define cluster in thermostat side also-->  #define GENERICAPP_CLUSTERID          1

    5) add this cluster in outclusterlist

    4) now in thermostat side in AF_INCOMING_MSG_CMD call back fn -->

    static void zclSampleThermostat_MessageMSGCB( afIncomingMSGPacket_t *pkt )

    switch ( pkt->clusterId )
    {
    case GENERICAPP_CLUSTERID:

    rxMsgCount += 1; // Count this message
    HalLedSet ( HAL_LED_4, HAL_LED_MODE_BLINK ); // Blink an LED

    HalLcdWriteString( (char*)pkt->cmd.Data, HAL_LCD_LINE_6 );
    HalLcdWriteStringValue( "Rcvd:", rxMsgCount, 10, HAL_LCD_LINE_7 );

    break;
    }
    }

    plz correct me if i am missing any steps or doing anything wrong or misunderstood anything........

    Thanks & Regards,

    Maneesh singh

  • You can't define GENERICAPP_CLUSTERID to 1. It is already used by HA profil. Please have a look at zcl.h. By the way, why don't you use zcl_SendReportCmd instead of AF_DataRequest if you want to use HA profile.

  • hello sir,

    1) yes u r right sir i cannot define it 1,  so i'll choose any another no. may be  0x1001 becoz in zcl.h last cluster is 

    // Light Link cluster
    #define ZCL_CLUSTER_ID_LIGHT_LINK         0x1000

    so i think i can choose 0x1001...... am i right ? 

     2) what i found is that the zcl_sendreport cmd can send maximum 10 - 12 byte of data at a time not more than that... and i hav to send bulk amount of data......so i can't prefer zcl_sendreport cmd.......becoz once i tried to send 20 bytes of data with zcl_sendreport but i was getting garbage value only.... 

    3) and when i tried with AF_datarequest  i found that it can send maximum 70 - 80 bytes of data so i found it much more convenient for my task...... that's why i am trying to use AF_DataRequest API .

    so plz help me how can i make AF_DataRequest API to work ??

    one thing i want to ask you sir ==>  if u remember once u said u also successfully able to stream live audio data over zigbee  and for that u used AF_DataRequest cmd.....so how u able to make it work ? i mean to say u did this with private profile like Generic APP or u also used HA profile ?  

    Thanks & Regards,

    Maneesh singh

  • If I revise zclSampleTemperatureSensor_SendTemp() to the followings, I don't have problem to send more than 12 bytes.

    char *theMessageData = "Hello i am temp Sensor 1 Hello i am temp Sensor 2 Hello i am temp Sensor";
    static void zclSampleTemperatureSensor_SendTemp( void )
    {
    #ifdef ZCL_REPORT
      zclReportCmd_t *pReportCmd;

      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = ATTRID_MS_TEMPERATURE_MEASURED_VALUE;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_CHAR_STR;
        pReportCmd->attrList[0].attrData = (void *)theMessageData;//(&zclSampleTemperatureSensor_MeasuredValue);
        zcl_SendReportCmd( SAMPLETEMPERATURESENSOR_ENDPOINT, &zclSampleTemperatureSensor_DstAddr,
                           ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
                           pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleTemperatureSensorSeqNum++ );
      }

      osal_mem_free( pReportCmd );
    #endif  // ZCL_REPORT
    }

  • Hello YiKai Chen sir,

    as u suggested i tried and i am able to send big string.....but this also has problem ---->

    1) when i tried to send these datatypes it works fine and i am able to receive properly at thermostat side->

    char *theMessageData = "Hello i am temp Sensor1 Hello i am temp Sensor2 Hello i am temp Sensor3";

    char *theMessageData = "123456789_123456789_123456789_123456789_123456789";

     

    2) but when i tried these datatypes then like my previous testing i am able to send only 10-12 byte of data maximum...

     int8 pCharStrNew[]= {1,2,3,4,5,6,7,8,9,0,0,0,1,2,3,4,5,6,7,8,9};

    char pCharStrNew[]= {1,2,3,4,5,6,7,8,9,0,0,0,1,2,3,4,5,6,7,8,9};

    at receiver side after receiving and printing 10th or 11byte data correctly i am start getting garbage values...this is same issue which i was getting before with zcl_sendreport API...

    that's why i moved to use AF_DataRequest API where i am able to send 70 -80 byte of data correctly...

    i am receiving data at receiver like this ->

    UARTprintf("received string is %d\n", (pInTempSensorReport->attrList[0].attrData[8]));  ///getting correct
    UARTprintf("received string is %d\n", (pInTempSensorReport->attrList[0].attrData[9]));  ///getting correct
    UARTprintf("received string is %d\n", (pInTempSensorReport->attrList[0].attrData[10]));  ///getting wrong values
    UARTprintf("received string is %d\n", (pInTempSensorReport->attrList[0].attrData[11]));  ///getting wrong values

    etc....

    Generic APP i was doing like this ->

    int8 theMessageData[] = {99,9,0,0,7,2,1,77,0,9,10};//11,1,9,0,2,8,66,0,19,20,21,1,1,1,1,1,1,1,29,30,31,1,1,1,1,13,2,2,39,40,41,2,2,2,2,2,2,2,49,50,51,9,0,0,7,2,1,77,59,60,61,1,1,9,0,2,8,66,69,70 };

    if  ( AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
          GENERICAPP_CLUSTERID,
          70,  //<= it is lenght of buffer
          (byte *)&theMessageData,
          &GenericApp_TransID,
          AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

    and as u can see with AF_DataRequest API cmd  i am able to send 70 -80 byte of data correctly... .and this is what my application also need...

    My Application Need ->

    1) i will store 250kb or say 300kb of data on SD-CARD

    2) then i'll create one buffer of  64byte and i'll creat a loop through which i'll send this data over the zigbee

    3) at the receiver side i'll receive this data in a 64bytes of buffer and from there i'll write this data on a SD-CARD

    plz help me and guide me how can i implement above application steps in zigbee and through which API i can achieve this task.......

    plz reply sir.....

    Thanks & Regards,

    Maneesh singh 

  • 1. You can send array data with 0 as element by zcl_SendReportCmd. The array is regarded as string and  0 would be judged as end of string.

    2. If you have 0 in your array, you have to use AF_DataRequest. It looks OK in your AF_DataRequest and I think your problem is on receiver side. As I told you, the message would be filtered in zcl_event_loop. You can try to reorder tasksArr like the followings and try to see if you can receive AF_INCOMING_MSG_CMD in zclSampleThermostat_event_loop().

    const pTaskEventHandlerFn tasksArr[] = {
      macEventLoop,
      nwk_event_loop,
      Hal_ProcessEvent,
    #if defined( MT_TASK )
      MT_ProcessEvent,
    #endif
      APS_event_loop,
    #if defined ( ZIGBEE_FRAGMENTATION )
      APSF_ProcessEvent,
    #endif
      ZDApp_event_loop,
    #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
      ZDNwkMgr_event_loop,
    #endif
      zclSampleThermostat_event_loop,
      zcl_event_loop
    };


    I don't have EVB nearby so you have to test this by yourself.

  • Hello YiKai Chen sir,

    thanks for your reply...

     as u said i tested it on my EVM but it is not working...

    1) the code is  getting compiled properly but after flashing it in controller when i am trying for EZ  mode binding.... it is not getting bind with other device....the program control remain in event-loop fn only... these are the program control steps which i printed on screen using UART -> 

    after powering ON my cc2538 board =>

    Now in zcl_event_loop fn
    in ZDApp_event_loop fn, taskid => 6, event => 1
    in ZDApp_event_loop fn -> ZDO_NETWORK_INIT
    in ZDApp_event_loop fn, taskid => 6, event => 16
    in ZDApp_event_loop fn -> ZDO_STATE_CHANGE_EVT

    Now in <> event loop fn
    task id = 8, event = 8000
    Now in event loop -> SYS_EVENT_MSG


    in ZDApp_event_loop fn, taskid => 6, event => 2
    in ZDApp_event_loop fn -> ZDO_NETWORK_START
    in ZDApp_event_loop fn, taskid => 6, event => 1
    in ZDApp_event_loop fn -> ZDO_NETWORK_INIT
    in ZDApp_event_loop fn, taskid => 6, event => 16
    in ZDApp_event_loop fn -> ZDO_STATE_CHANGE_EVT
    .....................
    in ZDApp_event_loop fn, taskid => 6, event => 64
    in ZDApp_event_loop fn, taskid => 6, event => 32768
    in ZDApp_event_loop fn -> SYS_EVENT_MSG

    Now in  <> event loop fn
    task id = 8, event = 8000
    Now in event loop -> SYS_EVENT_MSG

    Now in  <> event loop fn
    task id = 8, event = 8000
    Now in event loop -> SYS_EVENT_MSG

    Now in  <> event loop fn
    task id = 8, event = 8000
    Now in event loop -> SYS_EVENT_MSG

    and it continues............. so you can see here program control is coming in <> event loop fn and not coming out....

    2) but when i am doing like previous (first zcl_event then <>event  i.e without swaping the position which u suggested ) then both the device are getting bind properly ..............   but callback fn for AF_msg is not getting called.

    plz tell me sir how can i solve this issue how can i make AF_DataRequest  cmd API to work ? 

    Thanks & regards,

    Maneesh singh

  • hello YIKai Chen sir,
    plz reply sir, what should i do ?
    how can i send bulk of data from zigbee ?
    and how can i make AF_DataRequest to work ?

    plz reply sir...

    Thanks & Regards,
    Maneesh singh
  • Try to revise zcl_event_loop() using the following red codes. You have to add AF_INCOMING_MSG_CMD case in your application event handler.

    uint16 zcl_event_loop( uint8 task_id, uint16 events )
    {
      uint8 *msgPtr;

      (void)task_id;  // Intentionally unreferenced parameter

      if ( events & SYS_EVENT_MSG )
      {
        msgPtr = osal_msg_receive( zcl_TaskID );
        while ( msgPtr != NULL )
        {
          uint8 dealloc = TRUE;

          if ( *msgPtr == AF_INCOMING_MSG_CMD )
          {
            if ( ZSuccess!=zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr ) )
            {
              // send it to another task to process.
              osal_msg_send( zcl_RegisteredMsgTaskID, msgPtr );
              dealloc = FALSE;
            }
          }
          else if ( zcl_RegisteredMsgTaskID != TASK_NO_TASK )
          {
            // send it to another task to process.
            osal_msg_send( zcl_RegisteredMsgTaskID, msgPtr );
            dealloc = FALSE;
          }

          // Release the memory
          if ( dealloc )
          {
            osal_msg_deallocate( msgPtr );
          }

          // Next
          msgPtr = osal_msg_receive( zcl_TaskID );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }

      // Discard unknown events
      return 0;
    }

  • Hello YiKai Chen sir,

    Thanks for your reply....

    as u suggested i did the same thing but situation is still same like previous one...... -> still it is not getting bind together....and i am not able to send / Receive the AFDataRequest msg.....

    here is what i did =>

    1) in OSAL_Sample<>.c

    const pTaskEventHandlerFn tasksArr[] =

    {...........
    ............
    zclSampleThermostat_event_loop,
    zcl_event_loop

    };

    void osalInitTasks( void )
    {..........

    zcl_Init( taskID++ );
    zclSampleThermostat_Init( taskID );
    }

    2)  in zcl.c file

    uint16 zcl_event_loop( uint8 task_id, uint16 events )
    {............

    if ( *msgPtr == AF_INCOMING_MSG_CMD )
    {
         if(ZSuccess != (zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr )))
        {
            // send it to another task to process.
             osal_msg_send( zcl_RegisteredMsgTaskID, msgPtr );
            dealloc = FALSE;
       }
    }

    }

    3) i modified the zcl_ProcessMessageMSG in zcl.c by taking reference from zstack mesh1.0.0 becoz in zstack home 1.0 the fn return type was void====>

    void zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )

    {

    }

    so i was not able to compile the code as suggested by you.......... so i modified few lines especially return statements and fn return type....modified line is highlighted in yellow..

    typedef enum           // i defined these in zcl.h file
    {
    ZCL_PROC_SUCCESS = 0, // Message was processed
    ZCL_PROC_INVALID , // Format or parameter was wrong
    ZCL_PROC_EP_NOT_FOUND, // Endpoint descriptor not found
    ZCL_PROC_NOT_OPERATIONAL, // Can't respond to this command
    ZCL_PROC_INTERPAN_FOUNDATION_CMD, // INTER-PAN and Foundation Command (not allowed)
    ZCL_PROC_NOT_SECURE, // Security was required but the message is not secure
    ZCL_PROC_MANUFACTURER_SPECIFIC, // Manufacturer Specific command - not handled
    ZCL_PROC_MANUFACTURER_SPECIFIC_DR, // Manufacturer Specific command - not handled, but default response sent
    ZCL_PROC_NOT_HANDLED, // No default response was sent and the message was not handled
    ZCL_PROC_NOT_HANDLED_DR, // default response was sent and the message was not handled
    } zclProcMsgStatus_t;

    zclProcMsgStatus_t zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )
    {

    endPointDesc_t *epDesc;
    zclIncoming_t inMsg;
    zclLibPlugin_t *pInPlugin;
    zclDefaultRspCmd_t defautlRspCmd;
    uint8 options;
    uint8 securityEnable;
    uint8 interPanMsg;
    ZStatus_t status = ZFailure;
    uint8 defaultResponseSent = FALSE; //----

    if ( pkt->cmd.DataLength == 0 )

    return ( ZCL_PROC_INVALID ); // Error, ignore the message //----
    }

    // Initialize
    rawAFMsg = (afIncomingMSGPacket_t *)pkt;
    inMsg.msg = pkt;
    inMsg.attrCmd = NULL;
    inMsg.pData = NULL;
    inMsg.pDataLen = 0;

    inMsg.pData = zclParseHdr( &(inMsg.hdr), pkt->cmd.Data );
    inMsg.pDataLen = pkt->cmd.DataLength;
    inMsg.pDataLen -= (uint16)(inMsg.pData - pkt->cmd.Data);

    // Temporary workaround to allow callback functions access to the
    // transaction sequence number. Callback functions will call
    // zcl_getParsedTransSeqNum() to retrieve this number.
    savedZCLTransSeqNum = inMsg.hdr.transSeqNum; //----

    // Find the wanted endpoint
    epDesc = afFindEndPointDesc( pkt->endPoint );
    if ( epDesc == NULL )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_EP_NOT_FOUND ); // Error, ignore the message //----
    }

    if ( ( epDesc->simpleDesc == NULL ) ||
    ( zcl_DeviceOperational( pkt->endPoint, pkt->clusterId, inMsg.hdr.fc.type,
    inMsg.hdr.commandID, epDesc->simpleDesc->AppProfId ) == FALSE ) )
    {

    rawAFMsg = NULL;
    return ( ZCL_PROC_NOT_OPERATIONAL ); // Error, ignore the message //--
    }

    #if defined ( INTER_PAN )
    if ( StubAPS_InterPan( pkt->srcAddr.panId, pkt->srcAddr.endPoint ) )
    {

    if ( zcl_ProfileCmd( inMsg.hdr.fc.type ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_INTERPAN_FOUNDATION_CMD ); //----
    }

    interPanMsg = TRUE;
    options = AF_TX_OPTIONS_NONE;
    }
    else
    #endif
    {
    interPanMsg = FALSE;
    options = zclGetClusterOption( pkt->endPoint, pkt->clusterId );
    }

    // Find the appropriate plugin
    pInPlugin = zclFindPlugin( pkt->clusterId, epDesc->simpleDesc->AppProfId );

    // Local and remote Security options must match except for Default Response command
    if ( ( pInPlugin != NULL ) && !zcl_DefaultRspCmd( inMsg.hdr ) )
    {
    securityEnable = ( options & AF_EN_SECURITY ) ? TRUE : FALSE;


    if ( ( securityEnable == TRUE ) && ( pkt->SecurityUse == FALSE ) )
    {
    if ( UNICAST_MSG( inMsg.msg ) )
    {
    // Send a Default Response command back with no Application Link Key security
    zclSetSecurityOption( pkt->endPoint, pkt->clusterId, FALSE );

    defautlRspCmd.statusCode = status;
    defautlRspCmd.commandID = inMsg.hdr.commandID;
    zcl_SendDefaultRspCmd( inMsg.msg->endPoint, &(inMsg.msg->srcAddr),
    inMsg.msg->clusterId, &defautlRspCmd,
    !inMsg.hdr.fc.direction, true,
    inMsg.hdr.manuCode, inMsg.hdr.transSeqNum );

    zclSetSecurityOption( pkt->endPoint, pkt->clusterId, TRUE );
    }

    rawAFMsg = NULL;

    return ( ZCL_PROC_NOT_SECURE ); // Error, ignore the message //---
    }
    }

    // Is this a foundation type message
    if ( !interPanMsg && zcl_ProfileCmd( inMsg.hdr.fc.type ) )
    {
    if ( inMsg.hdr.fc.manuSpecific )
    {
    // We don't support any manufacturer specific command
    status = ZCL_STATUS_UNSUP_MANU_GENERAL_COMMAND;
    }
    else if ( ( inMsg.hdr.commandID <= ZCL_CMD_MAX ) &&
    ( zclCmdTable[inMsg.hdr.commandID].pfnParseInProfile != NULL ) )
    {
    zclParseCmd_t parseCmd;

    parseCmd.endpoint = pkt->endPoint;
    parseCmd.dataLen = inMsg.pDataLen;
    parseCmd.pData = inMsg.pData;

    // Parse the command, remember that the return value is a pointer to allocated memory
    inMsg.attrCmd = zclParseCmd( inMsg.hdr.commandID, &parseCmd );
    if ( (inMsg.attrCmd != NULL) && (zclCmdTable[inMsg.hdr.commandID].pfnProcessInProfile != NULL) )
    {
    // Process the command
    if ( zclProcessCmd( inMsg.hdr.commandID, &inMsg ) == FALSE )
    {
    // Couldn't find attribute in the table.
    }
    }

    // Free the buffer
    if ( inMsg.attrCmd )
    {
    zcl_mem_free( inMsg.attrCmd );
    }

    if ( CMD_HAS_RSP( inMsg.hdr.commandID ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_SUCCESS ); // We're done //---
    }

    status = ZSuccess;
    }
    else
    {

    status = ZCL_STATUS_UNSUP_GENERAL_COMMAND;
    }
    }
    else // Not a foundation type message, so it must be specific to the cluster ID.
    {
    if ( pInPlugin && pInPlugin->pfnIncomingHdlr )
    {
    // The return value of the plugin function will be
    // ZSuccess - Supported and need default response
    // ZFailure - Unsupported
    // ZCL_STATUS_CMD_HAS_RSP - Supported and do not need default rsp
    // ZCL_STATUS_INVALID_FIELD - Supported, but the incoming msg is wrong formatted
    // ZCL_STATUS_INVALID_VALUE - Supported, but the request not achievable by the h/w
    // ZCL_STATUS_SOFTWARE_FAILURE - Supported but ZStack memory allocation fails
    status = pInPlugin->pfnIncomingHdlr( &inMsg );
    if ( status == ZCL_STATUS_CMD_HAS_RSP || ( interPanMsg && status == ZSuccess ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_SUCCESS ); // We're done
    }
    }

    if ( status == ZFailure )

    if ( inMsg.hdr.fc.manuSpecific )
    {
    status = ZCL_STATUS_UNSUP_MANU_CLUSTER_COMMAND;
    }
    else
    {
    status = ZCL_STATUS_UNSUP_CLUSTER_COMMAND;
    }
    }
    }

    if ( UNICAST_MSG( inMsg.msg ) && inMsg.hdr.fc.disableDefaultRsp == 0 )
    {
    // Send a Default Response command back
    defautlRspCmd.statusCode = status;
    defautlRspCmd.commandID = inMsg.hdr.commandID;
    zcl_SendDefaultRspCmd( inMsg.msg->endPoint, &(inMsg.msg->srcAddr),
    inMsg.msg->clusterId, &defautlRspCmd,
    !inMsg.hdr.fc.direction, true,
    inMsg.hdr.manuCode, inMsg.hdr.transSeqNum );
    defaultResponseSent = TRUE;
    }

    rawAFMsg = NULL;
    if ( status == ZSuccess )
    {
    return ( ZCL_PROC_SUCCESS );
    }
    else if ( status == ZCL_STATUS_UNSUP_MANU_GENERAL_COMMAND )
    {
    if ( defaultResponseSent )
    {
    return ( ZCL_PROC_MANUFACTURER_SPECIFIC_DR );
    }
    else
    {
    return ( ZCL_PROC_MANUFACTURER_SPECIFIC );
    }
    }
    else
    {
    if ( defaultResponseSent )
    {
    return ( ZCL_PROC_NOT_HANDLED_DR );
    }
    else
    {
    return ( ZCL_PROC_NOT_HANDLED );
    }
    }
    }

    4) in zcl_sample<>.c file

    case ZCL_INCOMING_MSG:       // Incoming ZCL Foundation command/response messages

    zclSampleThermostat_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
    break;

     

    plz check it and tell me sir what i am doing  wrong ? is any of my step is wrong?

     

    Thanks & Regards,

    Maneesh singh

  • Hello sir,
    will you plz tell how to attach and send source files or zip files in this forum.....earlier i was able to do it becoz one tab/button was provided to attach and send file but now in this new look of forum there is buttons to send pic and movies but tab/button is missing for sending files......
    so will you plz tell me how can i attach files here in this forum.............

    Thanks & regards,
    Maneesh singh
  • I report the issue that you can't attach files to E2E forum support and hopefully they can fix the problem for you.
  • You can try to use "Inser/Edit Media" button in "Use rich formatting".

  • The expert of E2E forum support team replies:
    Easiest way to add files now is using drag and drop in the rich text editor.
  • In reply to YiKai Chen:

    Hello YiKai Chen sir,

    Thanks for your reply....

    as u suggested i did the same thing but situation is still same like previous one...... -> still it is not getting bind together....and i am not able to send / Receive the AFDataRequest msg.....

    here is what i did =>

    1) in OSAL_Sample<>.c

    const pTaskEventHandlerFn tasksArr[] =

    {...........
    ............
    zclSampleThermostat_event_loop,
    zcl_event_loop

    };

    void osalInitTasks( void )
    {..........

    zcl_Init( taskID++ );
    zclSampleThermostat_Init( taskID );
    }

    2)  in zcl.c file

    uint16 zcl_event_loop( uint8 task_id, uint16 events )
    {............

    if ( *msgPtr == AF_INCOMING_MSG_CMD )

         if(ZSuccess != (zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr )))
        {
            // send it to another task to process.
             osal_msg_send( zcl_RegisteredMsgTaskID, msgPtr );
            dealloc = FALSE;
       }
    }

    }

    3) i modified the zcl_ProcessMessageMSG in zcl.c by taking reference from zstack mesh1.0.0 becoz in zstack home 1.0 the fn return type was void====>

    void zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )

    {

    }

    so i was not able to compile the code as suggested by you.......... so i modified few lines especially return statements and fn return type....modified line is highlighted in yellow..

    typedef enum           // i defined these in zcl.h file
    {
    ZCL_PROC_SUCCESS = 0, // Message was processed
    ZCL_PROC_INVALID , // Format or parameter was wrong
    ZCL_PROC_EP_NOT_FOUND, // Endpoint descriptor not found
    ZCL_PROC_NOT_OPERATIONAL, // Can't respond to this command
    ZCL_PROC_INTERPAN_FOUNDATION_CMD, // INTER-PAN and Foundation Command (not allowed)
    ZCL_PROC_NOT_SECURE, // Security was required but the message is not secure
    ZCL_PROC_MANUFACTURER_SPECIFIC, // Manufacturer Specific command - not handled
    ZCL_PROC_MANUFACTURER_SPECIFIC_DR, // Manufacturer Specific command - not handled, but default response sent
    ZCL_PROC_NOT_HANDLED, // No default response was sent and the message was not handled
    ZCL_PROC_NOT_HANDLED_DR, // default response was sent and the message was not handled
    } zclProcMsgStatus_t;

    zclProcMsgStatus_t zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )


    endPointDesc_t *epDesc;
    zclIncoming_t inMsg;
    zclLibPlugin_t *pInPlugin;
    zclDefaultRspCmd_t defautlRspCmd;
    uint8 options;
    uint8 securityEnable;
    uint8 interPanMsg;
    ZStatus_t status = ZFailure;
    uint8 defaultResponseSent = FALSE; //----

    if ( pkt->cmd.DataLength == 0 )

    return ( ZCL_PROC_INVALID ); // Error, ignore the message //----
    }

    // Initialize
    rawAFMsg = (afIncomingMSGPacket_t *)pkt;
    inMsg.msg = pkt;
    inMsg.attrCmd = NULL;
    inMsg.pData = NULL;
    inMsg.pDataLen = 0;

    inMsg.pData = zclParseHdr( &(inMsg.hdr), pkt->cmd.Data );
    inMsg.pDataLen = pkt->cmd.DataLength;
    inMsg.pDataLen -= (uint16)(inMsg.pData - pkt->cmd.Data);

    // Temporary workaround to allow callback functions access to the 
    // transaction sequence number. Callback functions will call 
    // zcl_getParsedTransSeqNum() to retrieve this number.
    savedZCLTransSeqNum = inMsg.hdr.transSeqNum; //----

    // Find the wanted endpoint
    epDesc = afFindEndPointDesc( pkt->endPoint );
    if ( epDesc == NULL )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_EP_NOT_FOUND ); // Error, ignore the message //----
    }

    if ( ( epDesc->simpleDesc == NULL ) ||
    ( zcl_DeviceOperational( pkt->endPoint, pkt->clusterId, inMsg.hdr.fc.type,
    inMsg.hdr.commandID, epDesc->simpleDesc->AppProfId ) == FALSE ) )
    {

    rawAFMsg = NULL;
    return ( ZCL_PROC_NOT_OPERATIONAL ); // Error, ignore the message //--
    }

    #if defined ( INTER_PAN )
    if ( StubAPS_InterPan( pkt->srcAddr.panId, pkt->srcAddr.endPoint ) )
    {

    if ( zcl_ProfileCmd( inMsg.hdr.fc.type ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_INTERPAN_FOUNDATION_CMD ); //----
    }

    interPanMsg = TRUE;
    options = AF_TX_OPTIONS_NONE;
    }
    else
    #endif
    {
    interPanMsg = FALSE;
    options = zclGetClusterOption( pkt->endPoint, pkt->clusterId );
    }

    // Find the appropriate plugin
    pInPlugin = zclFindPlugin( pkt->clusterId, epDesc->simpleDesc->AppProfId );

    // Local and remote Security options must match except for Default Response command
    if ( ( pInPlugin != NULL ) && !zcl_DefaultRspCmd( inMsg.hdr ) )
    {
    securityEnable = ( options & AF_EN_SECURITY ) ? TRUE : FALSE;


    if ( ( securityEnable == TRUE ) && ( pkt->SecurityUse == FALSE ) )
    {
    if ( UNICAST_MSG( inMsg.msg ) )
    {
    // Send a Default Response command back with no Application Link Key security
    zclSetSecurityOption( pkt->endPoint, pkt->clusterId, FALSE );

    defautlRspCmd.statusCode = status;
    defautlRspCmd.commandID = inMsg.hdr.commandID;
    zcl_SendDefaultRspCmd( inMsg.msg->endPoint, &(inMsg.msg->srcAddr),
    inMsg.msg->clusterId, &defautlRspCmd,
    !inMsg.hdr.fc.direction, true,
    inMsg.hdr.manuCode, inMsg.hdr.transSeqNum );

    zclSetSecurityOption( pkt->endPoint, pkt->clusterId, TRUE );
    }

    rawAFMsg = NULL;

    return ( ZCL_PROC_NOT_SECURE ); // Error, ignore the message //---
    }
    }

    // Is this a foundation type message
    if ( !interPanMsg && zcl_ProfileCmd( inMsg.hdr.fc.type ) )
    {
    if ( inMsg.hdr.fc.manuSpecific )
    {
    // We don't support any manufacturer specific command
    status = ZCL_STATUS_UNSUP_MANU_GENERAL_COMMAND;
    }
    else if ( ( inMsg.hdr.commandID <= ZCL_CMD_MAX ) &&
    ( zclCmdTable[inMsg.hdr.commandID].pfnParseInProfile != NULL ) )
    {
    zclParseCmd_t parseCmd;

    parseCmd.endpoint = pkt->endPoint;
    parseCmd.dataLen = inMsg.pDataLen;
    parseCmd.pData = inMsg.pData;

    // Parse the command, remember that the return value is a pointer to allocated memory
    inMsg.attrCmd = zclParseCmd( inMsg.hdr.commandID, &parseCmd );
    if ( (inMsg.attrCmd != NULL) && (zclCmdTable[inMsg.hdr.commandID].pfnProcessInProfile != NULL) )
    {
    // Process the command
    if ( zclProcessCmd( inMsg.hdr.commandID, &inMsg ) == FALSE )
    {
    // Couldn't find attribute in the table.
    }
    }

    // Free the buffer
    if ( inMsg.attrCmd )
    {
    zcl_mem_free( inMsg.attrCmd );
    }

    if ( CMD_HAS_RSP( inMsg.hdr.commandID ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_SUCCESS ); // We're done //---
    }

    status = ZSuccess;
    }
    else
    {

    status = ZCL_STATUS_UNSUP_GENERAL_COMMAND;
    }
    }
    else // Not a foundation type message, so it must be specific to the cluster ID.
    {
    if ( pInPlugin && pInPlugin->pfnIncomingHdlr )
    {
    // The return value of the plugin function will be
    // ZSuccess - Supported and need default response
    // ZFailure - Unsupported
    // ZCL_STATUS_CMD_HAS_RSP - Supported and do not need default rsp
    // ZCL_STATUS_INVALID_FIELD - Supported, but the incoming msg is wrong formatted
    // ZCL_STATUS_INVALID_VALUE - Supported, but the request not achievable by the h/w
    // ZCL_STATUS_SOFTWARE_FAILURE - Supported but ZStack memory allocation fails
    status = pInPlugin->pfnIncomingHdlr( &inMsg );
    if ( status == ZCL_STATUS_CMD_HAS_RSP || ( interPanMsg && status == ZSuccess ) )
    {
    rawAFMsg = NULL;

    return ( ZCL_PROC_SUCCESS ); // We're done
    }
    }

    if ( status == ZFailure )

    if ( inMsg.hdr.fc.manuSpecific )
    {
    status = ZCL_STATUS_UNSUP_MANU_CLUSTER_COMMAND;
    }
    else
    {
    status = ZCL_STATUS_UNSUP_CLUSTER_COMMAND;
    }
    }
    }

    if ( UNICAST_MSG( inMsg.msg ) && inMsg.hdr.fc.disableDefaultRsp == 0 )
    {
    // Send a Default Response command back
    defautlRspCmd.statusCode = status;
    defautlRspCmd.commandID = inMsg.hdr.commandID;
    zcl_SendDefaultRspCmd( inMsg.msg->endPoint, &(inMsg.msg->srcAddr),
    inMsg.msg->clusterId, &defautlRspCmd,
    !inMsg.hdr.fc.direction, true,
    inMsg.hdr.manuCode, inMsg.hdr.transSeqNum );
    defaultResponseSent = TRUE;
    }

    rawAFMsg = NULL;
    if ( status == ZSuccess )
    {
    return ( ZCL_PROC_SUCCESS );
    }
    else if ( status == ZCL_STATUS_UNSUP_MANU_GENERAL_COMMAND )
    {
    if ( defaultResponseSent )
    {
    return ( ZCL_PROC_MANUFACTURER_SPECIFIC_DR );
    }
    else
    {
    return ( ZCL_PROC_MANUFACTURER_SPECIFIC );
    }
    }
    else
    {
    if ( defaultResponseSent )
    {
    return ( ZCL_PROC_NOT_HANDLED_DR );
    }
    else
    {
    return ( ZCL_PROC_NOT_HANDLED );
    }
    }
    }

    4) in zcl_sample<>.c file

    case ZCL_INCOMING_MSG:       // Incoming ZCL Foundation command/response messages

    zclSampleThermostat_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
    break;

     

    plz check it once and tell me sir what i am doing  wrong ? is any of my step is wrong?

     

    Thanks & Regards,

    Maneesh singh

  • Please check the following points:

    1) in OSAL_Sample<>.c

    const pTaskEventHandlerFn tasksArr[] =

    {...........

    ............

    zcl_event_loop,

    zclSampleThermostat_event_loop

    };

    2)  in zcl.c file

    uint16 zcl_event_loop( uint8 task_id, uint16 events )

    {............

    if ( *msgPtr == AF_INCOMING_MSG_CMD )

    {

        if(ZSuccess != (zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr )))

       {

           // send it to another task to process.

            osal_msg_send( zcl_RegisteredMsgTaskID, msgPtr );

           dealloc = FALSE;

      }

    }

    }

    3) in zcl_sample<>.c file

    case AF_INCOMING_MSG_CMD:
    case ZCL_INCOMING_MSG:       // Incoming ZCL Foundation command/response messages
    zclSampleXXX_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
    break;

    Then, set a breakpoint at zclSampleXXX_ProcessIncomingMsg and see if you can get it when a message is sent out to receiver.