/**************************************************************************************************
  Filename:       SerialApp.c
  Revised:        $Date: 2009-03-29 10:51:47 -0700 (Sun, 29 Mar 2009) $
  Revision:       $Revision: 19585 $

  Description -   Serial Transfer Application (no Profile).


  Copyright 2004-2009 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 sample application is basically a cable replacement
  and it should be customized for your application. A PC
  (or other device) sends data via the serial port to this
  application's device.  This device transmits the message
  to another device with the same application running. The
  other device receives the over-the-air message and sends
  it to a PC (or other device) connected to its serial port.
				
  This application doesn't have a profile, so it handles everything directly.

  Key control:
    SW1:
    SW2:  initiates end device binding
    SW3:
    SW4:  initiates a match description request
*********************************************************************/

/*********************************************************************
 * INCLUDES
 */

#include "AF.h"
#include "OnBoard.h"
#include "OSAL_Tasks.h"
#include "SerialApp.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"

#include "hal_drivers.h"
#include "hal_key.h"
#if defined ( LCD_SUPPORTED )
  #include "hal_lcd.h"
#endif
#include "hal_led.h"
#include "hal_uart.h"

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */

#if !defined( SERIAL_APP_PORT )
#define SERIAL_APP_PORT  0
#endif

#if !defined( SERIAL_APP_BAUD )
#define SERIAL_APP_BAUD  HAL_UART_BR_57600
//#define SERIAL_APP_BAUD  HAL_UART_BR_115200
#endif

// When the Rx buf space is less than this threshold, invoke the Rx callback.
#if !defined( SERIAL_APP_THRESH )
#define SERIAL_APP_THRESH  64
#endif

#if !defined( SERIAL_APP_RX_SZ )
#define SERIAL_APP_RX_SZ  128
#endif

#if !defined( SERIAL_APP_TX_SZ )
#define SERIAL_APP_TX_SZ  128
#endif

// Millisecs of idle time after a byte is received before invoking Rx callback.
#if !defined( SERIAL_APP_IDLE )
#define SERIAL_APP_IDLE  6
#endif

// Loopback Rx bytes to Tx for throughput testing.
#if !defined( SERIAL_APP_LOOPBACK )
#define SERIAL_APP_LOOPBACK  FALSE
#endif

// This is the max byte count per OTA message.
#if !defined( SERIAL_APP_TX_MAX )
#define SERIAL_APP_TX_MAX  80
#endif

#define SERIAL_APP_RSP_CNT  4

// This list should be filled with Application specific Cluster IDs.
const cId_t SerialApp_ClusterList[SERIALAPP_MAX_CLUSTERS] =
{
  SERIALAPP_CLUSTERID1,
  SERIALAPP_CLUSTERID2
};

const SimpleDescriptionFormat_t SerialApp_SimpleDesc =
{
  SERIALAPP_ENDPOINT,              //  int   Endpoint;
  SERIALAPP_PROFID,                //  uint16 AppProfId[2];
  SERIALAPP_DEVICEID,              //  uint16 AppDeviceId[2];
  SERIALAPP_DEVICE_VERSION,        //  int   AppDevVer:4;
  SERIALAPP_FLAGS,                 //  int   AppFlags:4;
  SERIALAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)SerialApp_ClusterList,  //  byte *pAppInClusterList;
  SERIALAPP_MAX_CLUSTERS,          //  byte  AppNumOutClusters;
  (cId_t *)SerialApp_ClusterList   //  byte *pAppOutClusterList;
};

const endPointDesc_t SerialApp_epDesc =
{
  SERIALAPP_ENDPOINT,
 &SerialApp_TaskID,
  (SimpleDescriptionFormat_t *)&SerialApp_SimpleDesc,
  noLatencyReqs
};

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */

uint8 SerialApp_TaskID;    // Task ID for internal task/event processing.
char status;
char temp;
char temp1;
char str_temp[]="FRIDGE 1";
char str_temp1[]="FREEZER -12";
char str_status[]="STATUS ON ";
char str_temp0[]="FRIDGE 1/";
char str_temp11[]="FREEZER -12/";
char str_status1[]="STATUS ON /";
char model[]="2398/";
char message[]="1";

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */

static uint8 SerialApp_MsgID;

static afAddrType_t SerialApp_TxAddr;
static uint8 SerialApp_TxSeq;
static uint8 SerialApp_TxBuf[SERIAL_APP_TX_MAX+1];
static uint8 SerialApp_TxLen;

