/********************************************************************************************************
 * @file	zb_appCb.c
 *
 * @brief	This is the source file for zb_appCb
 *
 * @author	Zigbee Group
 * @date	2019
 *
 * @par     Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
 *          All rights reserved.
 *
 *          Redistribution and use in source and binary forms, with or without
 *          modification, are permitted provided that the following conditions are met:
 *
 *              1. Redistributions of source code must retain the above copyright
 *              notice, this list of conditions and the following disclaimer.
 *
 *              2. Unless for usage inside a TELINK integrated circuit, redistributions
 *              in binary form must reproduce the above copyright notice, this list of
 *              conditions and the following disclaimer in the documentation and/or other
 *              materials provided with the distribution.
 *
 *              3. Neither the name of TELINK, nor the names of its contributors may be
 *              used to endorse or promote products derived from this software without
 *              specific prior written permission.
 *
 *              4. This software, with or without modification, must only be used with a
 *              TELINK integrated circuit. All other usages are subject to written permission
 *              from TELINK and different commercial license may apply.
 *
 *              5. Licensee shall be solely responsible for any claim to the extent arising out of or
 *              relating to such deletion(s), modification(s) or alteration(s).
 *
 *          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *          ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *          WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *          DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
 *          DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *          (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *          LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *          ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *          (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************************************/
#if (__PROJECT_3LIGHT_PANEL_DEMO__)

/**********************************************************************
 * INCLUDES
 */
#include "tl_common.h"
#include "zb_api.h"
#include "zcl_include.h"
#include "bdb.h"
#include "ota.h"
#include PROJECT_H
#include "ikk-ota.h"
#include "ikk-debug.h"
#include "ikk-network.h"
/**********************************************************************
 * LOCAL CONSTANTS
 */
#define DEBUG_HEART		0

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


/**********************************************************************
 * LOCAL FUNCTIONS
 */
void zbdemo_bdbInitCb(u8 status, u8 joinedNetwork);
void zbdemo_bdbCommissioningCb(u8 status, void *arg);
void zbdemo_bdbIdentifyCb(u8 endpoint, u16 srcAddr, u16 identifyTime);


/**********************************************************************
 * GLOBAL VARIABLES
 */
bdb_appCb_t g_zbDemoBdbCb = {zbdemo_bdbInitCb, zbdemo_bdbCommissioningCb, zbdemo_bdbIdentifyCb, NULL};

#ifdef ZCL_OTA
ota_callBack_t sampleLight_otaCb =
{
	sampleLight_otaProcessMsgHandler,
};
#endif

/**********************************************************************
 * LOCAL VARIABLES
 */
u32 heartInterval = 0;

#if DEBUG_HEART
ev_timer_event_t *heartTimerEvt = NULL;
#endif

/**********************************************************************
 * FUNCTIONS
 */
#if DEBUG_HEART
static s32 heartTimerCb(void *arg){
	if(heartInterval == 0){
		heartTimerEvt = NULL;
		return -1;
	}

	gpio_toggle(LED_POWER);

	return heartInterval;
}
#endif

s32 bdbNetworkSteerStart(void *arg){
	u8 status = bdb_networkSteerStart();
	printf("bdbNetworkSteerStart,restart steering = %d\r\n",status);
	return -1;
}

#if FIND_AND_BIND_SUPPORT
s32 sampleLight_bdbFindAndBindStart(void *arg){
	bdb_findAndBindStart(BDB_COMMISSIONING_ROLE_TARGET);

	return -1;
}
#endif

/*********************************************************************
 * @fn      zbdemo_bdbInitCb
 *
 * @brief   application callback for bdb initiation
 *
 * @param   status - the status of bdb init BDB_INIT_STATUS_SUCCESS or BDB_INIT_STATUS_FAILURE
 *
 * @param   joinedNetwork  - 1: node is on a network, 0: node isn't on a network
 *
 * @return  None
 */
void zbdemo_bdbInitCb(u8 status, u8 joinedNetwork){
	if(status == BDB_INIT_STATUS_SUCCESS){
		/*
		 * start bdb commissioning
		 * */
		if(joinedNetwork){
			heartInterval = 1000;

#ifdef ZCL_OTA
			ota_queryStart(30);
#endif
		}else{
			heartInterval = 500;

#if	(!ZBHCI_EN)
			u16 jitter = 0;
			do{
				jitter = zb_random();
				jitter &= 0xfff;
			}while(jitter == 0);
//			TL_ZB_TIMER_SCHEDULE(bdbNetworkSteerStart, NULL, jitter);

//			bdbNetworkSteerStart();
#endif
		}
	}else{
		heartInterval = 200;
	}

#if DEBUG_HEART
	if(heartTimerEvt){
		TL_ZB_TIMER_CANCEL(&heartTimerEvt);
	}
	heartTimerEvt = TL_ZB_TIMER_SCHEDULE(heartTimerCb, NULL, heartInterval);
#endif
}

/*********************************************************************
 * @fn      zbdemo_bdbCommissioningCb
 *
 * @brief   application callback for bdb commissioning
 *
 * @param   status - the status of bdb commissioning
 *
 * @param   arg
 *
 * @return  None
 */
