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.

The Z-Stack-CC2530 gets RSSI from source to destination

Other Parts Discussed in Thread: Z-STACK, CC2530, CC2530EM

Dear all,

               I use Z-Stack-CC2530 to develop a position system.

               In SampleApp, I use pkt->rssi to read the RSSI.

               But, the RSSI is not between source and destination.

               How should I get RSSI from source to destination?

  • Hi,

    That depends on several scenarios, but my guess is you are following the next scenario:

    An End Device (with unknown position - in other words a bind node) broadcasting a message

    to nearest routers, then routers forward extracted RSSI values to concentrator node, where the

    position is calculated from received data (in case where concentrator node used as gateway,

    these calculations can be performed by the host)

    So if this is your scenario you can do the following to get true values of RSSI:

    1. Blind Node should broadcast a ZigBee application level message (it can be even a
      dummy message) to nearest routers (broadcast radius = 1, in this case no rebroadcasts
      will be carried out by the router)
    2. In each router that got the dummy message, extract the RSSI value, construct a new
      message that must contain at least two arguments; RSSI value and short address of the
      blind node. Send this message (fro each router participating in this carnival) to 
      concentrator node.
    3. In concentrator (or host PC) collect all the messages with RSSI values and then
      you are ready to do the math crunching :) 
  • Dear,

                 Sorry, I don't understand dummy message. 

                 I just use  a coordinator, a router and a end-device.

                 The end-device send a request to router. 

                 Then the router send a message to end-device.

                 After receive the message, the end-device extracts RSSI values, and construct a new message.

                 Finally, the end-device send the new message to coordinator.

                 I use above-mentioned method to extract RSSI values, but the RSSI values is not between router and end-device.

                 It is between router and coordinator.

                 

    I have two problems, now.

                 1.Is the method error?

                 2.How should I extract RSSI values between router and end-device or end-device and end-device? 

  • Hi,

    This method won't work with many routers, since all the messages addressed to end device must be

    routed through the parent, hence the wrong RSSI values in your case (probably the parent of the end

    device in your case is the coordinator).

    So basically, in this very simple network of yours (coordinator, one router and a single end device) you

    can ensure that the router will also act as parent (not coordinator):

    • Power on coordinator
    • Take some distance and power on the router
    • Ensure that the end device will be powered on while it's far enough from coordinator, but still
      close to router to join the network. In that way the end device will join to router instead of
      coordinator (check it with packet sniffer) 

    Dummy message is a message where the content of data is not important, what is important is the

    destination of this message, an address of the sending device and of course the RSSI value. 

  • Dear,

              I understand what you mean.

              Can one end-device join two router at one time?

              Because I need three reference node positioned one bind node.

              The reference node is router and the bind node is end-device. 

    Best regards,

  • Hi,

    It is impossible to join two router at one time.

  • Dear,

               OK, I see.

                I will try it.

                Thanks you for your answer and suggest.

  • Dear,

               Can I set  scan range of the router or the coordinator?

               If I can. How should I do?

               

  • Hi,

    What you mean by scan range?

  • Dear,

                             Assume the distance is 1m between the router and the end device.

                              The router can discover the end device and the end device join the router.

                              Can I set the distance between the router and the end device, in Z-Stack ?

                              I want to set the distance that the end device join the router.

      Best regards,

                Dennis

  • Hi,

    Well, there is no direct way that I'm aware of. The indirect way is to reduce

    You can read about changing transmit power of device in "Z-stack API.pdf"

    section 3.5.1

  • Dear,

                 I increase a router called in the zigbee network.

                 So, it has two router, one is R1 and the other is R2.

                 Now, the parent of the end device is the R1.

                  I can extract RSSI value between the R1 and the end device.

                  But, I can not extract RSSI values between the R2 and the end device.

    Best regards,

                     Dennis

                 

  • Hi,

    Well that is a normal behavior of ZigBee network, all messages addressed

    to a specific ZED will be routed to ZEDs parent, then the parent will send this

    message to ZED.

    So, your question is how to overcome this behavior?

    Well, one way is to implement the scenario I have described in my first post in

    this thread. You may try it. :)

  • Dear Igor,

      I have been try it.

     If the parent of end device is R1. I can extract RSSI values between the R1 and the end device. The RSSI values is right.

     But, when I extract RSSI values between the R2 and the end device, the RSSI values is error.

     If the parent of end device is R2. I can extract RSSI values between the R2 and the end device. The RSSI values is right, too.

     But, when I extract RSSI values between the R1 and the end device, the RSSI values is error, too.

      I need the RSSI measured the distance between R1 and end device, and  the distance between R2 and end device.  

     I have to extract RSSI values between R1 and end device, and between R2 and end device at one time.

     So, my question is how to get right RSSI values between R1 and end device, and between R2 and end device?

      I use CC2530 chip. The ZStack version is ZStack-CC2530-2.3.0-1.4.0.

      In the zigbee application layer, I use pkt->rssi to extract RSSI values.

     Best regards,

                Dennis                 

  • Hi,

    It sounds like the ZED isn't broadcasting this message, in other words, in your ZED project you should use

    AF_DataRequest() function as follows:

    RTR_App_DstAddr.addr.shortAddr = 0xFFFC; //Routers and coordinator
    RTR_App_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
    RTR_App_DstAddr.endPoint = RTR_ENDPOINT;

    AF_DataRequest( &RTR_App_DstAddr, &XZED_App_epDesc,
    RTR_APP_CLUSTERID,
    someLen,
    (byte *)message,
    &ZED_App_TransID,
    AF_DISCV_ROUTE | AF_SKIP_ROUTING,
    1 );

    Pay attention on lines marked with red:

    The destination address should be of broadcast type (0xFFFC or 0xFFFD)

    Addressing mode should be AddrBroadcast.

    In options field, AF_SKIP_ROUTING must be ORed with other options (this flag

    prevents from ZigBee to perform routing)

    Radius field should be set to 1 (that means no broadcasting beyond the first wave).

  • Dear Igor,

                       I think that the problem is the parent of end device.

                       I use zb_SendDataRequest()  function as follow:

    void zb_SendDataRequest ( uint16 destination, uint16 commandId, uint8 *pData, uint8 len, uint8 radius )
    {
    afAddrType_t dstAddr;
    /* 設置目的地址 */
    if (destination == 0xFFFF)
    {
    // 廣播
    dstAddr.addrMode = AddrBroadcast;
    dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR; //0xFFFF 資料封包將被傳送到網路中所有的設備
    dstAddr.endPoint = SampleApp_epDesc.endPoint;
    if ( AF_DataRequest( &dstAddr,
    &SampleApp_epDesc,
    commandId,
    len,
    pData,
    &SampleApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    {
    }
    else
    {

    // Error occurred in request to send.
    }
    }
    else if (destination == 0xFFFC)
    {
    dstAddr.addrMode = (afAddrMode_t)AddrBroadcast;;
    dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVZCZR; //0xFFFC 廣播給協調者和全部的路由器
    dstAddr.endPoint = SampleApp_epDesc.endPoint;
    if ( AF_DataRequest( &dstAddr,
    &SampleApp_epDesc,
    commandId,
    len,
    pData,
    &SampleApp_TransID,
    AF_DISCV_ROUTE | AF_SKIP_ROUTING,
    1 ) == afStatus_SUCCESS )
    {
    }
    }
    else
    {
    // 使用短位址
    dstAddr.addrMode = afAddr16Bit;
    dstAddr.addr.shortAddr = destination; //shortAddr 目標設備位址
    /* 設置端點 */
    dstAddr.endPoint = SampleApp_epDesc.endPoint;

    /* 發送消息 */
    if ( AF_DataRequest( &dstAddr,
    &SampleApp_epDesc,
    commandId,
    len,
    pData,
    &SampleApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    {
    }
    else
    {

    // Error occurred in request to send.
    }
    }
    }

    Best regards,

                  Dennis

  • Hi,

    It's very hard to understand this code without proper indentation.

    Please attach this code in a .c file

  • /**************************************************************************************************
      Filename:       SampleApp.c
      Revised:        $Date: 2009-03-18 15:56:27 -0700 (Wed, 18 Mar 2009) $
      Revision:       $Revision: 19453 $
    
      Description:    Sample Application (no Profile).
    
    
      Copyright 2007 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 application isn't intended to do anything useful, it is
      intended to be a simple example of an application's structure.
    
      This application sends it's messages either as broadcast or
      broadcast filtered group messages.  The other (more normal)
      message addressing is unicast.  Most of the other sample
      applications are written to support the unicast message model.
    
      Key control:
        SW1:  Sends a flash command to all devices in Group 1.
        SW2:  Adds/Removes (toggles) this device in and out
              of Group 1.  This will enable and disable the
              reception of the flash command.
    *********************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include "OSAL.h"
    #include "ZGlobals.h"
    #include "AF.h"
    #include "aps_groups.h"
    #include "ZDApp.h"
    #include <string.h>
    #include <stdlib.h>     
    #include <stdio.h>
    #include <math.h>
    #include "SampleApp.h"
    #include "SampleAppHw.h"
    
    #include "OnBoard.h"
    
    #include "mac_rx.h"
    
    /* HAL */
    #include "hal_lcd.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    // This list should be filled with Application specific Cluster IDs.
    const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] =
    {
      SAMPLEAPP_PERIODIC_CLUSTERID,
      SAMPLEAPP_FLASH_CLUSTERID,
      SAMPLEAPP_KAO_CLUSTERID,
      SAMPLEAPP_GAO_CLUSTERID,
      SAMPLEAPP_LQI_CLUSTERID,
      SAMPLEAPP_RSSI_CLUSTERID,
      SAMPLEAPP_RAdrr_All,
      SAMPLEAPP_KAO_LQI,
      SAMPLEAPP_KAO_RSSI,
      SAMPLEAPP_KAO_STH11,
      TAG_KAO_RSSI,
      RECEIVE_TAG_RSSI,
      RECEIVE_ID_RSSI
    };
    
    const SimpleDescriptionFormat_t SampleApp_SimpleDesc =
    {
      SAMPLEAPP_ENDPOINT,              //  int Endpoint;
      SAMPLEAPP_PROFID,                //  uint16 AppProfId[2];
      SAMPLEAPP_DEVICEID,              //  uint16 AppDeviceId[2];
      SAMPLEAPP_DEVICE_VERSION,        //  int   AppDevVer:4;
      SAMPLEAPP_FLAGS,                 //  int   AppFlags:4;
      SAMPLEAPP_MAX_CLUSTERS,          //  uint8  AppNumInClusters;
      (cId_t *)SampleApp_ClusterList,  //  uint8 *pAppInClusterList;
      SAMPLEAPP_MAX_CLUSTERS,          //  uint8  AppNumInClusters;
      (cId_t *)SampleApp_ClusterList   //  uint8 *pAppInClusterList;
    };
    
    // This is the Endpoint/Interface description.  It is defined here, but
    // filled-in in SampleApp_Init().  Another way to go would be to fill
    // in the structure here and make it a "const" (in code space).  The
    // way it's defined in this sample app it is define in RAM.
    endPointDesc_t SampleApp_epDesc;
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    uint8 SampleApp_TaskID;   // Task ID for internal task/event processing
                              // This variable will be received when
                              // SampleApp_Init() is called.
    devStates_t SampleApp_NwkState;
    
    uint8 SampleApp_TransID;  // This is the unique message ID (counter)
    
    afAddrType_t SampleApp_Periodic_DstAddr;
    afAddrType_t SampleApp_Flash_DstAddr;
    
    aps_Group_t SampleApp_Group;
    
    uint8 SampleAppPeriodicCounter = 0;
    uint8 SampleAppFlashCounter = 0;
    
    uint8 len; // the transmit data length
    byte TransmitApp_Msg[ TRANSMITAPP_MAX_DATA_LEN ]; // Transmit message array
    appCmd mAppCmd;
    uint8 tmpAdrr[4];
    uint8 mOtaRx[20];
    uint8 mOtaTx[20];
    uint16 Addr_Char[4];
    uint16 TraAddr10;
    uint8 m0rssi[4];
    
    
    
    #if defined ( GAO_MASTER )
      uint8 DeviceType[] = {'I','D','0','0'};
      uint8 DeviceType1[] = {'I','D','0','1'};
      uint8 DeviceType2[] = {'I','D','0','2'};
      uint8 DeviceType3[] = {'I','D','0','3'};
    #endif
    #if defined ( GAO_TAG )
      uint8 DeviceType[] = {'I','D','0','0'};
      uint8 DeviceType1[] = {'I','D','0','1'};
      uint8 DeviceType2[] = {'I','D','0','2'};
      uint8 DeviceType3[] = {'I','D','0','3'};
      uint8 RefNode[] = {'R','N','0','1'};
      uint8 RefNode1[] = {'R','N','0','2'};
      uint8 RefNode2[] = {'R','N','0','3'};
    #endif
    #if defined ( GAO_END1)
      uint8 DeviceType[] = {'I','D','0','1'};
      uint8 RefNode[] = {'R','N','0','1'};
    #endif  
    #if defined (GAO_END2 )
      uint8 DeviceType[] = {'I','D','0','2'};
      uint8 RefNode1[] = {'R','N','0','2'};
    #endif
    #if defined (GAO_END3 )
      uint8 DeviceType[] = {'I','D','0','3'};
      uint8 RefNode2[] = {'R','N','0','3'};
    #endif  
      
    char Rssi, crc, j = 0;
    
    static macRx_t  * pRxBuf;
    
    #define MAC_RADIO_RSSI_OFFSET HAL_MAC_RSSI_OFFSET
    
    #define RSSI_OFFSET 73
    
    #define n  3.5
    #define A  49 
    #define col 1
    #define row 2
    #define mid 2
    
    
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    void SampleApp_HandleKeys( uint8 shift, uint8 keys );
    void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
    void SampleApp_SendPeriodicMessage( void );
    void SampleApp_SendFlashMessage( uint16 flashTime );
    void gaoAdrr( void );
    void gaoRssi( void );
    void zb_SendDataRequest ( uint16 destination, uint16 commandId, uint8 *pData, uint8 len, uint8 radius );
    void get_rssi (afIncomingMSGPacket_t *pkt);
    void get_Lqi (afIncomingMSGPacket_t *pkt);
    extern uint8 Mac_rssi;
    extern uint8 rssiDbm;
    /*********************************************************************
     * NETWORK LAYER CALLBACKS
     */
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SampleApp_Init
     *
     * @brief   Initialization function for the Generic App Task.
     *          This is called during initialization and should contain
     *          any application specific initialization (ie. hardware
     *          initialization/setup, table initialization, power up
     *          notificaiton ... ).
     *
     * @param   task_id - the ID assigned by OSAL.  This ID should be
     *                    used to send messages and set timers.
     *
     * @return  none
     */
    void SampleApp_Init( uint8 task_id )
    {
      SampleApp_TaskID = task_id;
      SampleApp_NwkState = DEV_INIT;
      SampleApp_TransID = 0;
    
      // Device hardware initialization can be added here or in main() (Zmain.c).
      // If the hardware is application specific - add it here.
      // If the hardware is other parts of the device add it in main().
    
     #if defined ( BUILD_ALL_DEVICES )
      // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START
      // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered
      // together - if they are - we will start up a coordinator. Otherwise,
      // the device will start as a router.
      if ( readCoordinatorJumper() )
        zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
      else
        zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;
    #endif // BUILD_ALL_DEVICES
    
    #if defined ( HOLD_AUTO_START )
      // HOLD_AUTO_START is a compile option that will surpress ZDApp
      //  from starting the device and wait for the application to
      //  start the device.
      ZDOInitDevice(0);
    #endif
    
      // Setup for the periodic message's destination address
      // Broadcast to everyone
      SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
      SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;
    
      // Setup for the flash command's destination address - Group 1
      SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
      SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
    
      // Fill out the endpoint description.
      SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_epDesc.task_id = &SampleApp_TaskID;
      SampleApp_epDesc.simpleDesc
                = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;
      SampleApp_epDesc.latencyReq = noLatencyReqs;
    
      // Register the endpoint description with the AF
      afRegister( &SampleApp_epDesc );
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( SampleApp_TaskID );
    
      // By default, all devices start out in Group 1
      SampleApp_Group.ID = 0x0001;
      osal_memcpy( SampleApp_Group.name, "Group 1", 7  );
      aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
    
    #if defined ( GAO_UART ) 
      halUARTCfg_t uartConfig;
      uartConfig.configured           = TRUE;              // 2x30 don't care - see uart driver.
      uartConfig.baudRate             = SERIAL_APP_BAUD;
      uartConfig.flowControl          = TRUE;
      uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.
      uartConfig.rx.maxBufSize        = SERIAL_APP_RX_SZ;  // 2x30 don't care - see uart driver.
      uartConfig.tx.maxBufSize        = SERIAL_APP_TX_SZ;  // 2x30 don't care - see uart driver.
      uartConfig.idleTimeout          = SERIAL_APP_IDLE;   // 2x30 don't care - see uart driver.
      uartConfig.intEnable            = TRUE;              // 2x30 don't care - see uart driver.
      uartConfig.callBackFunc         = zclUARTMsg_CallBack;
      HalUARTOpen (SERIAL_APP_PORT, &uartConfig);
    #endif
      
    
    }
    
    /*********************************************************************
     * @fn      SampleApp_ProcessEvent
     *
     * @brief   Generic Application Task event processor.  This function
     *          is called to process all events for the task.  Events
     *          include timers, messages and any other user defined events.
     *
     * @param   task_id  - The OSAL assigned task ID.
     * @param   events - events to process.  This is a bit map and can
     *                   contain more than one event.
     *
     * @return  none
     */
    uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
      (void)task_id;  // Intentionally unreferenced parameter
    
      if ( events & SYS_EVENT_MSG )
      {
        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
        while ( MSGpkt )
        {
          switch ( MSGpkt->hdr.event )
          {
            // Received when a key is pressed
            case KEY_CHANGE:
              SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
            // Received when a messages is received (OTA) for this endpoint
            case AF_INCOMING_MSG_CMD:
              SampleApp_MessageMSGCB( MSGpkt );
              break;
    
            // Received whenever the device changes state in the network
            case ZDO_STATE_CHANGE:
              SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
              if ( (SampleApp_NwkState == DEV_ZB_COORD)
                  || (SampleApp_NwkState == DEV_ROUTER)
                  || (SampleApp_NwkState == DEV_END_DEVICE) )
              {
                gaoAdrr();
                //gaoRssi();
                //int8 msgRssi = MSGpkt->rssi;
                //uint8 msgCorrelation = MSGpkt->correlation;
    
                osal_start_timerEx( SampleApp_TaskID,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
              }
              else
              {
                // Device is no longer in the network
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
    
          // Next - if one is available
          MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      // Send a message out - This event is generated by a timer
      //  (setup in SampleApp_Init()).
      if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
      {
      
        #if defined (GAO_TAG)
         if ( j == 0){
           for ( int i = 0 ; i < 4 ; i++){
           mOtaTx[i] = DeviceType1[i];
            }
           }
           else if ( j == 1){
           for ( int i = 0 ; i < 4 ; i++){
           mOtaTx[i] = DeviceType2[i];
            }
           }
           else if ( j == 2){
           for ( int i = 0 ; i < 4 ; i++){
           mOtaTx[i] = DeviceType3[i];
            }
           }
           j++;
           zb_SendDataRequest( 0xFFFC, TAG_KAO_RSSI, mOtaTx ,4, 1);
           if ( j > 2)
             j = 0;
         /*
         for ( i = 0 ; i < 4 ; i++){
           mOtaTx[i+4] = DeviceType1[i];
           zb_SendDataRequest( 0xFFFF, TAG_KAO_RSSI, mOtaTx ,4);
         }
         for (i = 0 ; i < 4 ; i++){
           mOtaTx[i+8] = DeviceType2[i];
           zb_SendDataRequest( 0xFFFF, TAG_KAO_RSSI, mOtaTx ,4);
         }
        */
         osal_start_timerEx( SampleApp_TaskID,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
    
        #endif
      
        // Setup to send message again in normal period (+ a little jitter)
    /*
        osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
            (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );*/
        // return unprocessed events
        return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
      }
      
      
    if ( events & UART_MSG_EVT ) 
    {
    #if defined ( GAO_UART )
        osal_memcpy(&mAppCmd, &TransmitApp_Msg, 18);
        switch ( mAppCmd.Head ){
        case '?':
          zb_SendDataRequest( 0xFFFF, SAMPLEAPP_RAdrr_All, "1" ,1, 1);
         break;
        case '&':
          for(int i = 0; i<4; i++){
              switch(mAppCmd.Sadrr[i]){
                case '0':
                  Addr_Char[i] = 0;
                  break;
                case '1':
                  Addr_Char[i] = 1;
                  break;
                case '2':
                  Addr_Char[i] = 2;
                  break;
                case '3':
                  Addr_Char[i] = 3;
                  break;
                case '4':
                  Addr_Char[i] = 4;
                  break;
                case '5':
                  Addr_Char[i] = 5;
                  break;
                case '6':
                  Addr_Char[i] = 6;
                  break;
                case '7':
                  Addr_Char[i] = 7;
                  break;
                case '8':
                  Addr_Char[i] = 8;
                  break;
    
                case '9':
                  Addr_Char[i] = 9;
                  break;
                case 'A':
                  Addr_Char[i] = 10;
                  break;
                case 'B':
                  Addr_Char[i] = 11;
                  break;
                case 'C':
                  Addr_Char[i] = 12;
                  break;
                case 'D':
                  Addr_Char[i] = 13;
                  break;
                case 'E':
                  Addr_Char[i] = 14;
                  break;
                case 'F':
                  Addr_Char[i] = 15;
                  break;
              }
              TraAddr10 = Addr_Char[0]*4096+Addr_Char[1]*256+Addr_Char[2]*16+Addr_Char[3];
            }
          if(mAppCmd.HeadCmd[0] == 'C' &
               mAppCmd.HeadCmd[1] == 'I' &
               mAppCmd.HeadCmd[2] == 'O' ){
                  zb_SendDataRequest( TraAddr10, SAMPLEAPP_KAO_LQI, mAppCmd.DataBuf ,3, 1);
            }
            
            if(mAppCmd.HeadCmd[0] == 'R' &
               mAppCmd.HeadCmd[1] == 'S' &
               mAppCmd.HeadCmd[2] == 'S' ){
                  zb_SendDataRequest( TraAddr10, SAMPLEAPP_KAO_RSSI, mAppCmd.DataBuf ,3, 1);
            }
            break;
      }
        //HalUARTWrite(SERIAL_APP_PORT,"OK", 2);   
        
    #if defined ( GAO_MASTER )   
        HalUARTWrite(SERIAL_APP_PORT,TransmitApp_Msg, 18);
        if ( strcmp(TransmitApp_Msg,"SWO2")==0 )
         {
          zb_SendDataRequest( 0xFFFF, SAMPLEAPP_KAO_CLUSTERID, "SWO2" ,4, 1);
          //HalUARTWrite(SERIAL_APP_PORT,"OK", 2);
         }
        if ( strcmp(TransmitApp_Msg,"SWC2")==0 ) 
         {
        //HalUARTWrite(SERIAL_APP_PORT,TransmitApp_Msg, 18);
         zb_SendDataRequest( 0xFFFF, SAMPLEAPP_GAO_CLUSTERID, "SWC2" ,4, 1);
         //HalUARTWrite(SERIAL_APP_PORT,"OK", 2);
         }
        if ( strcmp(TransmitApp_Msg,"LQI")==0 )
         {
           zb_SendDataRequest( 0xFFFF, SAMPLEAPP_LQI_CLUSTERID, "LQI:" ,4, 1);
         }
        if ( strcmp(TransmitApp_Msg,"RSSI")==0 )
         {
           zb_SendDataRequest( 0xFFFF, TAG_KAO_RSSI, "ID01" ,4, 1);  
         } 
       
    #endif  
        #if defined ( GAO_TAG )   
        HalUARTWrite(SERIAL_APP_PORT,TransmitApp_Msg, 18);
        if ( strcmp(TransmitApp_Msg,"SWO2")==0 )
         {
          zb_SendDataRequest( 0xFFFF, SAMPLEAPP_KAO_CLUSTERID, "SWO2" ,4, 1);
          //HalUARTWrite(SERIAL_APP_PORT,"OK", 2);
         }
        if ( strcmp(TransmitApp_Msg,"SWC2")==0 ) 
         {
        //HalUARTWrite(SERIAL_APP_PORT,TransmitApp_Msg, 18);
         zb_SendDataRequest( 0xFFFF, SAMPLEAPP_GAO_CLUSTERID, "SWC2" ,4, 1);
         //HalUARTWrite(SERIAL_APP_PORT,"OK", 2);
         }
        if ( strcmp(TransmitApp_Msg,"LQI")==0 )
         {
           zb_SendDataRequest( 0xFFFF, SAMPLEAPP_LQI_CLUSTERID, "LQI:" ,4, 1);
         }
        if ( strcmp(TransmitApp_Msg,"RSSI")==0 )
         {
           zb_SendDataRequest( 0xFFFF, TAG_KAO_RSSI, "ID01" ,4, 1);  
         } 
       
    #endif  
        
     /*   
        switch(mAppCmd.Head){
          case '?':
         zb_SendDataRequest( 0x796F, SampleTestApp_PERIODIC_CLUSTERID, "1" ,1);
         HalUARTWrite(SERIAL_APP_PORT,"123456789", 9);
          break;
           }
     */  
    /*
        if(strcmp(TransmitApp_Msg,"RFID")==0)
         {
         HalUARTWrite(SERIAL_APP_PORT,"OK", 2);
         }
        else
        {
        //HalUARTWrite(SERIAL_APP_PORT,TransmitApp_Msg, 18);
        zb_SendDataRequest( 0xFFFF, SampleTestApp_PERIODIC_CLUSTERID, TransmitApp_Msg ,18);
        for(TransmitApp_Msg[0]=18;TransmitApp_Msg[0]>0;TransmitApp_Msg[TransmitApp_Msg[0]--]='\0');
        }
    
        if(strcmp(mAppCmd.DataBuf,"1234567891")==0)
         {
         HalUARTWrite(SERIAL_APP_PORT,"DataBuf", 7);
         }
    
     */  
    for(TransmitApp_Msg[0]=18;TransmitApp_Msg[0]>0;TransmitApp_Msg[TransmitApp_Msg[0]--]='\0');  
        
    #endif
    
        return ( events ^ UART_MSG_EVT );
      }  
      
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * Event Generation Functions
     */
    /*********************************************************************
     * @fn      SampleApp_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_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    void SampleApp_HandleKeys( uint8 shift, uint8 keys )
    {
      zAddrType_t dstAddr;
      (void)shift;  // Intentionally unreferenced parameter
      //NLDE_Signal_t *KAOpkt; 
       if ( keys & HAL_KEY_SW_6 )
        {
          HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
    
       // Initiate an End Device Bind Request for the mandatory endpoint 
          dstAddr.addrMode = Addr16Bit; 
          dstAddr.addr.shortAddr = 0x0000; // Coordinator 
          ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(), 
                                SampleApp_epDesc.endPoint, 
                                SAMPLEAPP_PROFID, 
                                SAMPLEAPP_MAX_CLUSTERS, (cId_t *)SampleApp_ClusterList,  SAMPLEAPP_MAX_CLUSTERS, (cId_t *)SampleApp_ClusterList,  FALSE ); 
    
        #if defined (GAO_END1) 
        //HalLedSet (HAL_LED_1, HAL_LED_MODE_ON);
        //HalLedBlink( HAL_LED_1, 5, 50, 1000 );
          //HAL_TURN_ON_LED1();
        //HalUARTWrite( SERIAL_APP_PORT, "123", 3 );
        //int8 msgRssi = KAOpkt->rssi;
        //uint8 msgCorrelation = KAOpkt->correlation;
        
         //osal_stop_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT );
        /* This key sends the Flash Command is sent to Group 1.
         * This device will not receive the Flash Command from this
         * device (even if it belongs to group 1).
         */
        //SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION );
        #endif
     /*   
      #if defined ( GAO_END2)
       zb_SendDataRequest(0,SAMPLEAPP_GAO_CLUSTERID, "hello Dennis", 12);
       HalLedBlink( HAL_LED_1, 4, 50, 1000 );  
      #endif
         */
      } 
    }
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SampleApp_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
     */
    void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
    {
      uint16 flashTime;
      uint8 Rssi,times;
      //uint8 LQI;
      //uint8 tmpLen;
      uint8 str_1[ ]="Lqi:";
      uint8 str_2[ ]="Rssi_dBm:-";
      uint8 Lqibuf[3];
      uint8 Rssibuf[2];
      int8 msgRssi,temp;
      uint8 temp2;
      uint8 temp3;
      uint8 RSSI_buf[2];
      uint8 LQI_buf[3];
      uint8 temp_buf[2];
      uint8 sort[2];
      int16 rssi_dBm;
      uint8 X[2];
      uint8 Y[2];
      uint16 S[2][3];
      double d[3];
      double L[3];
      int x[3]={1,2,3};
      int y[3]={1,2,1};
      double q,p;
      int i,j,g,k;
      NLDE_Signal_t *NLDEpkt;
      macTxIntData_t *macTxpkt;
      macDataInd_t *macDatapkt;
      macMcpsDataCnf_t *macMCpspkt;
      ZMacDataCnf_t *ZMacpkt;
      //char *rstr1, *rstr2;
     
      
      for(i=0;i<pkt->cmd.DataLength;i++)
      mOtaRx[i] = pkt->cmd.Data[i];
      switch ( pkt->clusterId )
      {
        case SAMPLEAPP_PERIODIC_CLUSTERID:
          break;
    
        case SAMPLEAPP_FLASH_CLUSTERID:
          flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
          HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
          break;
          
          
        case SAMPLEAPP_KAO_CLUSTERID:
    #if defined (GAO_END1)
         HalLedSet( HAL_LED_2, HAL_LED_MODE_ON);
         zb_SendDataRequest( 0, SAMPLEAPP_KAO_CLUSTERID, "open" ,4, 1);
    #endif
    #if defined ( GAO_MASTER )    
        for(int i = 0; i < 3; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
             }
        HalUARTWrite(SERIAL_APP_PORT, mOtaRx, pkt->cmd.DataLength);
    #endif 
         break;
         
        case SAMPLEAPP_GAO_CLUSTERID:
    #if defined (GAO_END1)
         HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF);
         zb_SendDataRequest( 0, SAMPLEAPP_GAO_CLUSTERID, "close" ,5, 1);
    #endif
         
          
    /*     
    #if defined ( GAO_END1 )        
        //zb_SendDataRequest(0,SAMPLEAPP_KAO_CLUSTERID, tmpAdrr, 4);
        //if ( strcmp(mOtaRx,"123")==0)
        //HalLedBlink( HAL_LED_1, 4, 50, 1000 ); 
         for(int i = 0; i < 3; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
          }
          if(mOtaRx[0] == 'P' & mOtaRx[1] == '2' & mOtaRx[2] == 'O' ){
            HalLedSet( HAL_LED_2, HAL_LED_MODE_ON);
          }
          if(mOtaRx[0] == 'P' & mOtaRx[1] == '2' & mOtaRx[2] == 'C' ){
            HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF);
          }
    #endif    
    */     
       #if defined ( GAO_MASTER )   
         for(int i = 0; i < 4; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
             }
            HalUARTWrite(SERIAL_APP_PORT, mOtaRx, pkt->cmd.DataLength);
       #endif 
        break; 
       
        case SAMPLEAPP_LQI_CLUSTERID:
          #if defined (GAO_END1)
           HalLedBlink( HAL_LED_1, 4, 50, 1000 );
           //uint8 msgLqi = pkt->LinkQuality;
           //err = (uint32)(msgRssi);
           LQI_buf[0]=pkt->LinkQuality/100+48;
           LQI_buf[1]=(pkt->LinkQuality%100)/10+48;
           LQI_buf[2]=pkt->LinkQuality%10+48;
          // _ltoa( msgLqi, Lqibuf, 16 );
          
          zb_SendDataRequest ( 0, SAMPLEAPP_LQI_CLUSTERID, LQI_buf, pkt->cmd.DataLength, 1);
            
           
           //zb_SendDataRequest( 0, SAMPLEAPP_LQI_CLUSTERID, pkt->LinkQuality ,1 );
          #endif
           
          #if defined ( GAO_MASTER )
            for(int i = 0; i < 3; i++){
              mOtaRx[i] = pkt->cmd.Data[i];
             }
             //mOtaRx[0] > mOtaRx2[0] ? sort[0] = mOtaRx[0] : sort[0] = mOtaRx2[0];
            //int8 msgRssi = pkt->rssi;
            //buf[msgRssi] = ' ';
            //err = (uint32)(msgRssi);
            //_ltoa( err, &buf[msgRssi], 10 );
            //HalLcdWriteStringValue( "RSSI: ", msgRssi, 10, HAL_LCD_LINE_1 );
            HalUARTWrite(SERIAL_APP_PORT, str_1 , 4);
            HalUARTWrite(SERIAL_APP_PORT, mOtaRx , 3);
            //HalUARTWrite(0, mOtaRx , pkt->cmd.DataLength);
          #endif 
        break;
        
       case SAMPLEAPP_RSSI_CLUSTERID:
        #if defined (GAO_END1)
           HalLedBlink( HAL_LED_2, 4, 50, 1000 );
           for(int i = 0; i < 2; i++){
              mOtaRx[i] = pkt->cmd.Data[i];
             }
           temp_buf[0] = mOtaRx[0];
           temp_buf[1] = mOtaRx[1];
           //pRxBuf->mac.rssi = rssiDbm - 255;
           //uint8 msgRssi = pkt->rssi - 1;
           //get_rssi(pkt);
           //msgRssi = msgRssi - 255;
           //err = (uint32)(msgRssi);
           //RSSI_buf[0]=((uint8)(~(pkt->rssi)+1))/10+48;
           //RSSI_buf[1]=((uint8)(~(pkt->rssi)))%10+48;
           //RSSI_buf[0]=((uint8)(~(pkt->rssi)+1))/100+48;
           //RSSI_buf[1]=((uint8)(~(pkt->rssi))%100)/10+48;
           //RSSI_buf[2]=((uint8)(~(pkt->rssi)))%10+48;
           //RSSI_buf >= 128 ? (RSSI_buf-256)/2 : ((RSSI_buf)/2) - RSSI_OFFSET;
           //RSSI_buf[0]=((uint8)(~(pRxBuf->mac.rssi)+1))/10+48;
           //RSSI_buf[1]=((uint8)(~(pRxBuf->mac.rssi)))%10+48;
           //_ltoa( msgRssi, Rssi, 10 );
          /*
           int8 rssi_dec = pkt->rssi;
           if (rssi_dec >= 128){
             rssi_dBm = (int16) ((rssi_dec - 256) / 2) - RSSI_OFFSET;
           }
          else{
             rssi_dBm = (rssi_dec / 2) - RSSI_OFFSET;
          }
         */
          //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, "ID01", 4); 
          //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, temp_buf,pkt->cmd.DataLength);
            
           //zb_SendDataRequest( 0, SAMPLEAPP_LQI_CLUSTERID, pkt->LinkQuality ,1 );
          #endif
          
         #if defined ( GAO_MASTER )
           
            for(i = 0; i < 6; i++){
              mOtaRx[i] = pkt->cmd.Data[i];
             }
            if (mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '1'){
              //rstr1 = &mOtaRx[4];
              //rstr2 = &mOtaRx[5];
              temp = mOtaRx[4]*10+mOtaRx[5];
              d[0]=pow(10,(fabs(temp)-A)/(10*n));
              g++;
            }
           else if (mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '2'){
              temp = mOtaRx[4]*10+mOtaRx[5];
              d[1]=pow(10,(fabs(temp)-A)/(10*n));
              g++;
            }
            else if (mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '2'){
              temp = mOtaRx[4]*10+mOtaRx[5];
              d[2]=pow(10,(fabs(temp)-A)/(10*n));
              g++;
            }
             //d[k]=pow(10,(fabs(sort[k])-A)/(10*n));
            
            if ( g == 3){
              g = 0;
            for (i =0 ; i < 2 ; i++){
                X[i]=2*(x[i+1]-x[i]);
                Y[i]=2*(y[i+1]-y[i]);
                L[i]=-pow(x[i],2)-pow(y[i],2)+pow(d[i],2)+pow(x[i+1],2)+pow(y[i+1],2)-pow(d[i+1],2);
                S[i][0] = X[i];
                S[i][1] = Y[i];
                S[i][2] = L[i];
            }
            //�p�ߤ�{�����Ѫk(�줦�B�����k)
            for (k = 0; k < 2 ; k++){
              p = S[k][k];
              for ( j = k ; j < 3 ; j++)
                S[k][j] = S[k][j]/p;
              for (i = 0 ; i < 2 ; i++){
                if ( i != k){
                  q = S[i][k];
                  for ( j = k ; j < 3 ; j++)
                  S[i][j] = S[i][j] - q*S[k][j];
                  _ltoa (S[i][j], &sort[i], 10);
                }
            }
             //sort[0] = S[0][0]+0x30;
             //sort[1] = S[1][0]+0x30;
        }
      }  
            
            //_itoa( temp, Rssi, 10 );
        /*
            k=6-1;
            while ( k != 0){
              times = 0;
              for (int i = 0; i <= k-1; i++){
                if ( sort[i] > sort[i+1]){
                  temp = sort[i]; sort[i] = sort[i+1]; sort[i+1]=temp;
                  times = 1;
             }
            }
             k =times;
            }
         */
            //int8 msgRssi = pkt->rssi;
            //buf[msgRssi] = ' ';
            //err = (uint32)(msgRssi);
            //_ltoa( err, &buf[msgRssi], 10 );
            //HalLcdWriteStringValue( "RSSI: ", msgRssi, 10, HAL_LCD_LINE_1 );
            //HalUARTWrite(SERIAL_APP_PORT, str_2 , 10);
            //HalUARTWrite(SERIAL_APP_PORT, sort , pkt->cmd.DataLength);
      
          #endif  
        break;  
        
       case SAMPLEAPP_KAO_LQI:
        #if defined (GAO_END1)
         mOtaTx[0] = '$';
         for(int i = 0; i < 4; i++){
          mOtaTx[i+1] = tmpAdrr[i];
          }
         LQI_buf[0]=pkt->LinkQuality/100+48;
         LQI_buf[1]=(pkt->LinkQuality%100)/10+48;
         LQI_buf[2]=pkt->LinkQuality%10+48;
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_LQI, mOtaTx, 5, 1);
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_LQI, str_1 , 4, 1);
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_LQI, LQI_buf, pkt->cmd.DataLength, 1);
        #endif  
        #if defined ( GAO_MASTER )
            for(int i = 0; i < 12; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
             }        
            HalUARTWrite(SERIAL_APP_PORT, mOtaRx , pkt->cmd.DataLength);
        #endif
       break;
       
       case SAMPLEAPP_KAO_RSSI:
        #if defined (GAO_END1)
            HalLedBlink( HAL_LED_2, 2, 50, 1000 );
            temp = pkt->rssi;
            temp2 = 255 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
           }
            //RSSI_buf[0]=((uint8)(~Mac_rssi+1))/10+48;
            //RSSI_buf[1]=((uint8)(~Mac_rssi+1))%10+48;
            //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, "ID01", 4);
            //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, RSSI_buf, pkt->cmd.DataLength); 
         /*
         mOtaTx[0] = '$';
         for(int i = 0; i < 4; i++){
            mOtaTx[i+1] = tmpAdrr[i];
         }
         RSSI_buf[0]=((uint8)(~(pkt->rssi)+1))/10+48;
         RSSI_buf[1]=((uint8)(~(pkt->rssi)))%10+48;
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_RSSI, mOtaTx, 5);
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_RSSI, str_2, 10);
         zb_SendDataRequest ( 0, SAMPLEAPP_KAO_RSSI, RSSI_buf, pkt->cmd.DataLength);
         */
        #endif
        #if defined ( GAO_MASTER )
            for(int i = 0; i < 17; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
             }
            HalUARTWrite(SERIAL_APP_PORT, mOtaRx , pkt->cmd.DataLength);
            //HalUARTWrite(SERIAL_APP_PORT, str_2 , 10);
        #endif  
        break;   
       case SAMPLEAPP_RAdrr_All:
        #if defined ( GAO_MASTER )
          for(int i = 0; i < 9; i++){
          mOtaRx[i] = pkt->cmd.Data[i];
          }
          HalUARTWrite(SERIAL_APP_PORT, mOtaRx, 9);
        #endif
        #if defined ( GAO_END1 )
          mOtaTx[0] = '$';
          for(int i = 0; i < 4; i++){
           mOtaTx[i+1] = DeviceType[i];
          }
          for(int i = 0; i < 4; i++){
          mOtaTx[i+5] = tmpAdrr[i];
          }
          zb_SendDataRequest ( 0, SAMPLEAPP_RAdrr_All, mOtaTx, 9, 1);
        #endif      
          #if defined ( GAO_TAG )
          mOtaTx[0] = '$';
          for(int i = 0; i < 4; i++){
           mOtaTx[i+1] = DeviceType[i];
          }
          for(int i = 0; i < 4; i++){
          mOtaTx[i+5] = tmpAdrr[i];
          }
          zb_SendDataRequest ( 0, SAMPLEAPP_RAdrr_All, mOtaTx, 9, 1);
        #endif
          #if defined ( GAO_END2 )
          mOtaTx[0] = '$';
          for(int i = 0; i < 4; i++){
           mOtaTx[i+1] = DeviceType[i];
          }
          for(int i = 0; i < 4; i++){
          mOtaTx[i+5] = tmpAdrr[i];
          }
          zb_SendDataRequest ( 0, SAMPLEAPP_RAdrr_All, mOtaTx, 9, 1);
        #endif      
          #if defined ( GAO_END3 )
          mOtaTx[0] = '$';
          for(int i = 0; i < 4; i++){
           mOtaTx[i+1] = DeviceType[i];
          }
          for(int i = 0; i < 4; i++){
          mOtaTx[i+5] = tmpAdrr[i];
          }
          zb_SendDataRequest ( 0, SAMPLEAPP_RAdrr_All, mOtaTx, 9, 1);
        #endif      
          break;
        case SAMPLEAPP_KAO_STH11:
         #if defined ( GAO_MASTER )
          for(int i = 0; i < 15; i++){
          mOtaRx[i] = pkt->cmd.Data[i];
          }
          HalUARTWrite(SERIAL_APP_PORT, mOtaRx, 15);
         #endif
          
         #if defined ( GAO_END1 )
          for(int i = 0; i < 3; i++){
            mOtaRx[i] = pkt->cmd.Data[i];
          }
          if(mOtaRx[0] == 'T' & mOtaRx[1] == 'H' & mOtaRx[2] == '0' ){
            zb_SendDataRequest ( 0, SAMPLEAPP_KAO_STH11, "123", 3, 1);
          }
         #endif
          break;
       case TAG_KAO_RSSI:
         #if defined (GAO_END1)
         HalLedBlink( HAL_LED_2, 2, 50, 1000 );
         for (int i =0 ; i < 4 ; i++){
           mOtaRx[i] = pkt->cmd.Data[i];
         }
         if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '1'){
           for (int i =0 ; i < 4 ; i++){
           mOtaTx[i] = RefNode[i];
          }
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) &0x0F);
            RSSI_buf[1] = (uint8)(temp2 & 0x0F);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              //osal_memcpy(&temp_buf, &RSSI_buf, 2);
              //mOtaRx[i+4] = RSSI_buf[i];
           }
            //RSSI_buf[0]=((uint8)(~Mac_rssi+1))/10+48;
            //RSSI_buf[1]=((uint8)(~Mac_rssi+1))%10+48;
            zb_SendDataRequest (0xFFFF, RECEIVE_ID_RSSI,  mOtaTx, 4, 1);
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI,  mOtaTx, 4); 
          }
         #endif
         #if defined (GAO_END2)
         HalLedBlink( HAL_LED_2, 2, 50, 1000 );
         for (int i =0 ; i < 4 ; i++){
           mOtaRx[i] = pkt->cmd.Data[i];
         }
         if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '2'){
            for (int i =0 ; i < 4 ; i++){
            mOtaTx[i] = RefNode1[i];
          }
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              mOtaTx[i+4] = RSSI_buf[i];
           }
            zb_SendDataRequest (0xFFFF, RECEIVE_ID_RSSI,  mOtaTx, 6, 1);
            //RSSI_buf[0]=((uint8)(~Mac_rssi+1))/10+48;
            //RSSI_buf[1]=((uint8)(~Mac_rssi+1))%10+48;
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI, "ID02", 4);
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI, RSSI_buf, pkt->cmd.DataLength);
          }
         #endif
         #if defined (GAO_END3)
         HalLedBlink( HAL_LED_2, 2, 50, 1000 );
         for (int i =0 ; i < 4 ; i++){
           mOtaRx[i] = pkt->cmd.Data[i];
         }
         if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '3'){
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              mOtaTx[i+4] = RSSI_buf[i];
           }
            zb_SendDataRequest (0, RECEIVE_TAG_RSSI,  mOtaTx, 6, 1);
            //RSSI_buf[0]=((uint8)(~(pkt->rssi)+1))/10+48;
            //RSSI_buf[1]=((uint8)(~(pkt->rssi)))%10+48;
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI, "ID03", 4);
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI, RSSI_buf, pkt->cmd.DataLength);
          }
         #endif
         /*
         #if defined ( GAO_TAG )
          HalLedBlink( HAL_LED_2, 2, 50, 1000 );
          for(int i = 0; i < 4; i++){
           mOtaRx[i] = pkt->cmd.Data[i];
          }
          if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '1'){
            for(int i = 0; i < 4; i++){
              mOtaTx[i] = RefNode[i];
            }
            temp2 = pkt->LinkQuality;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
           }
            zb_SendDataRequest ( 0xFFFF, TAG_KAO_RSSI, mOtaTx, 4);
            //zb_SendDataRequest ( 0xFFFF, TAG_KAO_RSSI, RSSI_buf, 2);
          }
          if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '2'){
            for(int i = 0; i < 4; i++){
              mOtaTx[i] = RefNode1[i];
            }
          }
          if(mOtaRx[0] == 'I' & mOtaRx[1] == 'D' & mOtaRx[2] == '0' & mOtaRx[3] == '3'){
            for(int i = 0; i < 4; i++){
              mOtaTx[i] = RefNode2[i];
            }
          }
         
         #endif
         */
       break; 
       case RECEIVE_ID_RSSI:
        #if defined ( GAO_TAG )
          HalLedBlink( HAL_LED_2, 2, 50, 1000 );
          for(int i = 0; i < 4; i++){
           mOtaRx[i] = pkt->cmd.Data[i];
          }
          //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, mOtaRx, 6);
          //HalUARTWrite(SERIAL_APP_PORT, mOtaRx , 6);
          if(mOtaRx[0] == 'R' & mOtaRx[1] == 'N' & mOtaRx[2] == '0' & mOtaRx[3] == '1'){
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              mOtaRx[i+4] = RSSI_buf[i];
           }
            //osal_memcpy(&sort, &RSSI_buf, 2);
           //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, "ID01", 4);
           //HalUARTWrite(SERIAL_APP_PORT, RSSI_buf , 2);
           zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, mOtaRx, 6, 1);
        }
        if(mOtaRx[0] == 'R' & mOtaRx[1] == 'N' & mOtaRx[2] == '0' & mOtaRx[3] == '2'){
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              mOtaRx[i+4] = RSSI_buf[i];
           }
            //osal_memcpy(&sort, &RSSI_buf, 2);
           //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, "ID01", 4);
           //HalUARTWrite(SERIAL_APP_PORT, RSSI_buf , 2);
           zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, mOtaRx, 6, 1);
        }
        if(mOtaRx[0] == 'R' & mOtaRx[1] == 'N' & mOtaRx[2] == '0' & mOtaRx[3] == '3'){
            temp = pkt->rssi;
            temp2 = 256 - temp;
            RSSI_buf[0] = (uint8)((temp2 >> 4) & 0x0f);
            RSSI_buf[1] = (uint8)(temp2 & 0x0f);
            for(int i = 0; i < 2; i++){
              switch(RSSI_buf[i]){
               case 0:
                RSSI_buf[i] = '0';
               break;
               case 1:
                RSSI_buf[i] = '1';
               break;
               case 2:
                RSSI_buf[i] = '2';
               break;
               case 3:
                RSSI_buf[i] = '3';
               break;
               case 4:
                RSSI_buf[i] = '4';
               break;
               case 5:
                RSSI_buf[i] = '5';
               break;
               case 6:
                RSSI_buf[i] = '6';
               break;
               case 7:
                RSSI_buf[i] = '7';
               break;
               case 8:
                RSSI_buf[i] = '8';
               break;
               case 9:
                RSSI_buf[i] = '9';
               break;
               case 10:
                RSSI_buf[i] = 'A';
               break;
               case 11:
                RSSI_buf[i] = 'B';
               break;
               case 12:
                RSSI_buf[i] = 'C';
               break;
               case 13:
                RSSI_buf[i] = 'D';
               break;
               case 14:
                RSSI_buf[i] = 'E';
               break;
               case 15:
                RSSI_buf[i] = 'F';
               break;      
              }
              mOtaRx[i+4] = RSSI_buf[i];
           }
            //osal_memcpy(&sort, &RSSI_buf, 2);
           //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, "ID01", 4);
           //HalUARTWrite(SERIAL_APP_PORT, RSSI_buf , 2);
           zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, mOtaRx, 6, 1);
        }
            //RSSI_buf[0]=((uint8)(~Mac_rssi+1))/10+48;
            //RSSI_buf[1]=((uint8)(~Mac_rssi+1))%10+48;
            //zb_SendDataRequest ( 0, RECEIVE_TAG_RSSI, mOtaRx, pkt->cmd.DataLength);
            //zb_SendDataRequest ( 0xFFFF, TAG_KAO_RSSI, RSSI_buf, pkt->cmd.DataLength);
            //zb_SendDataRequest ( 0xFFFF, RECEIVE_ID_RSSI, RSSI_buf, pkt->cmd.DataLength);         
         #endif
        break;
      case RECEIVE_TAG_RSSI:
        #if defined ( GAO_MASTER )
          for(int i = 0; i < 6; i++){
          mOtaRx[i] = pkt->cmd.Data[i];
          }
          HalUARTWrite(SERIAL_APP_PORT, mOtaRx, 6);
         #endif
        break;
      }
    }
    
    /*********************************************************************
     * @fn      SampleApp_SendPeriodicMessage
     *
     * @brief   Send the periodic message.
     *
     * @param   none
     *
     * @return  none
     */
    void SampleApp_SendPeriodicMessage( void )
    {
      /*
      if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
                           SAMPLEAPP_PERIODIC_CLUSTERID,
                           1,
                           (uint8*)&SampleAppPeriodicCounter,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
      }
      else
      {
        // Error occurred in request to send.
      }
      */
    }
    
    /*********************************************************************
     * @fn      SampleApp_SendFlashMessage
     *
     * @brief   Send the flash message to group 1.
     *
     * @param   flashTime - in milliseconds
     *
     * @return  none
     */
    void SampleApp_SendFlashMessage( uint16 flashTime )
    {
      /*
      uint8 buffer[3];
      buffer[0] = (uint8)(SampleAppFlashCounter++);
      buffer[1] = LO_UINT16( flashTime );
      buffer[2] = HI_UINT16( flashTime );
    
      if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
                           SAMPLEAPP_FLASH_CLUSTERID,
                           3,
                           buffer,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
      }
      else
      {
        // Error occurred in request to send.
      }
      */
    }
    
    /*********************************************************************
     * ��ƦW�١Gzb_SendDataRequest
     * �\    ��G�o�e��ƽШD���
     * �J�f�ѼơGdestination    �Q�o�e��ƪ��ت��a�}�C�Ӧa�}���G
     *�@�@�@�@                 - �]��16�줸�u��}�i0-0xFFFD�j
     *            flashTime    �{�{�ɶ�
                  destination  �ؼеu��}
                  commandId   �LID
                  pData   �ǰe���
                  len   ��ƪ���
     * �X�f�ѼơG�L
     * �� �^ �ȡG�L
     ********************************************************************/
    void zb_SendDataRequest ( uint16 destination, uint16 commandId, uint8 *pData, uint8 len, uint8 radius )
    {
      afAddrType_t dstAddr;
      /* �]�m�ت��a�} */
      if (destination == 0xFFFF)
      {
        // �s��
        dstAddr.addrMode = AddrBroadcast;
        dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;  //0xFFFF ��ƫʥ]�N�Q�ǰe������Ҧ����]��
        dstAddr.endPoint = SampleApp_epDesc.endPoint;
         if ( AF_DataRequest( &dstAddr, 
                           &SampleApp_epDesc,
                           commandId,
                           len,
                           pData,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
      }
      else
      {
    
            // Error occurred in request to send.
      }
     }
      else if (destination == 0xFFFC)
      {
        dstAddr.addrMode = (afAddrMode_t)AddrBroadcast;;
        dstAddr.addr.shortAddr = 0xFFFC;  //0xFFFC �s������ժ̩M��������Ѿ�
        dstAddr.endPoint = SampleApp_epDesc.endPoint;
         if ( AF_DataRequest( &dstAddr, 
                           &SampleApp_epDesc,
                           commandId,
                           len,
                           pData,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE | AF_SKIP_ROUTING,
                           1 ) == afStatus_SUCCESS )
      {
      }
     } 
      else  
      {
        // �ϥεu��}
        dstAddr.addrMode = afAddr16Bit;
        dstAddr.addr.shortAddr = destination;  //shortAddr �ؼг]�Ʀ�}
      /* �]�m���I */
      dstAddr.endPoint = SampleApp_epDesc.endPoint;
      
      /* �o�e���� */
      if ( AF_DataRequest( &dstAddr, 
                           &SampleApp_epDesc,
                           commandId,
                           len,
                           pData,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
      {
      }
      else
      {
    
            // Error occurred in request to send.
      }
     } 
    }
    /*********************************************************************
    /*********************************************************************
     * @fn      zclUARTMsg_CallBack
     *
     * @brief   Send data OTA.
     *
     * @param   port - UART port.
     * @param   event - the UART port event flag.
     *
     * @return  none
     *******************************************************************/
    void zclUARTMsg_CallBack(uint8 port, uint8 event)
    {
      (void)port;
      if(Hal_UART_RxBufLen( SERIAL_APP_PORT) > 0 )
      {
          len = Hal_UART_RxBufLen( SERIAL_APP_PORT );
          HalUARTRead( SERIAL_APP_PORT, TransmitApp_Msg, len );
          osal_set_event( SampleApp_TaskID, UART_MSG_EVT );
       //   osal_set_event( SampleTestApp_TaskID, RECIPROCAL_MSG_EVT );
      }
    }
    
    void gaoAdrr( void ){     //Ū���ثe����m
    uint16 msgAdrr;
    /* First fill in details */
        msgAdrr = NLME_GetShortAddr(); //���o�׺ݳ]�Ʀۨ����u��} NLME_GetExtAddr()���o64���X�i��}
        tmpAdrr[0] = (uint8)( (msgAdrr >> 12) & 0x0F );
        tmpAdrr[1] = (uint8)( (msgAdrr >> 8) & 0x0F );
        tmpAdrr[2] = (uint8)( (msgAdrr >> 4) & 0x0F );
        tmpAdrr[3] = (uint8)( msgAdrr & 0x0F );
        for(int i = 0; i < 4; i++){
          switch(tmpAdrr[i]){
          case 0:
            tmpAdrr[i] = '0';
            break;
          case 1:
            tmpAdrr[i] = '1';
            break;
          case 2:
            tmpAdrr[i] = '2';
            break;
          case 3:
            tmpAdrr[i] = '3';
            break;
          case 4:
            tmpAdrr[i] = '4';
            break;
          case 5:
            tmpAdrr[i] = '5';
            break;
          case 6:
            tmpAdrr[i] = '6';
            break;
          case 7:
            tmpAdrr[i] = '7';
            break;
          case 8:
            tmpAdrr[i] = '8';
            break;
          case 9:
            tmpAdrr[i] = '9';
            break;
          case 10:
            tmpAdrr[i] = 'A';
            break;
          case 11:
            tmpAdrr[i] = 'B';
            break;
          case 12:
            tmpAdrr[i] = 'C';
            break;
          case 13:
            tmpAdrr[i] = 'D';
            break;
          case 14:
            tmpAdrr[i] = 'E';
            break;
          case 15:
            tmpAdrr[i] = 'F';
            break;      
          }
        }
        HalUARTWrite(SERIAL_APP_PORT, tmpAdrr, 4);
    }
    
    void gaoRssi( void ){     
        
    }
    
    
    /*********************************************************************
    *********************************************************************/
    /*********************************************************************
     * @fn      zclUARTMsg_CallBack
     *
     * @brief   Send data OTA.
     *
     * @param   port - UART port.
     * @param   event - the UART port event flag.
     *
     * @return  none
     *******************************************************************/
    
    void get_rssi (afIncomingMSGPacket_t *pkt)
    {
      //uint8 str_1[ ]="SourAddr:";
      //uint8 str_2[ ]="DestAddr:";
      //uint8 str_3[ ]="DataLen:";
      //uint8 str_4[ ]="Data:";
      //uint8 str_5[ ]={'\n'};
      //uint8 str_6[ ]="Rssi_dBm:-";
      //uint8 str_7[ ]="Lqi:";
      //uint8 str_8[ ]="   ";
      
      //uint16 short_ddr;
      //uint8 Src_short_ddr_H;
      //uint8 Src_short_ddr_L;
      //uint8 Des_short_ddr_H;
      //uint8 Des_short_ddr_L;
      
      uint8 RSSI_buf[2];
      //uint8 LQI_buf[3];    
      //uint8 Len_buffer[3];
      //uint8 Src_shortaddr[6];
      //uint8 Des_shortaddr[6];
      
      //------------------------------------RSSI
      RSSI_buf[0]=((uint8)(~(pRxBuf->mac.rssi)+1))/10+48;
      RSSI_buf[1]=((uint8)(~(pRxBuf->mac.rssi)))%10+48;
    
      //Rssi =((pkt->rssi) >= 128 ? (signed int) (pkt->rssi-256)/2 : (pkt->rssi)/2) - RSSI_OFFSET;
    }
    
    void get_Lqi (afIncomingMSGPacket_t *pkt)
    {
      uint8 LQI_buf[3];
      
      //------------------------------------LQI
      LQI_buf[0]=pkt->LinkQuality/100+48;
      LQI_buf[1]=(pkt->LinkQuality%100)/10+48;
      LQI_buf[2]=pkt->LinkQuality%10+48;
    }
    
    

    Dear, 

                I attach my SampleApp.c file.

  • Hello Dennis Kao,

    I have the same problem.

    I am trying to get RSSI values from sensor nodes using CC2530. How did you manage to do that ?  

    Regards



  • Dear Samih Eise,

                             In application layer, I use pkt->RSSI to get the RSSI values.

                            The RSSI values are complementary offset binary. So you have to use 256 - pkt->RSSI = RSSI values.

    Best regards,

                    Dennis

  • Hi Dennis Kao,

    Thanks for reply.

    I am using SensorDemo Example. I did the same, but always RSSI value = 0. 

    I modified sendGtwReport  method as follows

    afIncomingMSGPacket_t *MSGpkt;

    // Rssi modification
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( sapi_TaskID )) )
    {

    msgRssi = 256- MSGpkt->rssi;


     #ifdef LCD_SUPPORTED
     HalLcdWriteStringValue( "RSSI: ", msgRssi, 10, HAL_LCD_LINE_1 );
    #endif
    }

    Also I was trying to use SampleAPP as you mentioned, but for that I need the header file to test your solution.

    Thanks




  • What is exactly 0, the msgRssi?

    Besides, to be able to display this value on LCD, msgRssi must be converted to an array of

    chars, where the last byte in this array must be zero.

  • Dear Samih Eisa,

                        What is datatype of  the msgRssi?    int8 or uint8?

                        I define temp is int8, temp2 is uint8.

                        temp = MSGpkt->rssi;

                        temp2 = 256 - MSGpkt->rssi;

    Best regards,

                Dennis

  • Hi Igor,

    Thanks for reply.

    Besides, to be able to display this value on LCD, msgRssi must be converted to an array of

    chars, where the last byte in this array must be zero

    I have no idea how to do it ? any advice ?

    Thanks

  • Hi Dennis,

    I defined

    int8 msgRssi

    Thanks

  • Hello Dennis,

    Thanks for help. I managed to get Rssi values displayed on the Coordinator's LCD.

    Now, I need ZED to be able to send broadcast message to all nearby ZR. Imagine I have three routers and One blind node.

    Any advice?

    Thanks

    Sam

      

  • Should be as follow:

    XZ1001_App_DstAddr.addr.shortAddr = 0xFFFC; // Broadcast to routers (no end device involved)
    XZ1001_App_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
    XZ1001_App_DstAddr.endPoint = DST_APP_ENDPOINT;

    AF_DataRequest( &ED_App_DstAddr, &ED_App_epDesc,
                                      ED_APP_CLUSTERID,
                                      someLength,
                                      (byte *)someDataBuff,
                                     &ED_App_TransID,
                                     AF_DISCV_ROUTE | AF_SKIP_ROUTING,
                                     1 );  // 1 = Only nearest routers (W/O rebroadcasts)

  • Hello Igor,

    Thanks.

    It works fine. Now I am trying to send the collected Rssi values on the routers to the coordinator.

    And advice ?

    Sam

  • Pretty straight forward, just add some jitter of tens of milliseconds in each router before actually sending

    RSSI value to avoid collisions and slightly reduce the load on coordinator.

  • Dear,

              If you want to extract RSSI value between bind node and reference node.

             The parent of reference node must be bind node.

             Then, you can use zb_SendDataRequest() function that send broadcast message.

    Best regards,

        Dennis 

  • Dear Dennis,

    Thanks for reply.

            If you want to extract RSSI value between bind node and reference node.

             The parent of reference node must be bind node.

    What did you mean ? and how to change the parent of the reference nodes ? 

    Thanks

  • Hello Igor,

    Thanks for reply.

    After checking the network using packet sniffer, I found all data request messages coming from EndDevice (blind node)  are going to its parent only, meaning that, there is something wrong in the broadcast process. The following is the modified method for broadcasting:

    void SampleApp_SendPeriodicMessage( void )
    {

    SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
    SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
    SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFC;


    if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
    SAMPLEAPP_PERIODIC_CLUSTERID,
    1,
    (uint8*)&SampleAppPeriodicCounter,
    &SampleApp_TransID,
    AF_DISCV_ROUTE | AF_SKIP_ROUTING,
    1) == afStatus_SUCCESS )
    {
    }

    }

    any Advice ?

    Thanks

  • Can you attach packet sniffer trace?

  • Judging by the trace, your end device broadcasting the message.

    It also sends requests for data to its parent, but this shouldn't bother you.

    It seems like the routers, including coordinator, broadcasts some message too,

    shouldn't be like that.

    Didn't you follow the next scenario:

    • End device broadcasts some message to nearest routers (achieved)
    • All the routers, that received this broadcast, extracting RSSI value and the sending
      a unicast message to the coordinator. (not achieved)
  • Hello Igor,

    Thanks for reply.

    Please find attached Packet Trace. The network consists of a Coordinator, 2 Router , and End device.

    Now, I need to write the received Unicast messages to the serial port in order to be able to collect them from an application on PC.

    The problem is, before writing any code for sending data to serial port, some received data start appearing on HyperTerminal Screen !!!!!.

    Is that normal ? I only display some LCD messages for code verification.

    Thanks

    4606.NewTrace.psd

  • Hi,

    Samih Eisa said:
    Please find attached Packet Trace. The network consists of a Coordinator, 2 Router , and End device.

    I'll have a look at the .psd file later. You want to ask a question regarding this

    trace, or you just want me to take a look on it?

    Samih Eisa said:

    some received data start appearing on HyperTerminal Screen !!!!!.

    Is that normal ? I only display some LCD messages for code verification.

    MT (monitor and test) is enabled by default, which means that

    what you write to LCD is also transmitted over UART.

    Look for these precompile flags in
    project options->C/C++ compiler->preprocessor->Defined symbols:

    MT_TASK
    MT_SYS_FUNC
    MT_ZDO_FUNC

    You can prefix it with x, to disable MT functionality, like this:

    xMT_TASK
    xMT_SYS_FUNC
    xMT_ZDO_FUNC

    Compile the project once again, and download it. Now the hyper terminal

    shouldn't be catching any of the messages displayed on LCD.

  • Thanks Igor, 

    I got this error when debugging End device !!!

    Error[e46]: Undefined external "debug_str::?relay" referred in hal_lcd ( C:\Texas Instruments\ZStack-CC2530-2.5.1a\Projects\zstack\Samples\SampleApp\

    CC2530DB\EndDeviceEB\Obj\hal_lcd.r51 )

  • Ok,

    More information about what you did that caused this error to appear, would be great.

  • Ok,

    I did what you mentioned. Disable MT functionality as follows:

    xMT_TASK
    xMT_SYS_FUNC
    xMT_ZDO_FUNC

    and then Rebuild ALL


  • Ohh, I have totally forgotten, you should also mask out the LCD_SUPPORTED=DEBUG too.

  • Hello Igor,

    Thanks for reply.

    I am trying to control the number of broadcast and unicast messages that sent from End device and routers.

    How many broadcast/unicast can be sent per min ?

    Thanks

  • Let me ask you another question, how much broadcast messages you want to send, considering power saving

    constraints in End Device.

    Keep in mind that, following your scenario,  a single broadcast message from a blind node that is received

    by N nearby routers will generate N unicast messages to a single sink node!

  • Ok,

    One broadcast message is enough to send N Unicast Rssi messages. However, a single Rssi value per router is not quite enough to rely on it. Therefore, I prefer if I could be able to receive more than one Rssi per router (let's say 10 per router).

  • So you need to transmit 10 broadcast messages followed by 10*N unicast messages

    (by the way, 3, or 4 is more than enough i think).

    How much nearby routers you think there will be in your application (a rough estimation)?

  • Hello Igor,

    Thanks for reply.

    I would say, no more than 3-4 routers. 

    Question:

    I am trying to get as well the Mac address of each router. So I will have on my application : Rssi, and Mac Address for each router.

    NLME_GetExtAdd() : is it the function that I need for that ?

    Thanks

  • Hi,

    Samih Eisa said:
    I would say, no more than 3-4 routers. 

    3-4 routers sending 10 messages each shouldn't pose a problem, it won't clog your network

    Samih Eisa said:
    NLME_GetExtAdd() : is it the function that I need for that ?

    Yes

  • Ok thanks

    But this means, I should get the Mac address of each Router and include it in the Unicast message as well ? 

    Is there any way to get the sender's Mac address in the coordinator without sending it explicitly ? 

    Thanks

  • Samih Eisa said:
    But this means, I should get the Mac address of each Router and include it in the Unicast message as well ? 

    Yes

    Samih Eisa said:
    Is there any way to get the sender's Mac address in the coordinator without sending it explicitly ? 

    There is a private case, where router is a child of coordinator, then you can extract its MAC address

    from coordinators data base directly.

  • Hello Igor,

    Thanks for reply.

    Now, memory copy problem. I did the following:

    void* buff;

    byte* P1 = NLME_GetExtAdd(void);
    byte* P2 = (byte*)&SampleAppRSSI;

    osal_memcpy(buff,&P1, 4);
    osal_memcpy(buff, &P2, 1);

    But I got an error saying 

    function "NLME_GetExtAdd" declared implicitly 

    Any advice ?

    Thanks

  • Ok Igor,

    Thanks

    Now it works. but I got this warning 

    Warning[Pe549]: variable "buff" is used before its value is set