static afAddrType_t SerialApp_RxAddr;
static uint8 SerialApp_RxSeq;
static uint8 SerialApp_RspBuf[SERIAL_APP_RSP_CNT];

/*********************************************************************
 * LOCAL FUNCTIONS
 */

static void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
static void SerialApp_HandleKeys( uint8 shift, uint8 keys );
static void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt );
static void SerialApp_Send(void);
static void SerialApp_Resp(void);
static void SerialApp_CallBack(uint8 port, uint8 event);
static void decrease_fridge(void);
static void decrease_freezer(void);
static void increase_fridge(void);
static void increase_freezer(void);
static void toggle_status(void);
static void send_statistic(void);
static int get_number(char c);

static int get_number(char c)
{
  int i;
  switch(c)
  {
    case '0':
      i=0;
      break;
    case '1':
      i=1;
      break;
    case '2':
      i=2;
      break;
    case '3':
      i=3;
      break;
    case '4':
      i=4;
      break;
    case '5':
      i=5;
      break;
    case '6':
      i=6;
      break;
    case '7':
      i=7;
      break;
    case '8':
      i=8;
      break;
    case '9':
      i=9;
      break;
      
    
  }
  return i;
}
  

static void send_statistic(void)
{
  int t,t1,t2;
  char p[]="P   /";
  if(status!='0')
  {
    t=get_number(temp);
    t1=get_number(temp1);
    t2=t+t1;
    switch(t2)
    {
      case 0:
        p[2]='0';
        break;
      case 1:
        p[2]='1';
        break;
      case 2:
        p[2]='2';
        break;
      case 3:
        p[2]='3';
        break;
      case 4:
        p[2]='4';
        break;
      case 5:
        p[2]='5';
        break;
      case 6:
        p[2]='6';
        break;
      case 7:
        p[2]='7';
        break;
      case 8:
        p[2]='8';
        break;
      case 9:
        p[2]='9';
        break;
      case 10:
        p[2]='1';p[3]='0';
        break;
      case 11:
        p[2]='1';p[3]='1';
        break;
      case 12:
        p[2]='1';p[3]='2';
        break;
      case 13:
        p[2]='1';p[3]='3';
        break;
      case 14:
        p[2]='1';p[3]='4';
        break;
      case 15:
        p[2]='1';p[3]='5';
        break;
      case 16:
        p[2]='1';p[3]='6';
        break;
      case 17:
        p[2]='1';p[3]='7';
        break;
      case 18:
        p[2]='1';p[3]='8';
        break;
      
        
        
    }
  }
  else
    p[2]='0';
  
  AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,5, (unsigned char *)p,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
  
  
}

static void decrease_fridge(void)
{
  UINT16 addr=NLME_GetShortAddr();
      
  if(addr==0x000)
  {
    
  }
  else
  {
    if(temp>'0')
    {
      temp--;
    }
    str_temp[7]=temp;
    str_temp0[7]=temp;
    HalLcdWriteString(str_temp,2);
   AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,9, (unsigned char *)str_temp0,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
   send_statistic();
    
  }
  
}
static void decrease_freezer(void)
{
  UINT16 addr=NLME_GetShortAddr();
  if(addr==0x000)
  {
    
  }
  else
  {
    if(temp1>'2')
    {
      temp1--;
    }
    str_temp1[10]=temp1;
    str_temp11[10]=temp1;
    HalLcdWriteString(str_temp1,1);
    AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,12, (unsigned char *)str_temp11,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
    send_statistic();
  }
  
}

static void increase_fridge(void)
{
  UINT16 addr=NLME_GetShortAddr();
  if(addr==0x000)
  {
    
  }
  else
  {
    if(temp<'9')
    {
      temp++;
    }
    str_temp[7]=temp;
    str_temp0[7]=temp;
    HalLcdWriteString(str_temp,2);
    AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,9, (unsigned char *)str_temp0,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
    send_statistic();
  }
}

static void increase_freezer(void)
{
  UINT16 addr=NLME_GetShortAddr();
  if(addr==0x000)
  {
    
  }
  else
  {
    if(temp1<'8')
    {
      temp1++;
    }
    str_temp1[10]=temp1;
    str_temp11[10]=temp1;
    HalLcdWriteString(str_temp1,1);
    AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,12, (unsigned char *)str_temp11,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
    send_statistic();
  }
}

