/********************************************************************************************************
 * @file	sampleLightEpCfg.c
 *
 * @brief	This is the source file for sampleLightEpCfg
 *
 * @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 "zcl_include.h"
#include PROJECT_H
#include ENDPOINT_CONFIG_H
#include "ikk-debug.h"
/**********************************************************************
 * LOCAL CONSTANTS
 */
#define ZCL_BASIC_MFG_NAME     		{5,'K','o','n','k','e'}

#define ZCL_BASIC_MODEL_ID	   		{16,'3','A','F','E','2','0','2','0','0','0','0','6','8','6','2','4'}

#ifndef ZCL_BASIC_MFG_NAME
#define ZCL_BASIC_MFG_NAME     		{6,'T','E','L','I','N','K'}
#endif
#ifndef ZCL_BASIC_MODEL_ID
#define ZCL_BASIC_MODEL_ID	   		{8,'T','L','S','R','8','2','x','x'}
#endif
#ifndef ZCL_BASIC_SW_BUILD_ID
#define ZCL_BASIC_SW_BUILD_ID     	{10,'0','1','2','2','0','5','2','0','1','7'}
#endif

#ifndef ZCL_FCC0_OPT_ID
#define ZCL_FCC0_OPT_ID     		{50,'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
#endif

const uint8_t fixedEndpoints[SUPPORT_MAX_EP] = Support_Endpoint_Array;
const uint16_t fixedProfileIds[SUPPORT_MAX_EP] = FIXED_PROFILE_IDS;
const uint16_t fixedDeviceIds[SUPPORT_MAX_EP] = FIXED_DEVICE_IDS;

#if COLOR_CCT_SUPPORT
#define COLOR_TEMPERATURE_PHYSICAL_MIN	0x00FA//4000K
#define COLOR_TEMPERATURE_PHYSICAL_MAX	0x01C6//2200K
#endif

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


/**********************************************************************
 * GLOBAL VARIABLES
 */
/**
 *  @brief Definition for Incoming cluster / Sever Cluster
 */
 /******************************EP1 INFO**********************************/
const u16 EP1_inClusterList[] =
{
	ZCL_CLUSTER_GEN_BASIC,
	ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP
	ZCL_CLUSTER_GEN_GROUPS,
#endif
#ifdef ZCL_SCENE
	ZCL_CLUSTER_GEN_SCENES,
#endif
#ifdef ZCL_ON_OFF
	ZCL_CLUSTER_GEN_ON_OFF,
#endif
#ifdef ZCL_LEVEL_CTRL
	ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif
#ifdef ZCL_ZLL_COMMISSIONING
	ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif
#ifdef ZCL_FCC0
	ZCL_CLUSTER_PRIVATE_FCC0,
#endif
};

