/********************************************************************************************************
 * @file	sampleLight.c
 *
 * @brief	This is the source file for sampleLight
 *
 * @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 "gp.h"
#include PROJECT_H
#if ZBHCI_EN
#include "zbhci.h"
#endif

#include "00ikonke_app/general/ikk-tick-handler.h"
#include "00ikonke_app/general/ikk-network.h"
/**********************************************************************
 * LOCAL CONSTANTS
 */


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


/**********************************************************************
 * GLOBAL VARIABLES
 */
app_ctx_t gLightCtx;


#ifdef ZCL_OTA
extern ota_callBack_t sampleLight_otaCb;

//running code firmware information
ota_preamble_t sampleLight_otaInfo = {
	.fileVer 			= FILE_VERSION,
	.imageType 			= IMAGE_TYPE,
	.manufacturerCode 	= MANUFACTURER_CODE_TELINK,
};
#endif


//Must declare the application call back function which used by ZDO layer
const zdo_appIndCb_t appCbLst = {
	bdb_zdoStartDevCnf,//start device cnf cb
	NULL,//reset cnf cb
	NULL,//device announce indication cb
	sampleLight_leaveIndHandler,//leave ind cb
	NetworkLeaveHandler,//leave cnf cb
	sampleLight_nwkUpdateIndicateHandler,//nwk update ind cb
	NULL,//permit join ind cb
	NULL,//nlme sync cnf cb
	JoinNetworkHandler,//tc join ind cb
};


/**
 *  @brief Definition for bdb commissioning setting
 */
bdb_commissionSetting_t g_bdbCommissionSetting = {
	.linkKey.tcLinkKey.keyType = SS_GLOBAL_LINK_KEY,
	.linkKey.tcLinkKey.key = (u8 *)tcLinkKeyCentralDefault,       		//can use unique link key stored in NV

	.linkKey.distributeLinkKey.keyType = MASTER_KEY,
	.linkKey.distributeLinkKey.key = (u8 *)linkKeyDistributedMaster,  	//use linkKeyDistributedCertification before testing

	.linkKey.touchLinkKey.keyType = MASTER_KEY,
	.linkKey.touchLinkKey.key = (u8 *)touchLinkKeyMaster,   			//use touchLinkKeyCertification before testing

#if TOUCHLINK_SUPPORT
	.touchlinkEnable = 1,												/* enable touch-link */
#else
	.touchlinkEnable = 0,												/* disable touch-link */
#endif
	.touchlinkChannel = DEFAULT_CHANNEL, 								/* touch-link default operation channel for target */
	.touchlinkLqiThreshold = 0xA0,			   							/* threshold for touch-link scan req/resp command */
};

/**********************************************************************
 * LOCAL VARIABLES
 */
ev_timer_event_t *sampleLightAttrsStoreTimerEvt = NULL;


/**********************************************************************
 * FUNCTIONS
 */

/*********************************************************************
 * @fn      stack_init
 *
 * @brief   This function initialize the ZigBee stack and related profile. If HA/ZLL profile is
 *          enabled in this application, related cluster should be registered here.
 *
 * @param   None
 *
 * @return  None
 */
void stack_init(void)
{
	/* Initialize ZB stack */
	zb_init();

	/* Register stack CB */
    zb_zdoCbRegister((zdo_appIndCb_t *)&appCbLst);
}

/*********************************************************************
 * @fn      user_app_init
 *
 * @brief   This function initialize the application(Endpoint) information for this node.
 *
 * @param   None
 *
 * @return  None
 */