static void toggle_status(void)
{
  UINT16 addr=NLME_GetShortAddr();
  if(addr==0x000)
  {
    
  }
  else
  {
    if(status=='0')
    {
      str_status[7]='O';
      str_status[8]='N';
      str_status[9]=' ';
      str_status1[7]='O';
      str_status1[8]='N';
      str_status1[9]=' ';
      status='1';
    }
    else
    {
      str_status[7]='O';
      str_status[8]='F';
      str_status[9]='F';
      str_status1[7]='O';
      str_status1[8]='F';
      str_status1[9]='F';
      status='0';
    }
    HalLcdWriteString(str_status,3);
    AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,11, (unsigned char *)str_status1,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
    send_statistic();
  }
}





/*********************************************************************
 * @fn      SerialApp_Init
 *
 * @brief   This is called during OSAL tasks' initialization.
 *
 * @param   task_id - the Task ID assigned by OSAL.
 *
 * @return  none
 */
void SerialApp_Init( uint8 task_id )
{
  halUARTCfg_t uartConfig;

  SerialApp_TaskID = task_id;
  SerialApp_RxSeq = 0xC3;

  afRegister( (endPointDesc_t *)&SerialApp_epDesc );

  RegisterForKeys( task_id );

  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         = SerialApp_CallBack;
  HalUARTOpen (SERIAL_APP_PORT, &uartConfig);

#if defined ( LCD_SUPPORTED )
  HalLcdWriteString( "SerialApp", HAL_LCD_LINE_2 );
#endif
  
  ZDO_RegisterForZDOMsg( SerialApp_TaskID, End_Device_Bind_rsp );
  ZDO_RegisterForZDOMsg( SerialApp_TaskID, Match_Desc_rsp );
  temp='1';
  temp1='2';
  status='1';
}

/*********************************************************************
 * @fn      SerialApp_ProcessEvent
 *
 * @brief   Generic Application Task event processor.
 *
 * @param   task_id  - The OSAL assigned task ID.
 * @param   events   - Bit map of events to process.
 *
 * @return  Event flags of all unprocessed events.
 */
UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )
{
  (void)task_id;  // Intentionally unreferenced parameter
  
  if ( events & SYS_EVENT_MSG )
  {
    afIncomingMSGPacket_t *MSGpkt;

    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SerialApp_TaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
      case ZDO_CB_MSG:
        SerialApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
        break;
          
      case KEY_CHANGE:
        SerialApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
        break;

      case AF_INCOMING_MSG_CMD:
        SerialApp_ProcessMSGCmd( MSGpkt );
        break;

      default:
        break;
      }

      osal_msg_deallocate( (uint8 *)MSGpkt );
    }

    return ( events ^ SYS_EVENT_MSG );
  }

  if ( events & SERIALAPP_SEND_EVT )
  {
    SerialApp_Send();
    return ( events ^ SERIALAPP_SEND_EVT );
  }

  if ( events & SERIALAPP_RESP_EVT )
  {
    SerialApp_Resp();
    return ( events ^ SERIALAPP_RESP_EVT );
  }

  return ( 0 );  // Discard unknown events.
}

/*********************************************************************
 * @fn      SerialApp_ProcessZDOMsgs()
 *
 * @brief   Process response messages
 *
 * @param   none
 *
 * @return  none
 */
static void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
  switch ( inMsg->clusterID )
  {
    case End_Device_Bind_rsp:
      if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
      {
        // Light LED
        HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
      }
#if defined(BLINK_LEDS)
      else
      {
        // Flash LED to show failure
        HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );
      }
#endif
      break;
      
    case Match_Desc_rsp:
      {
        ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
        if ( pRsp )
        {
          if ( pRsp->status == ZSuccess && pRsp->cnt )
          {
            SerialApp_TxAddr.addrMode = (afAddrMode_t)Addr16Bit;
            SerialApp_TxAddr.addr.shortAddr = pRsp->nwkAddr;
            // Take the first endpoint, Can be changed to search through endpoints
            SerialApp_TxAddr.endPoint = pRsp->epList[0];
            
            // Light LED
            HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
          }
          osal_mem_free( pRsp );
        }
      }
      break;
  }
}

/*********************************************************************
 * @fn      SerialApp_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys  - bit field for key events.
 *
 * @return  none
 */