static ev_timer_event_t *kkSteeringNetworkEvent = NULL;
void zbdemo_bdbCommissioningCb(u8 status, void *arg){
	printf("zbdemo_bdbCommissioningCb,status:%d\n\r",status);

	NwkSteeringStatusEnum state = NWK_STEERING_STATUS_FAILED;
	if(status == BDB_COMMISSION_STA_SUCCESS){
		heartInterval = 1000;
		Set2NwkJoiningCountdownCounter(3*1000);

#if FIND_AND_BIND_SUPPORT
	    if(!gLightCtx.bdbFindBindFlg){
	    	gLightCtx.bdbFindBindFlg = TRUE;
#endif

	    	//light_blink_start(2, 200, 200);

#ifdef ZCL_OTA
	    	ota_queryStart(30);
#endif

#if FIND_AND_BIND_SUPPORT
	    	//start Finding & Binding
        	TL_ZB_TIMER_SCHEDULE(sampleLight_bdbFindAndBindStart, NULL, 1000);
        }
#endif
	    state =   NWK_STEERING_STATUS_SUCCESS;
	}else if(status == BDB_COMMISSION_STA_IN_PROGRESS){

	}else if(status == BDB_COMMISSION_STA_NOT_AA_CAPABLE){

	}else if((status == BDB_COMMISSION_STA_NO_NETWORK)||(status == BDB_COMMISSION_STA_TCLK_EX_FAILURE)){
		u16 jitter = 0;
		do{
			jitter = zb_random();
			jitter &= 0xfff;
		}while(jitter == 0);
//		if(!ev_timer_exist(kkSteeringNetworkEvent)) {
//			iKonkeAfSelfPrint("kkSteeringNetworkEvent not exist\r\n");
//			kkSteeringNetworkEvent = TL_ZB_TIMER_SCHEDULE(bdbNetworkSteerStart, NULL, 4000);
//		}
//		iKonkeAfSelfPrint("zbdemo_bdbCommissioningCb,restart steering,timer is %d,%d\r\n",ev_timer_enough(),jitter);

//		TL_ZB_TIMER_SCHEDULE(bdbNetworkSteerStart, NULL, jitter);
	}else if(status == BDB_COMMISSION_STA_TARGET_FAILURE){

	}else if(status == BDB_COMMISSION_STA_FORMATION_FAILURE){

	}else if(status == BDB_COMMISSION_STA_NO_IDENTIFY_QUERY_RESPONSE){

	}else if(status == BDB_COMMISSION_STA_BINDING_TABLE_FULL){

	}else if(status == BDB_COMMISSION_STA_NO_SCAN_RESPONSE){

	}else if(status == BDB_COMMISSION_STA_NOT_PERMITTED){

	}else if(status == BDB_COMMISSION_STA_FORMATION_DONE){
#if ZBHCI_EN

#else
		tl_zbMacChannelSet(DEFAULT_CHANNEL);  //set default channel
#endif
	}
	iKonkeAfSelfPrint("zbdemo_bdbCommissioningCbNetworkSteering,State =  %d\r\n", status);
	Set_Nwk_Steering_Status(state);			//lmm modified
}


extern void sampleLight_zclIdentifyCmdHandler(u8 endpoint, u16 srcAddr, u16 identifyTime);
void zbdemo_bdbIdentifyCb(u8 endpoint, u16 srcAddr, u16 identifyTime){
#if FIND_AND_BIND_SUPPORT
	sampleLight_zclIdentifyCmdHandler(endpoint, srcAddr, identifyTime);
#endif
}

#ifdef ZCL_OTA
void sampleLight_otaProcessMsgHandler(u8 evt, u8 status)
{
	Tl_printf("sampleLight_otaProcessMsgHandler111111, evt = %d, status = %d\r\n", evt, status);
	if(evt == OTA_EVT_START){
		if(status == ZCL_STA_SUCCESS){
			kOTAMoudleCallback(OTA_START);
		}else{
			kOTAMoudleCallback(OTA_FAILED);
		}
	}else if(evt == OTA_EVT_COMPLETE){
		if(status == ZCL_STA_SUCCESS){
			kOTAMoudleCallback(OTA_DOWNLOAD_DONE);
		}else{
			kOTAMoudleCallback(OTA_FAILED);
		}
	}else if(evt == OTA_EVT_COMPLETE){
		if(status == ZCL_STA_SUCCESS){
			ota_mcuReboot();
			kOTAMoudleCallback(OTA_VERITY_SUCCEED);
		}else{
			ota_queryStart(30);
			kOTAMoudleCallback(OTA_FAILED);
		}
	}
}
#endif

/*********************************************************************
 * @fn      sampleLight_leaveIndHandler
 *
 * @brief   Handler for ZDO leave indication message.
 *
 * @param   pInd - parameter of leave indication
 *
 * @return  None
 */
void sampleLight_leaveIndHandler(nlme_leave_ind_t *pLeaveInd)
{
	iKonkeAfSelfPrint("111111Leave Network!!!!!!!\r\n");
}

u8 sampleLight_nwkUpdateIndicateHandler(nwkCmd_nwkUpdate_t *pNwkUpdate){
//	iKonkeAfSelfPrint("111111sampleLight_nwkUpdateIndicateHandler!!!!!!!\r\n");
	return FAILURE;
}

#endif  /* __PROJECT_TL_DIMMABLE_LIGHT__ */