extern af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num];
extern zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num];
extern uint8_t Cluster_Num_List[Support_Endpoint_Num];
void user_app_init(void)
{

	af_nodeDescManuCodeUpdate(MANUFACTURER_CODE_TELINK);

    /* Initialize ZCL layer */
	/* Register Incoming ZCL Foundation command/response messages */
    zcl_init(sampleLight_zclProcessIncomingMsg);

	/* Initialize or restore attributes, this must before 'zcl_register()' */
	//zcl_sampleLightAttrsInit();

	for(uint8_t i =0;i< Support_Endpoint_Num;i++)
	{

		SimpleDesc_Init(fixedEndpoints[i]);
		/* Register endPoint */
		af_endpointRegister(fixedEndpoints[i], (af_simple_descriptor_t *)&device_simpleDesc[i], zcl_rx_handler, NULL);
		/* Register ZCL specific cluster information */
		zcl_register(fixedEndpoints[i], Cluster_Num_List[i], (zcl_specClusterInfo_t *)g_EPClusterAllList[i]);
	}

#if AF_TEST_ENABLE
	/* Register endPoint */
	u8 status = af_endpointRegister(SAMPLE_TEST_ENDPOINT, (af_simple_descriptor_t *)&sampleTestDesc, afTest_rx_handler, afTest_dataSendConfirm);
	printf("af_test regester status =%d\r\n",status);
#endif

#ifdef ZCL_GREEN_POWER
	/* Initialize GP */
	gp_init();
#endif

#ifdef ZCL_OTA
	/* Initialize OTA */
    ota_init(OTA_TYPE_CLIENT, (af_simple_descriptor_t *)&device_simpleDesc[0], &sampleLight_otaInfo, &sampleLight_otaCb);
#endif

    zcl_reportingTabInit();
}



void report_handler(void)
{
	if(zb_isDeviceJoinedNwk()){
		if(zcl_reportingEntryActiveNumGet()){
			u16 second = 1;//TODO: fix me

			reportNoMinLimit();

			//start report timer
			reportAttrTimerStart(second);
		}else{
			//stop report timer
			//reportAttrTimerStop();
		}
	}
}

void app_task(void)
{
	//app_key_handler();					//lmm deledt
	//localPermitJoinState();
	if(BDB_STATE_GET() == BDB_STATE_IDLE){
		//factroyRst_handler();

		report_handler();

#if 0/* NOTE: If set to '1', the latest status of lighting will be stored. */
		sampleLightAttrsChk();
#endif
	}
}

static void sampleLightSysException(void)
{
	zcl_onOffAttr_save();
	//zcl_levelAttr_save();
	//zcl_colorCtrlAttr_save();
	iKonkeAfSelfPrint("something wrong ,then system reset");
	SYSTEM_RESET();
	//led_on(LED_POWER);
	//while(1);
}


/*********************************************************************
 * @fn      user_init
 *
 * @brief   User level initialization code.
 *
 * @param   isRetention - if it is waking up with ram retention.
 *
 * @return  None
 */
extern void App_Init(void);
void user_init(bool isRetention)
{
	(void)isRetention;

	/*Initialize Tick Running*/
	Tick_Time_Init();						//lmm add for tick event init

	/* Initialize Stack */
	stack_init();

	/* Initialize user application */
	user_app_init();

	App_Init();
	printf("###########init ŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄŁĄ\r\n");

	/* Register except handler for test */
	sys_exceptHandlerRegister(sampleLightSysException);

	/* Adjust light state to default attributes*/
	//light_adjust();

	/* User's Task */
#if ZBHCI_EN
	zbhciInit();
	ev_on_poll(EV_POLL_HCI, zbhciTask);
#endif
	ev_on_poll(EV_POLL_IDLE, app_task);

    /* Read the pre-install code from NV */
	if(bdb_preInstallCodeLoad(&gLightCtx.tcLinkKey.keyType, gLightCtx.tcLinkKey.key) == RET_OK){
		g_bdbCommissionSetting.linkKey.tcLinkKey.keyType = gLightCtx.tcLinkKey.keyType;
		g_bdbCommissionSetting.linkKey.tcLinkKey.key = gLightCtx.tcLinkKey.key;
	}

    /* Set default reporting configuration */
    u8 reportableChange = 0x00;
    for(uint8_t i =0;i< Support_Endpoint_Num;i++)
	{
    	status_t status = bdb_defaultReportingCfg(fixedEndpoints[i], fixedProfileIds[i], ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF,
    	    						0x0000, 0, (u8 *)&reportableChange);
    	/* Initialize BDB */

    	iKonkeAfSelfPrint("bdb_defaultReportingCfg: index(%d),endpoint(%d),profile(%d) status(%d)\r\n", i,fixedEndpoints[i],fixedProfileIds[i], status);
	}
    u8 result =bdb_init((af_simple_descriptor_t *)&g_EPClusterAllList[0], &g_bdbCommissionSetting, &g_zbDemoBdbCb, 1);
    iKonkeAfSelfPrint("bdb_defaultReportingCfg,result = %d\r\n",result);
}

#endif  /* __PROJECT_TL_DIMMABLE_LIGHT__ */