void SerialApp_HandleKeys( uint8 shift, uint8 keys )
{
  zAddrType_t txAddr;
  
  if ( shift )
  {
    if ( keys & HAL_KEY_SW_1 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
      
      // Initiate a Match Description Request (Service Discovery)
      txAddr.addrMode = AddrBroadcast;
      txAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
      ZDP_MatchDescReq( &txAddr, NWK_BROADCAST_SHORTADDR,
                        SERIALAPP_PROFID,
                        SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
                        SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
                        FALSE );
    }
    if ( keys & HAL_KEY_SW_2 )
    {
      UINT16 addr=NLME_GetShortAddr();
      if(addr==0x000)
      {
        
      }
      else
      {       
        HalLcdWriteString(str_temp1,1);
        HalLcdWriteString(str_temp,2);
        HalLcdWriteString(str_status,3);
      }
     
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys & HAL_KEY_SW_1 )
    {
      decrease_fridge(); 
    }

    if ( keys & HAL_KEY_SW_2 )
    {
      decrease_freezer();
    }

    if ( keys & HAL_KEY_SW_3 )
    {
      increase_fridge(); 
    }

    if ( keys & HAL_KEY_SW_4 )
    {
       increase_freezer();      
    }
    
    if ( keys & HAL_KEY_SW_5 )
    {
      toggle_status();      
    }
  }
}

/*********************************************************************
 * @fn      SerialApp_ProcessMSGCmd
 *
 * @brief   Data message processor callback. This function processes
 *          any incoming data - probably from other devices. Based
 *          on the cluster ID, perform the intended action.
 *
 * @param   pkt - pointer to the incoming message packet
 *
 * @return  TRUE if the 'pkt' parameter is being used and will be freed later,
 *          FALSE otherwise.
 */
void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
  uint8 stat;
  uint8 seqnb;
  uint8 delay;

  
  
  switch ( pkt->clusterId )
  {
  // A message with a serial data block to be transmitted on the serial port.
  case SERIALAPP_CLUSTERID1:
    // Store the address for sending and retrying.
    osal_memcpy(&SerialApp_RxAddr, &(pkt->srcAddr), sizeof( afAddrType_t ));

    seqnb = pkt->cmd.Data[0];

    
    
      // Transmit the data on the serial port.
      if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data, (pkt->cmd.DataLength) ) )
      {
        // Save for next incoming message
        SerialApp_RxSeq = seqnb;
        stat = OTA_SUCCESS;
      }
      else
      {
        stat = OTA_SER_BUSY;
      }
   

    // Select approproiate OTA flow-control delay.
    delay = (stat == OTA_SER_BUSY) ? SERIALAPP_NAK_DELAY : SERIALAPP_ACK_DELAY;

    // Build & send OTA response message.
    SerialApp_RspBuf[0] = stat;
    SerialApp_RspBuf[1] = seqnb;
    SerialApp_RspBuf[2] = LO_UINT16( delay );
    SerialApp_RspBuf[3] = HI_UINT16( delay );
    osal_set_event( SerialApp_TaskID, SERIALAPP_RESP_EVT );
    osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_RESP_EVT);
    break;

  // A response to a received serial data block.
  case SERIALAPP_CLUSTERID2:
    if ((pkt->cmd.Data[1] == SerialApp_TxSeq) &&
       ((pkt->cmd.Data[0] == OTA_SUCCESS) || (pkt->cmd.Data[0] == OTA_DUP_MSG)))
    {
      SerialApp_TxLen = 0;
      osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_SEND_EVT);
    }
    else
    {
      // Re-start timeout according to delay sent from other device.
      delay = BUILD_UINT16( pkt->cmd.Data[2], pkt->cmd.Data[3] );
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_SEND_EVT, delay );
    }
    break;

    default:
      break;
  }
  UINT16 addr=NLME_GetShortAddr();
  if(addr==0x000)
  {
    HalLcdWriteString((char *)pkt->cmd.Data,2); 
  }
  else
  {
    if((((char *)pkt->cmd.Data)[1]=='T')&&(((char *)pkt->cmd.Data)[5]=='F'))
    {
      str_temp1[10]=((char *)pkt->cmd.Data)[15]; 
      str_temp11[10]=((char *)pkt->cmd.Data)[15]; 
      HalLcdWriteString(str_temp1,1); 
      temp1=str_temp1[10];
      send_statistic();
    }
    else if(((char *)pkt->cmd.Data)[1]=='T')
    {
      str_temp[7]=((char *)pkt->cmd.Data)[6];
      str_temp0[7]=((char *)pkt->cmd.Data)[6]; 
      HalLcdWriteString(str_temp,2);
      temp=str_temp[7];
      send_statistic();
    }
    
    if((((char *)pkt->cmd.Data)[1]=='I')&&(((char *)pkt->cmd.Data)[2]=='N'))
    {
      AF_DataRequest(&SerialApp_TxAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID1,5, (unsigned char *)model,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS);
      
    }
    
    if(((char *)pkt->cmd.Data)[1]=='S')
    {
     
      if(((char *)pkt->cmd.Data)[8]=='1')
      {
        
        str_status[7]='O';
        str_status[8]='N';
        str_status[9]=' ';
        str_status1[7]='O';
        str_status1[8]='N';
        str_status1[9]=' ';
        status='1';
        send_statistic();
      }
      else if(((char *)pkt->cmd.Data)[8]=='0')
      {
        
        str_status[7]='O';
        str_status[8]='F';
        str_status[9]='F';
        str_status1[7]='O';
        str_status1[8]='F';
        str_status1[9]='F';
        
        status='0';
        send_statistic();
      }
      HalLcdWriteString(str_status,3);
      
    }
    
  }
 
  
}