/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 EP1_outClusterList[] =
{
#ifdef ZCL_OTA
    ZCL_CLUSTER_OTA,
#endif
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define EP1_IN_CLUSTER_NUM		(sizeof(EP1_inClusterList)/sizeof(EP1_inClusterList[0]))
#define EP1_OUT_CLUSTER_NUM		(sizeof(EP1_outClusterList)/sizeof(EP1_outClusterList[0]))

/******************************EP2 INFO**********************************/
const u16 EP2_inClusterList[] =
{
	ZCL_CLUSTER_GEN_BASIC,
	ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP
	ZCL_CLUSTER_GEN_GROUPS,
#endif
#ifdef ZCL_SCENE
	ZCL_CLUSTER_GEN_SCENES,
#endif
#ifdef ZCL_ON_OFF
	ZCL_CLUSTER_GEN_ON_OFF,
#endif
#ifdef ZCL_LEVEL_CTRL
	ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif
#ifdef ZCL_ZLL_COMMISSIONING
	ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif
};

/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 EP2_outClusterList[] =
{
#ifdef ZCL_OTA
    ZCL_CLUSTER_OTA,
#endif
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define EP2_IN_CLUSTER_NUM		(sizeof(EP2_inClusterList)/sizeof(EP2_inClusterList[0]))
#define EP2_OUT_CLUSTER_NUM		(sizeof(EP2_outClusterList)/sizeof(EP2_outClusterList[0]))

/******************************EP3 INFO**********************************/

const u16 EP3_inClusterList[] =
{
	ZCL_CLUSTER_GEN_BASIC,
	ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP
	ZCL_CLUSTER_GEN_GROUPS,
#endif
#ifdef ZCL_SCENE
	ZCL_CLUSTER_GEN_SCENES,
#endif
#ifdef ZCL_ON_OFF
	ZCL_CLUSTER_GEN_ON_OFF,
#endif
#ifdef ZCL_LEVEL_CTRL
	ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif
#ifdef ZCL_ZLL_COMMISSIONING
	ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif
};

/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 EP3_outClusterList[] =
{
#ifdef ZCL_OTA
    ZCL_CLUSTER_OTA,
#endif
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define EP3_IN_CLUSTER_NUM		(sizeof(EP3_inClusterList)/sizeof(EP3_inClusterList[0]))
#define EP3_OUT_CLUSTER_NUM		(sizeof(EP3_outClusterList)/sizeof(EP3_outClusterList[0]))

/******************************EP4 INFO**********************************/
const u16 EP4_inClusterList[] =
{
	ZCL_CLUSTER_GEN_BASIC,
	ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP
	ZCL_CLUSTER_GEN_GROUPS,
#endif
#ifdef ZCL_SCENE
	ZCL_CLUSTER_GEN_SCENES,
#endif
#ifdef ZCL_ON_OFF
	ZCL_CLUSTER_GEN_ON_OFF,
#endif
#ifdef ZCL_LEVEL_CTRL
	ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif
#ifdef ZCL_ZLL_COMMISSIONING
	ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif
};

/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 EP4_outClusterList[] =
{
#ifdef ZCL_OTA
    ZCL_CLUSTER_OTA,
#endif
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define EP4_IN_CLUSTER_NUM		(sizeof(EP4_inClusterList)/sizeof(EP4_inClusterList[0]))
#define EP4_OUT_CLUSTER_NUM		(sizeof(EP4_outClusterList)/sizeof(EP4_outClusterList[0]))

/**
 *  @brief Definition for simple description for HA profile
 */
af_simple_descriptor_t EP1_simpleDesc;
af_simple_descriptor_t EP2_simpleDesc;
af_simple_descriptor_t EP3_simpleDesc;
af_simple_descriptor_t EP4_simpleDesc;
af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num] ;;
uint8_t Cluster_Num_List[Support_Endpoint_Num];
zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num];



/******************************EP4 INFO**********************************/
#if AF_TEST_ENABLE
/**
 *  @brief Definition for Incoming cluster / Sever Cluster
 */
const u16 sampleTest_inClusterList[] =
{
	ZCL_CLUSTER_TELINK_SDK_TEST_REQ,
	ZCL_CLUSTER_TELINK_SDK_TEST_RSP,
	ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ,
	ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP,
	0x0001,
};


/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 sampleTest_outClusterList[] =
{
	ZCL_CLUSTER_TELINK_SDK_TEST_REQ,
	ZCL_CLUSTER_TELINK_SDK_TEST_RSP,
	ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ,
	ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP,
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define SAMPLE_TEST_IN_CLUSTER_NUM		(sizeof(sampleTest_inClusterList)/sizeof(sampleTest_inClusterList[0]))
#define SAMPLE_TEST_OUT_CLUSTER_NUM		(sizeof(sampleTest_outClusterList)/sizeof(sampleTest_outClusterList[0]))

/**
 *  @brief Definition for simple description for HA profile
 */
const af_simple_descriptor_t sampleTestDesc =
{
	ZDO_PROFILE_ID,                      /* Application profile identifier */
	HA_DEV_ONOFF_LIGHT_SWITCH,              /* Application device identifier */
	SAMPLE_TEST_ENDPOINT,               /* Endpoint */
	0,                                  /* Application device version */
	0,									/* Reserved */
	SAMPLE_TEST_IN_CLUSTER_NUM,         /* Application input cluster count */
	SAMPLE_TEST_OUT_CLUSTER_NUM,        /* Application output cluster count */
	(u16 *)sampleTest_inClusterList,    /* Application input cluster list */
	(u16 *)sampleTest_outClusterList,   /* Application output cluster list */
};
#endif	/* AF_TEST_ENABLE */


/* Basic */
zcl_basicAttr_t g_zcl_basicAttrs =
{
	.zclVersion 	= 0x03,
	.appVersion 	= 0x29,
	.stackVersion 	= 0x02,
	.hwVersion		= 0x20,
	.manuName		= ZCL_BASIC_MFG_NAME,
	.modelId		= ZCL_BASIC_MODEL_ID,
	.powerSource	= POWER_SOURCE_MAINS_1_PHASE,
	.swBuildId		= ZCL_BASIC_SW_BUILD_ID,
	.deviceEnable	= TRUE,
};

const zclAttrInfo_t basic_attrTbl[] =
{
	{ ZCL_ATTRID_BASIC_ZCL_VER,      		ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  						(u8*)&g_zcl_basicAttrs.zclVersion},
	{ ZCL_ATTRID_BASIC_APP_VER,      		ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,	(u8*)&g_zcl_basicAttrs.appVersion},
	{ ZCL_ATTRID_BASIC_STACK_VER,    		ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  						(u8*)&g_zcl_basicAttrs.stackVersion},
	{ ZCL_ATTRID_BASIC_HW_VER,       		ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.hwVersion},
	{ ZCL_ATTRID_BASIC_MFR_NAME,     		ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,	(u8*)g_zcl_basicAttrs.manuName},
	{ ZCL_ATTRID_BASIC_MODEL_ID,     		ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,	(u8*)g_zcl_basicAttrs.modelId},
	{ ZCL_ATTRID_BASIC_POWER_SOURCE, 		ZCL_DATA_TYPE_ENUM8,    ACCESS_CONTROL_READ,  						(u8*)&g_zcl_basicAttrs.powerSource},
	{ ZCL_ATTRID_BASIC_DEV_ENABLED,  		ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.deviceEnable},
	{ ZCL_ATTRID_BASIC_SW_BUILD_ID,  		ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ,  						(u8*)&g_zcl_basicAttrs.swBuildId},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  						(u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_BASIC_ATTR_NUM	  sizeof(basic_attrTbl) / sizeof(zclAttrInfo_t)

#define		INDETIFY_DEFAULT1  	{	0x0000   		/*identifyTime*/		,\
																}
#define		INDETIFY_DEFAULT2  	{	0x0000   		/*identifyTime*/		,\
																}
#define		INDETIFY_DEFAULT3  	{	0x0000   		/*identifyTime*/		,\
																}
#define		INDETIFY_DEFAULT4  	{	0x0000   		/*identifyTime*/		,\
																}
/* Identify */
zcl_identifyAttr_t g_zcl_identifyAttrs[Support_Endpoint_Num] = {INDETIFY_DEFAULT1,INDETIFY_DEFAULT2,INDETIFY_DEFAULT3,INDETIFY_DEFAULT4};


const zclAttrInfo_t identify_attrTbl[] =
{
	{ ZCL_ATTRID_IDENTIFY_TIME,  			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[0].identifyTime },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  						(u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t identify_attrTb2[] =
{
	{ ZCL_ATTRID_IDENTIFY_TIME,  			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[1].identifyTime },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  						(u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t identify_attrTb3[] =
{
	{ ZCL_ATTRID_IDENTIFY_TIME,  			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[2].identifyTime },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  						(u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t identify_attrTb4[] =
{
	{ ZCL_ATTRID_IDENTIFY_TIME,  			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[3].identifyTime },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  						(u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_IDENTIFY_ATTR1_NUM	 sizeof(identify_attrTbl) / sizeof(zclAttrInfo_t)
#define ZCL_IDENTIFY_ATTR2_NUM	 sizeof(identify_attrTb2) / sizeof(zclAttrInfo_t)
#define ZCL_IDENTIFY_ATTR3_NUM	 sizeof(identify_attrTb3) / sizeof(zclAttrInfo_t)
#define ZCL_IDENTIFY_ATTR4_NUM	 sizeof(identify_attrTb4) / sizeof(zclAttrInfo_t)

uint8_t g_identifyAttrsNum[Support_Endpoint_Num] = {ZCL_IDENTIFY_ATTR1_NUM,ZCL_IDENTIFY_ATTR2_NUM,ZCL_IDENTIFY_ATTR3_NUM,ZCL_IDENTIFY_ATTR4_NUM};


#ifdef ZCL_GROUP
/* Group */
#define		GROUP_DEFAULT1  	{	0   		/*nameSupport*/		,\
																}
#define		GROUP_DEFAULT2  	{	0   		/*nameSupport*/		,\
																}
#define		GROUP_DEFAULT3  	{	0   		/*nameSupport*/		,\
																}
#define		GROUP_DEFAULT4  	{	0   		/*nameSupport*/		,\
																}
zcl_groupAttr_t g_zcl_groupAttrs[Support_Endpoint_Num] = {GROUP_DEFAULT1,GROUP_DEFAULT2,GROUP_DEFAULT3,GROUP_DEFAULT4};


const zclAttrInfo_t group_attrTbl[] =
{
	{ ZCL_ATTRID_GROUP_NAME_SUPPORT,  		ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_groupAttrs[0].nameSupport },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t group_attrTb2[] =
{
	{ ZCL_ATTRID_GROUP_NAME_SUPPORT,  		ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_groupAttrs[1].nameSupport },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t group_attrTb3[] =
{
	{ ZCL_ATTRID_GROUP_NAME_SUPPORT,  		ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_groupAttrs[2].nameSupport },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t group_attrTb4[] =
{
	{ ZCL_ATTRID_GROUP_NAME_SUPPORT,  		ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_groupAttrs[3].nameSupport },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_GROUP_ATTR1_NUM	  sizeof(group_attrTbl[0]) / sizeof(zclAttrInfo_t)
#define ZCL_GROUP_ATTR2_NUM	  sizeof(group_attrTbl[1]) / sizeof(zclAttrInfo_t)
#define ZCL_GROUP_ATTR3_NUM	  sizeof(group_attrTbl[2]) / sizeof(zclAttrInfo_t)
#define ZCL_GROUP_ATTR4_NUM	  sizeof(group_attrTbl[3]) / sizeof(zclAttrInfo_t)

uint8_t g_groupAttrsNum[Support_Endpoint_Num] = {ZCL_GROUP_ATTR1_NUM,ZCL_GROUP_ATTR2_NUM,ZCL_GROUP_ATTR3_NUM,ZCL_GROUP_ATTR4_NUM};
#endif

#ifdef ZCL_SCENE

#define		SCENE_DEFAULT1  	{	0   		/*sceneCount*/		,\
									0  			/*currentScene*/	,\
									0X0000		/*currentGroup*/	,\
									FALSE		/*sceneValid*/		,\
									0			/*nameSupport*/	}
#define		SCENE_DEFAULT2  	{	0   		/*sceneCount*/		,\
									0  			/*currentScene*/	,\
									0X0000		/*currentGroup*/	,\
									FALSE		/*sceneValid*/		,\
									0			/*nameSupport*/	}
#define		SCENE_DEFAULT3  	{	0   		/*sceneCount*/		,\
									0  			/*currentScene*/	,\
									0X0000		/*currentGroup*/	,\
									FALSE		/*sceneValid*/		,\
									0			/*nameSupport*/	}
#define		SCENE_DEFAULT4  	{	0   		/*sceneCount*/		,\
									0  			/*currentScene*/	,\
									0X0000		/*currentGroup*/	,\
									FALSE		/*sceneValid*/		,\
									0			/*nameSupport*/	}
/* Scene */
zcl_sceneAttr_t g_zcl_sceneAttrs[Support_Endpoint_Num] ={SCENE_DEFAULT1,SCENE_DEFAULT2,SCENE_DEFAULT3,SCENE_DEFAULT4};

const zclAttrInfo_t scene_attrTbl[] =
{
    { ZCL_ATTRID_SCENE_SCENE_COUNT,       	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[0].sceneCount		},
    { ZCL_ATTRID_SCENE_CURRENT_SCENE,     	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[0].currentScene   },
    { ZCL_ATTRID_SCENE_CURRENT_GROUP,     	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[0].currentGroup   },
    { ZCL_ATTRID_SCENE_SCENE_VALID,       	ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[0].sceneValid     },
    { ZCL_ATTRID_SCENE_NAME_SUPPORT,      	ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[0].nameSupport    },

    { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t scene_attrTb2[] =
{
    { ZCL_ATTRID_SCENE_SCENE_COUNT,       	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[1].sceneCount		},
    { ZCL_ATTRID_SCENE_CURRENT_SCENE,     	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[1].currentScene   },
    { ZCL_ATTRID_SCENE_CURRENT_GROUP,     	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[1].currentGroup   },
    { ZCL_ATTRID_SCENE_SCENE_VALID,       	ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[1].sceneValid     },
    { ZCL_ATTRID_SCENE_NAME_SUPPORT,      	ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[1].nameSupport    },

    { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t scene_attrTb3[] =
{
    { ZCL_ATTRID_SCENE_SCENE_COUNT,       	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[2].sceneCount		},
    { ZCL_ATTRID_SCENE_CURRENT_SCENE,     	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[2].currentScene   },
    { ZCL_ATTRID_SCENE_CURRENT_GROUP,     	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[2].currentGroup   },
    { ZCL_ATTRID_SCENE_SCENE_VALID,       	ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[2].sceneValid     },
    { ZCL_ATTRID_SCENE_NAME_SUPPORT,      	ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[2].nameSupport    },

    { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t scene_attrTb4[] =
{
    { ZCL_ATTRID_SCENE_SCENE_COUNT,       	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[3].sceneCount		},
    { ZCL_ATTRID_SCENE_CURRENT_SCENE,     	ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[3].currentScene   },
    { ZCL_ATTRID_SCENE_CURRENT_GROUP,     	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[3].currentGroup   },
    { ZCL_ATTRID_SCENE_SCENE_VALID,       	ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[3].sceneValid     },
    { ZCL_ATTRID_SCENE_NAME_SUPPORT,      	ZCL_DATA_TYPE_BITMAP8,  ACCESS_CONTROL_READ,  (u8*)&g_zcl_sceneAttrs[3].nameSupport    },

    { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  (u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_SCENE_ATTR1_NUM	 sizeof(scene_attrTbl[0]) / sizeof(zclAttrInfo_t)
#define ZCL_SCENE_ATTR2_NUM	 sizeof(scene_attrTbl[1]) / sizeof(zclAttrInfo_t)
#define ZCL_SCENE_ATTR3_NUM	 sizeof(scene_attrTbl[2]) / sizeof(zclAttrInfo_t)
#define ZCL_SCENE_ATTR4_NUM	 sizeof(scene_attrTbl[3]) / sizeof(zclAttrInfo_t)

uint8_t g_sceneAttrsNum[Support_Endpoint_Num] ={ZCL_SCENE_ATTR1_NUM,ZCL_SCENE_ATTR2_NUM,ZCL_SCENE_ATTR3_NUM,ZCL_SCENE_ATTR4_NUM};
#endif

#ifdef ZCL_ON_OFF
/* On/Off */
#define		ONOFF_DEFAULT1  	{	0x00   		/*onOff*/				,\
									1  			/*globalSceneControl*/	,\
									0X0000		/*onTime*/				,\
									0X0000		/*offWaitTime*/			,\
									ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF			/*offWaitTime*/	}
#define		ONOFF_DEFAULT2  	{	0x00   		/*onOff*/				,\
									1  			/*globalSceneControl*/	,\
									0X0000		/*onTime*/				,\
									0X0000		/*offWaitTime*/			,\
									ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF			/*offWaitTime*/	}
#define		ONOFF_DEFAULT3  	{	0x00   		/*onOff*/				,\
									1  			/*globalSceneControl*/	,\
									0X0000		/*onTime*/				,\
									0X0000		/*offWaitTime*/			,\
									ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF			/*offWaitTime*/	}
#define		ONOFF_DEFAULT4  	{	0x00   		/*onOff*/				,\
									1  			/*globalSceneControl*/	,\
									0X0000		/*onTime*/				,\
									0X0000		/*offWaitTime*/			,\
									ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF			/*offWaitTime*/	}
zcl_onOffAttr_t g_zcl_onOffAttrs[Support_Endpoint_Num] ={ONOFF_DEFAULT1,ONOFF_DEFAULT2,ONOFF_DEFAULT3,ONOFF_DEFAULT4};

const zclAttrInfo_t onOff_attrTbl[] =
{
	{ ZCL_ATTRID_ONOFF,  					ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_onOffAttrs[0].onOff},
	{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, 		ZCL_DATA_TYPE_BOOLEAN, 	ACCESS_CONTROL_READ, 							  (u8*)&g_zcl_onOffAttrs[0].globalSceneControl},
	{ ZCL_ATTRID_ON_TIME, 					ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[0].onTime},
	{ ZCL_ATTRID_OFF_WAIT_TIME, 			ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[0].offWaitTime},
	{ ZCL_ATTRID_START_UP_ONOFF, 			ZCL_DATA_TYPE_ENUM8, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[0].startUpOnOff},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t onOff_attrTb2[] =
{
	{ ZCL_ATTRID_ONOFF,  					ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_onOffAttrs[1].onOff},
	{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, 		ZCL_DATA_TYPE_BOOLEAN, 	ACCESS_CONTROL_READ, 							  (u8*)&g_zcl_onOffAttrs[1].globalSceneControl},
	{ ZCL_ATTRID_ON_TIME, 					ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[1].onTime},
	{ ZCL_ATTRID_OFF_WAIT_TIME, 			ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[1].offWaitTime},
	{ ZCL_ATTRID_START_UP_ONOFF, 			ZCL_DATA_TYPE_ENUM8, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[1].startUpOnOff},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t onOff_attrTb3[] =
{
	{ ZCL_ATTRID_ONOFF,  					ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_onOffAttrs[2].onOff},
	{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, 		ZCL_DATA_TYPE_BOOLEAN, 	ACCESS_CONTROL_READ, 							  (u8*)&g_zcl_onOffAttrs[2].globalSceneControl},
	{ ZCL_ATTRID_ON_TIME, 					ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[2].onTime},
	{ ZCL_ATTRID_OFF_WAIT_TIME, 			ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[2].offWaitTime},
	{ ZCL_ATTRID_START_UP_ONOFF, 			ZCL_DATA_TYPE_ENUM8, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[2].startUpOnOff},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t onOff_attrTb4[] =
{
	{ ZCL_ATTRID_ONOFF,  					ZCL_DATA_TYPE_BOOLEAN,  ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_onOffAttrs[3].onOff},
	{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, 		ZCL_DATA_TYPE_BOOLEAN, 	ACCESS_CONTROL_READ, 							  (u8*)&g_zcl_onOffAttrs[3].globalSceneControl},
	{ ZCL_ATTRID_ON_TIME, 					ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[3].onTime},
	{ ZCL_ATTRID_OFF_WAIT_TIME, 			ZCL_DATA_TYPE_UINT16, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[3].offWaitTime},
	{ ZCL_ATTRID_START_UP_ONOFF, 			ZCL_DATA_TYPE_ENUM8, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, 	  (u8*)&g_zcl_onOffAttrs[3].startUpOnOff},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_ONOFF_ATTR1_NUM	 sizeof(onOff_attrTbl) / sizeof(zclAttrInfo_t)
#define ZCL_ONOFF_ATTR2_NUM	 sizeof(onOff_attrTb2) / sizeof(zclAttrInfo_t)
#define ZCL_ONOFF_ATTR3_NUM	 sizeof(onOff_attrTb3) / sizeof(zclAttrInfo_t)
#define ZCL_ONOFF_ATTR4_NUM	 sizeof(onOff_attrTb4) / sizeof(zclAttrInfo_t)

uint8_t  g_onoffAttrsNum[Support_Endpoint_Num] ;
#endif

#ifdef ZCL_LEVEL_CTRL
/* Level */
zcl_levelAttr_t g_zcl_levelAttrs =
{
	.curLevel				= 0xFE,
	.remainingTime			= 0,
	.startUpCurrentLevel 	= ZCL_START_UP_CURRENT_LEVEL_TO_PREVIOUS,
};

const zclAttrInfo_t level_attrTbl[] =
{
	{ ZCL_ATTRID_LEVEL_CURRENT_LEVEL,  			ZCL_DATA_TYPE_UINT8,   ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_levelAttrs.curLevel },
	{ ZCL_ATTRID_LEVEL_REMAINING_TIME, 			ZCL_DATA_TYPE_UINT16,  ACCESS_CONTROL_READ,  							(u8*)&g_zcl_levelAttrs.remainingTime },
	{ ZCL_ATTRID_LEVEL_START_UP_CURRENT_LEVEL,  ZCL_DATA_TYPE_UINT8,   ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,  	(u8*)&g_zcl_levelAttrs.startUpCurrentLevel },

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 		ZCL_DATA_TYPE_UINT16,  ACCESS_CONTROL_READ,  							(u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_LEVEL_ATTR_NUM	 sizeof(level_attrTbl) / sizeof(zclAttrInfo_t)
#endif

#ifdef ZCL_LIGHT_COLOR_CONTROL
/* Color Control */
zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs =
{
	.colorMode						= ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS,
	.options						= 0,
	.enhancedColorMode				= ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS,
	.colorCapabilities				= ZCL_COLOR_CAPABILITIES_BIT_COLOR_TEMPERATURE,
	.numOfPrimaries					= 0,
#if COLOR_RGB_SUPPORT
	.currentHue						= 0x00,
	.currentSaturation				= 0x00,
	.colorLoopActive				= 0x00,
	.colorLoopDirection				= 0x00,
	.colorLoopTime					= 0x0019,
	.colorLoopStartEnhancedHue		= 0x2300,
	.colorLoopStoredEnhancedHue		= 0x0000,
#elif COLOR_CCT_SUPPORT
	.colorTemperatureMireds			= COLOR_TEMPERATURE_PHYSICAL_MAX,
	.colorTempPhysicalMinMireds		= COLOR_TEMPERATURE_PHYSICAL_MIN,
	.colorTempPhysicalMaxMireds 	= COLOR_TEMPERATURE_PHYSICAL_MAX,
	.startUpColorTemperatureMireds 	= ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_TO_PREVIOUS,
#endif
};

const zclAttrInfo_t lightColorCtrl_attrTbl[] =
{
    { ZCL_ATTRID_COLOR_MODE,              			ZCL_DATA_TYPE_ENUM8,   	ACCESS_CONTROL_READ,     					(u8*)&g_zcl_colorCtrlAttrs.colorMode },
    { ZCL_ATTRID_COLOR_OPTIONS,           			ZCL_DATA_TYPE_BITMAP8, 	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.options },
    { ZCL_ATTRID_ENHANCED_COLOR_MODE,     			ZCL_DATA_TYPE_ENUM8,   	ACCESS_CONTROL_READ,     					(u8*)&g_zcl_colorCtrlAttrs.enhancedColorMode },
    { ZCL_ATTRID_COLOR_CAPABILITIES,       			ZCL_DATA_TYPE_BITMAP16, ACCESS_CONTROL_READ,     					(u8*)&g_zcl_colorCtrlAttrs.colorCapabilities },
    { ZCL_ATTRID_NUMBER_OF_PRIMARIES,     			ZCL_DATA_TYPE_UINT8,   	ACCESS_CONTROL_READ,     					(u8*)&g_zcl_colorCtrlAttrs.numOfPrimaries },

#if COLOR_RGB_SUPPORT
    { ZCL_ATTRID_CURRENT_HUE,             			ZCL_DATA_TYPE_UINT8,   	ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentHue },
    { ZCL_ATTRID_CURRENT_SATURATION,      			ZCL_DATA_TYPE_UINT8,   	ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentSaturation },
    { ZCL_ATTRID_COLOR_LOOP_ACTIVE,       			ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopActive },
    { ZCL_ATTRID_COLOR_LOOP_DIRECTION,    			ZCL_DATA_TYPE_UINT8,    ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopDirection },
    { ZCL_ATTRID_COLOR_LOOP_TIME,         			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopTime },
    { ZCL_ATTRID_COLOR_LOOP_START_ENHANCED_HUE,   	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,     						 (u8*)&g_zcl_colorCtrlAttrs.colorLoopStartEnhancedHue },
    { ZCL_ATTRID_COLOR_LOOP_STORED_ENHANCED_HUE,  	ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,     						 (u8*)&g_zcl_colorCtrlAttrs.colorLoopStoredEnhancedHue },
#elif COLOR_CCT_SUPPORT
    { ZCL_ATTRID_COLOR_TEMPERATURE_MIREDS,			ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorTemperatureMireds },
    { ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MIN_MIREDS,  	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,     						 (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMinMireds },
    { ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MAX_MIREDS,  	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,     						 (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMaxMireds },
    { ZCL_ATTRID_START_UP_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,      (u8*)&g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds },
#endif

    { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 			ZCL_DATA_TYPE_UINT16,   ACCESS_CONTROL_READ,  							 (u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_COLOR_ATTR_NUM	 sizeof(lightColorCtrl_attrTbl) / sizeof(zclAttrInfo_t)
#endif


#ifdef ZCL_FCC0
/* FCC0 Attr */
//zcl_privateAttr_t g_zcl_Fcc0Attrs =
//{
//	.optdata		= ZCL_FCC0_OPT_ID,
//};

const zclAttrInfo_t fcc0_attrTbl[] =
{
	//{ ECA_OPTDATA,  				ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_Fcc0Attrs.optdata},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t fcc0_attrTb2[] =
{
	//{ ECA_OPTDATA,  				ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_Fcc0Attrs.optdata},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t fcc0_attrTb3[] =
{
	//{ ECA_OPTDATA,  				ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_Fcc0Attrs.optdata},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t fcc0_attrTb4[] =
{
	//{ ECA_OPTDATA,  				ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE,  (u8*)&g_zcl_Fcc0Attrs.optdata},

	{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, 	ZCL_DATA_TYPE_UINT16,  	ACCESS_CONTROL_READ,  							  (u8*)&zcl_attr_global_clusterRevision},
};

#define ZCL_FCC0_ATTR1_NUM	 sizeof(fcc0_attrTbl) / sizeof(zclAttrInfo_t)
#define ZCL_FCC0_ATTR2_NUM	 sizeof(fcc0_attrTb2) / sizeof(zclAttrInfo_t)
#define ZCL_FCC0_ATTR3_NUM	 sizeof(fcc0_attrTb3) / sizeof(zclAttrInfo_t)
#define ZCL_FCC0_ATTR4_NUM	 sizeof(fcc0_attrTb4) / sizeof(zclAttrInfo_t)

uint8_t  g_fcc0AttrsNum[Support_Endpoint_Num] = {ZCL_FCC0_ATTR1_NUM,ZCL_FCC0_ATTR2_NUM,ZCL_FCC0_ATTR3_NUM,ZCL_FCC0_ATTR4_NUM};
#endif


zcl_specClusterInfo_t g_EP1ClusterList[] =
{
	{ZCL_CLUSTER_GEN_BASIC,				 MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, 	basic_attrTbl,  		zcl_basic_register,			 sampleLight_basicCb},
	{ZCL_CLUSTER_GEN_IDENTIFY,			 MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR1_NUM,identify_attrTbl,		zcl_identify_register,		 sampleLight_identifyCb},
#ifdef ZCL_GROUP
	{ZCL_CLUSTER_GEN_GROUPS,			 MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR1_NUM, 	group_attrTbl,  		zcl_group_register,			 NULL},
#endif
#ifdef ZCL_SCENE
	{ZCL_CLUSTER_GEN_SCENES,			 MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR1_NUM,	scene_attrTbl,			zcl_scene_register,			 sampleLight_sceneCb},
#endif
#ifdef ZCL_ON_OFF
	{ZCL_CLUSTER_GEN_ON_OFF,			 MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR1_NUM,	onOff_attrTbl,			zcl_onOff_register,			 sampleLight_onOffCb},
#endif
#ifdef ZCL_LEVEL_CTRL
	{ZCL_CLUSTER_GEN_LEVEL_CONTROL,		 MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM,	level_attrTbl,			zcl_level_register,			 sampleLight_levelCb},
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM,	lightColorCtrl_attrTbl,	zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif
#ifdef ZCL_FCC0
	{ZCL_CLUSTER_PRIVATE_FCC0, 			MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR1_NUM,		fcc0_attrTbl,			NULL, 	 NULL},
#endif
};
u8 EP1_CB_CLUSTER_NUM = (sizeof(g_EP1ClusterList)/sizeof(g_EP1ClusterList[0]));

zcl_specClusterInfo_t g_EP2ClusterList[] =
{
	{ZCL_CLUSTER_GEN_BASIC,				 MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, 	basic_attrTbl,  		zcl_basic_register,			 sampleLight_basicCb},
	{ZCL_CLUSTER_GEN_IDENTIFY,			 MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR2_NUM,identify_attrTb2,		zcl_identify_register,		 sampleLight_identifyCb},
#ifdef ZCL_GROUP
	{ZCL_CLUSTER_GEN_GROUPS,			 MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR2_NUM, 	group_attrTb2,  		zcl_group_register,			 NULL},
#endif
#ifdef ZCL_SCENE
	{ZCL_CLUSTER_GEN_SCENES,			 MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR2_NUM,	scene_attrTb2,			zcl_scene_register,			 sampleLight_sceneCb},
#endif
#ifdef ZCL_ON_OFF
	{ZCL_CLUSTER_GEN_ON_OFF,			 MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR2_NUM,	onOff_attrTb2,			zcl_onOff_register,			 sampleLight_onOffCb},
#endif
#ifdef ZCL_LEVEL_CTRL
	{ZCL_CLUSTER_GEN_LEVEL_CONTROL,		 MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM,	level_attrTb2,			zcl_level_register,			 sampleLight_levelCb},
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM,	lightColorCtrl_attrTb2,	zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif
#ifdef ZCL_FCC0
	{ZCL_CLUSTER_PRIVATE_FCC0, 			MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR2_NUM,		fcc0_attrTb2,			NULL, 	 NULL},
#endif
};
u8 EP2_CB_CLUSTER_NUM = (sizeof(g_EP2ClusterList)/sizeof(g_EP2ClusterList[0]));

zcl_specClusterInfo_t g_EP3ClusterList[] =
{
	{ZCL_CLUSTER_GEN_BASIC,				 MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, 	basic_attrTbl,  		zcl_basic_register,			 sampleLight_basicCb},
	{ZCL_CLUSTER_GEN_IDENTIFY,			 MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR3_NUM,identify_attrTb3,		zcl_identify_register,		 sampleLight_identifyCb},
#ifdef ZCL_GROUP
	{ZCL_CLUSTER_GEN_GROUPS,			 MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, 	group_attrTb3,  		zcl_group_register,			 NULL},
#endif
#ifdef ZCL_SCENE
	{ZCL_CLUSTER_GEN_SCENES,			 MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR3_NUM,	scene_attrTb3,			zcl_scene_register,			 sampleLight_sceneCb},
#endif
#ifdef ZCL_ON_OFF
	{ZCL_CLUSTER_GEN_ON_OFF,			 MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR3_NUM,	onOff_attrTb3,			zcl_onOff_register,			 sampleLight_onOffCb},
#endif
#ifdef ZCL_LEVEL_CTRL
	{ZCL_CLUSTER_GEN_LEVEL_CONTROL,		 MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM,	level_attrTb3,			zcl_level_register,			 sampleLight_levelCb},
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM,	lightColorCtrl_attrTb3,	zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif
#ifdef ZCL_FCC0
	{ZCL_CLUSTER_PRIVATE_FCC0, 			MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR3_NUM,		fcc0_attrTb3,			NULL, 	 NULL},
#endif
};
u8 EP3_CB_CLUSTER_NUM = (sizeof(g_EP3ClusterList)/sizeof(g_EP3ClusterList[0]));

zcl_specClusterInfo_t g_EP4ClusterList[] =
{
	{ZCL_CLUSTER_GEN_BASIC,				 MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, 	basic_attrTbl,  		zcl_basic_register,			 sampleLight_basicCb},
	{ZCL_CLUSTER_GEN_IDENTIFY,			 MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR4_NUM,identify_attrTb4,		zcl_identify_register,		 sampleLight_identifyCb},
#ifdef ZCL_GROUP
	{ZCL_CLUSTER_GEN_GROUPS,			 MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, 	group_attrTb4,  		zcl_group_register,			 NULL},
#endif
#ifdef ZCL_SCENE
	{ZCL_CLUSTER_GEN_SCENES,			 MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR4_NUM,	scene_attrTb4,			zcl_scene_register,			 sampleLight_sceneCb},
#endif
#ifdef ZCL_ON_OFF
	{ZCL_CLUSTER_GEN_ON_OFF,			 MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR4_NUM,	onOff_attrTb4,			zcl_onOff_register,			 sampleLight_onOffCb},
#endif
#ifdef ZCL_LEVEL_CTRL
	{ZCL_CLUSTER_GEN_LEVEL_CONTROL,		 MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM,	level_attrTb4,			zcl_level_register,			 sampleLight_levelCb},
#endif
#ifdef ZCL_LIGHT_COLOR_CONTROL
	{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM,	lightColorCtrl_attrTb4,	zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif
#ifdef ZCL_FCC0
	{ZCL_CLUSTER_PRIVATE_FCC0, 			MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR4_NUM,		fcc0_attrTb4,			NULL, 	 NULL},
#endif
};
u8 EP4_CB_CLUSTER_NUM = (sizeof(g_EP4ClusterList)/sizeof(g_EP4ClusterList[0]));


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

void SimpleDesc_Init(uint8_t endpint)
{
	 switch(endpint)
	 {
		 case 1:
		 {
			 EP1_simpleDesc.app_profile_id 	= fixedProfileIds[0];
			 EP1_simpleDesc.app_dev_id  	= fixedDeviceIds[0];
			 EP1_simpleDesc.endpoint  		= fixedEndpoints[0];
			 EP1_simpleDesc.app_dev_ver 	= 1;
			 EP1_simpleDesc.reserved   		= 0;
			 EP1_simpleDesc.app_in_cluster_count	= EP1_IN_CLUSTER_NUM;
			 EP1_simpleDesc.app_out_cluster_count	= EP1_OUT_CLUSTER_NUM;
			 EP1_simpleDesc.app_in_cluster_lst 		= (u16 *)EP1_inClusterList;
			 EP1_simpleDesc.app_out_cluster_lst		= (u16 *)EP1_outClusterList;
			 device_simpleDesc[0] 					= EP1_simpleDesc;
			 Cluster_Num_List[0]					= EP1_CB_CLUSTER_NUM;
			 g_EPClusterAllList[0]					= g_EP1ClusterList;
			 break;
		 }
		 case 2:
		 {
			 EP2_simpleDesc.app_profile_id 	= fixedProfileIds[1];
			 EP2_simpleDesc.app_dev_id  	= fixedDeviceIds[1];
			 EP2_simpleDesc.endpoint  		= fixedEndpoints[1];
			 EP2_simpleDesc.app_dev_ver 	= 1;
			 EP2_simpleDesc.reserved   		= 0;
			 EP2_simpleDesc.app_in_cluster_count	= EP2_IN_CLUSTER_NUM;
			 EP2_simpleDesc.app_out_cluster_count	= EP2_OUT_CLUSTER_NUM;
			 EP2_simpleDesc.app_in_cluster_lst 		= (u16 *)EP2_inClusterList;
			 EP2_simpleDesc.app_out_cluster_lst		= (u16 *)EP2_outClusterList;
			 device_simpleDesc[1] 					= EP2_simpleDesc;
			 Cluster_Num_List[1]					= EP2_CB_CLUSTER_NUM;
			 g_EPClusterAllList[1]					= g_EP2ClusterList;
			 break;
		 }
		 case 3:
		 {
			 EP3_simpleDesc.app_profile_id 	= fixedProfileIds[2];
			 EP3_simpleDesc.app_dev_id  	= fixedDeviceIds[2];
			 EP3_simpleDesc.endpoint  		= fixedEndpoints[2];
			 EP3_simpleDesc.app_dev_ver 	= 1;
			 EP3_simpleDesc.reserved   		= 0;
			 EP3_simpleDesc.app_in_cluster_count	= EP3_IN_CLUSTER_NUM;
			 EP3_simpleDesc.app_out_cluster_count	= EP3_OUT_CLUSTER_NUM;
			 EP3_simpleDesc.app_in_cluster_lst 		= (u16 *)EP3_inClusterList;
			 EP3_simpleDesc.app_out_cluster_lst		= (u16 *)EP3_outClusterList;
			 device_simpleDesc[2] 					= EP3_simpleDesc;
			 Cluster_Num_List[2]					= EP3_CB_CLUSTER_NUM;
			 g_EPClusterAllList[2]					= g_EP3ClusterList;
			 break;
		 }
		 case 4:
		 {
			 EP4_simpleDesc.app_profile_id 	= fixedProfileIds[3];
			 EP4_simpleDesc.app_dev_id  	= fixedDeviceIds[3];
			 EP4_simpleDesc.endpoint  		= fixedEndpoints[3];
			 EP4_simpleDesc.app_dev_ver 	= 1;
			 EP4_simpleDesc.reserved   		= 0;
			 EP4_simpleDesc.app_in_cluster_count	= EP4_IN_CLUSTER_NUM;
			 EP4_simpleDesc.app_out_cluster_count	= EP4_OUT_CLUSTER_NUM;
			 EP4_simpleDesc.app_in_cluster_lst 		= (u16 *)EP4_inClusterList;
			 EP4_simpleDesc.app_out_cluster_lst		= (u16 *)EP4_outClusterList;
			 device_simpleDesc[3] 					= EP4_simpleDesc;
			 Cluster_Num_List[3]					= EP4_CB_CLUSTER_NUM;
			 g_EPClusterAllList[3]					= g_EP4ClusterList;
			 break;
		 }
		 default:
			 break;
	 }
}

/*********************************************************************
 * @fn      zcl_onOffAttr_save
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
nv_sts_t zcl_onOffAttr_save(void)
{
	nv_sts_t st = NV_SUCC;

#ifdef ZCL_ON_OFF
#if NV_ENABLE
	zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num];

	st = nv_flashReadNew(1, NV_MODULE_ZCL,  NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
	bool write_falge = false;
	if(st == NV_SUCC){
		for(uint8_t i=0;i<Support_Endpoint_Num;i++)
		{
			if((zcl_nv_onOff[i].onOff !=g_zcl_onOffAttrs[i].onOff)||(zcl_nv_onOff[i].startUpOnOff !=g_zcl_onOffAttrs[i].startUpOnOff))
			{
				zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff;
				zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff;
				write_falge = true;
			}
			if(write_falge)
				st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
		}
	}else if(st == NV_ITEM_NOT_FOUND){
		for(uint8_t i=0;i<Support_Endpoint_Num;i++)
		{
			zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff;
			zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff;
		}
		st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
	}
#else
	st = NV_ENABLE_PROTECT_ERROR;
#endif
#endif

	return st;
}

/*********************************************************************
 * @fn      zcl_onOffAttr_restore
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
nv_sts_t zcl_onOffAttr_get(void)
{
	nv_sts_t st = NV_SUCC;

#ifdef ZCL_ON_OFF
#if NV_ENABLE
	zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num];
	st = nv_flashReadNew(1, NV_MODULE_ZCL,  NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
	if(st == NV_SUCC){
		iKonkeAfSelfPrint("Token Get,zcl_onOffAttr_get::\r\n");
		for(uint8_t i=0;i<Support_Endpoint_Num;i++)
		{
			g_zcl_onOffAttrs[i].onOff = zcl_nv_onOff[i].onOff;
			g_zcl_onOffAttrs[i].startUpOnOff = zcl_nv_onOff[i].startUpOnOff;
			iKonkeAfSelfPrint("ep(%d)state%d  ",i+1,g_zcl_onOffAttrs[i].onOff);
		}
		iKonkeAfSelfPrint("\r\n");

	}
#else
	st = NV_ENABLE_PROTECT_ERROR;
#endif
#endif

	return st;
}

#endif	/* __PROJECT_TL_DIMMABLE_LIGHT__ */