/*********************************************************************
 * @fn      SerialApp_Send
 *
 * @brief   Send data OTA.
 *
 * @param   none
 *
 * @return  none
 */
static void SerialApp_Send(void)
{
#if SERIAL_APP_LOOPBACK
  if (SerialApp_TxLen < SERIAL_APP_TX_MAX)
  {
    SerialApp_TxLen += HalUARTRead(SERIAL_APP_PORT, SerialApp_TxBuf+SerialApp_TxLen+1,
                                                    SERIAL_APP_TX_MAX-SerialApp_TxLen);
  }

  if (SerialApp_TxLen)
  {
    (void)SerialApp_TxAddr;
    if (HalUARTWrite(SERIAL_APP_PORT, SerialApp_TxBuf+1, SerialApp_TxLen))
    {
      SerialApp_TxLen = 0;
    }
    else
    {
      osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);
    }
  }
#else
  if (!SerialApp_TxLen && 
      (SerialApp_TxLen = HalUARTRead(SERIAL_APP_PORT, SerialApp_TxBuf+1, SERIAL_APP_TX_MAX)))
  {
    // Pre-pend sequence number to the Tx message.
    SerialApp_TxBuf[0] = ++SerialApp_TxSeq;
  }

  if (SerialApp_TxLen)
  {
    if (afStatus_SUCCESS != AF_DataRequest(&SerialApp_TxAddr,
                                           (endPointDesc_t *)&SerialApp_epDesc,
                                            SERIALAPP_CLUSTERID1,
                                            SerialApp_TxLen+1, SerialApp_TxBuf,
                                            &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS))
      
    {
      osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);
    }
    HalLcdWriteString("                ",3);
    HalLcdWriteString((char *)SerialApp_TxBuf,3);
  }
#endif
}

/*********************************************************************
 * @fn      SerialApp_Resp
 *
 * @brief   Send data OTA.
 *
 * @param   none
 *
 * @return  none
 */
static void SerialApp_Resp(void)
{
  if (afStatus_SUCCESS != AF_DataRequest(&SerialApp_RxAddr,
                                         (endPointDesc_t *)&SerialApp_epDesc,
                                          SERIALAPP_CLUSTERID2,
                                          SERIAL_APP_RSP_CNT, SerialApp_RspBuf,
                                         &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS))
  {
    osal_set_event(SerialApp_TaskID, SERIALAPP_RESP_EVT);
  }
}

/*********************************************************************
 * @fn      SerialApp_CallBack
 *
 * @brief   Send data OTA.
 *
 * @param   port - UART port.
 * @param   event - the UART port event flag.
 *
 * @return  none
 */
static void SerialApp_CallBack(uint8 port, uint8 event)
{
  (void)port;

  if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)) &&
#if SERIAL_APP_LOOPBACK
      (SerialApp_TxLen < SERIAL_APP_TX_MAX))
#else
      !SerialApp_TxLen)
#endif
  {
    SerialApp_Send();
  }
}

/*********************************************************************
*********************************************************************/
