#include "ikk-factory-test.h"
#include "ikk-debug.h"
#include "ikk-token.h"
#include "ikk-common-utils.h"
#include "../driver/ikk-button.h"
#include "../driver/ikk-led.h"
#include "../driver/ikk-relay.h"
#include "ikk-cluster.h"
#include "ikk-command.h"

#define AGING_TEST_15MIN_VALUE			0xA1
#define AGING_TEST_4HOU_VALUE			0xA2
#define AGINE_TEST_DONE_VALUE			0xFA
//已经置老化标志
#define SINGLE_BOARD_TEST_DONE_VALUE       	 	0xF1
#define FULL_DEVICE_TEST_DONE_VALUE          	0xF2
#define FORCE_FACTORY_TEST_VALUE				0xF8

#define TEST_INIT_VALUE					0xFF
#define LED_SLOW_BLINK_ON_TIME_MS				800
#define LED_SLOW_BLINK_OFF_TIME_MS				800
#define LED_FAST_BLINK_ON_TIME_MS				200
#define LED_FAST_BLINK_OFF_TIME_MS				200

#define LED_SLOW_BLINK_CONTINUE_TIME_MS			(60 * 1000)
#define LED_FAST_BLINK_CONTINUE_TIME_MS			(5 * 1000)

u8 g_u8NetworkSteeringChannel	= 20;
u16 g_u16NetworkSteeringPanId	= 0xFFFF;
static ev_timer_event_t *kFactoryTestEvt = NULL;
s32 kFactoryTestEventHandler(void *arg);


typedef struct{
	uint8_t u8BtnId;
	uint8_t u8BtnLongPressTimes; //touch keys must be long pressed 2 times, mechanical keys is pressed 1 time
	uint32_t u32AgingForceExitTimeMs;  //key long pressed time for  exit aging test
	uint32_t u32AgingForceExitTimeCounter;  //key long pressed time for  exit aging test
	BtnActionEnum elastBtnAction;
	BtnActionEnum eCurrentBtnAction;
	bool bIsFirstBtnLongPressed ;
	uint32_t u32FirstBtnLongPressedCountDown;
}FactoryTestControllerSt;

typedef enum{FT_SINGLE_BOARD_TEST=0x01, FT_FULL_DEVICE_TEST=0x02, FT_NORMAL_DONE=0x04, FT_FORCE_EXIT=0x08, FT_AGING_DONE = 0X10,}FT_STATUS;
extern LedConfSt g_ledConfList;

FactoryTestControllerSt g_stFactoryTestControllerList[AGING_EXIT_MAX_BTN_NUM] \
	= {{BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}, {BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}};

FactoryTestStatusEnum g_eFactoryTestStatus = FTS_NORMAL;
static FactoryTestStatusEnum g_eLastFactoryTestStatus = FTS_NORMAL;
static uint32_t g_u32AgingTotalTimeMS = 0;
static uint32_t g_u32AgingMaxTimeMS = 0;
static pFactoryTestPollCallback g_pFactoryTestPollCallback = NULL;
static 	uint8_t g_u8LongPressedKeyIndex = 0;
static uint32_t g_u32Count = 0;
static uint8_t g_u8FactoryTestLedId = LED_UNKNOW_ID;  //just for single board test or full device test
/*	DESP: get the test index by id.
 * 	Auth: mazj.20200227.
 * */
static uint8_t kGetFactoryTestIndexByID(uint8_t id )
{
	for(int index = 0; index < AGING_EXIT_MAX_BTN_NUM; ++index ) {
		if( g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ) {
			if( g_stFactoryTestControllerList[index].u8BtnId == id ) {
				return index;
			}
		}else break;
	}

	return 0XFF;
}

FactoryTestStatusEnum kGetFactoryTestStatus(void)
{
	return g_eFactoryTestStatus;
}

void kSetAgingMaxTime(uint16_t value)
{
	nv_sts_t st = NV_SUCC;

	uint16_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&temp);
	if(st == NV_SUCC){
		if(temp != value)
		{
			st = nv_flashWriteNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&value);
			iKonkeAfSelfPrint("kSetAgingTestTime:st = %d,data = %d\r\n",st,NV_AGING_TEST_TIME);
		}
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&value);
	}
}
uint32_t kGetAgingMaxTime(void)
{
	nv_sts_t st = NV_SUCC;
	uint32_t maxTime;
	uint16_t value = 0;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_AGING_TEST_TIME, sizeof(value), (u8*)&value);
	iKonkeAfSelfPrint("kGetAgingTestTime:st = %d,value = %d\r\n",st,value);
	if(st != NV_SUCC){
		maxTime = FACTORY_TEST_4HOU_MS;
	}
	else if ((value == 0) || (value == 0xffff)) {
		maxTime = FACTORY_TEST_4HOU_MS;
	} else {
		maxTime = value * 60 * 1000;
	}
	return maxTime;
}
uint8_t kGetFactoryTestValueStatus(void)
{
    uint8_t status = 0;

#if Z30_DEVICE_SINGLE_BOARD_ENABLE
    if (kGetSingleBoardValue() == FORCE_FACTORY_TEST_VALUE) {
        status = status | FT_FORCE_EXIT;
     }else if (kGetSingleBoardValue() != SINGLE_BOARD_TEST_DONE_VALUE) {
    	status = status | FT_SINGLE_BOARD_TEST;
     }else {
#if !Z30_DEVICE_FULL_DEVICE_ENBALE
    	 status = status | FT_NORMAL_DONE;
#endif
    }
#endif

#if Z30_DEVICE_FULL_DEVICE_ENBALE
    if (kGetFullDeviceValue() == FORCE_FACTORY_TEST_VALUE) {
        status = status | FT_FORCE_EXIT;
     }else if (kGetFullDeviceValue() != FULL_DEVICE_TEST_DONE_VALUE){
    	status = status | FT_FULL_DEVICE_TEST;//没过整机时该标志位是1，单板整机都过的时候第三位bit为1，最后两个bit位为0
    }else {
    	status = status | FT_NORMAL_DONE;
    }
#endif

#if Z30_DEVICE_AGING_ENABLE
    if (kGetAgingTestValue() != AGINE_TEST_DONE_VALUE) {
        status = status | FT_AGING_DONE;
     }
#endif
    return status;
}
nv_sts_t General_Set_Factory_Test(nv_item_t items,uint8_t value)
{
	nv_sts_t st = NV_SUCC;
	uint8_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  items, sizeof(uint8_t), (u8*)&temp);
	if(st == NV_SUCC){
		if(temp != value)
		{
			st = nv_flashWriteNew(1, NV_MODULE_APP, items, sizeof(uint8_t), (u8*)&value);
			iKonkeAfSelfPrint("kSetSingleBoardValue:st = %d,data = %d\r\n",st,value);
		}
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, items, sizeof(uint8_t), (u8*)&value);
	}
	return st;
}
uint8_t General_Get_Factory_Test(nv_item_t items,uint8_t default_value)
{
	nv_sts_t st = NV_SUCC;
	uint8_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  items, sizeof(temp), (u8*)&temp);
	iKonkeAfSelfPrint("kGetSingleBoardValue:st = %d,data = %d\r\n",st,temp);
	if(st != NV_SUCC){
		temp = default_value;
	}
	return temp;
}
void  kFactoryTestBtnActionCallback(unsigned char button_id, BtnActionEnum action)
{
	if (kGetFactoryTestStatus() != FTS_NORMAL)
	{
		uint8_t u8FactoryTestIndex = kGetFactoryTestIndexByID(button_id);
		if (u8FactoryTestIndex != 0xFF){
			//add bby maozj 20200828
			if(action == EBA_LONGPRESS)
				g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = EBA_PRESSED;
			else
				g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = action;

			//松手复位,触摸按键长时间按着也会自动松手
			if ((g_eFactoryTestStatus == FTS_WAITING_RELEASED || g_eFactoryTestStatus == FTS_FORCE_EXIT) && g_stFactoryTestControllerList[g_u8LongPressedKeyIndex].eCurrentBtnAction == EBA_RELEASED){
				g_eFactoryTestStatus = FTS_FORCE_REBOOT;
				g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数
				iKonkeAfSelfPrint("FactoryTest Released\r\n");
			}
		}
	}
}

static uint16_t opcodeReampTable[][2] =
{
	//FCC0, AA55
	{0xF0, 0xED14},//打开产测
	{0xF1, 0xED04},//退出产测
	{0xF2, 0xED05},//查询产测（按bit位）
    {0xF8, 0xED16},//查询产测（按字节）
};

static uint16_t kCmdOpcodeRemap(uint16_t Opcode, uint8_t direction)
{
	for (uint8_t i = 0; i < (sizeof(opcodeReampTable)/(2*sizeof(uint16_t))); i++ ) {
		if (opcodeReampTable[i][0] == Opcode) {
			return opcodeReampTable[i][1];
		}
	}
	return 0xFFFF;
}

kk_err_t kkFactoryMsgInComingPaser(UMsgNodeSt *pMsgNode, ComPortEm port, DataField_st *pDataOut)
 {
	//UMsgNodeSt uMsgNode = {0};
	uint16_t length = 0;
	uint8_t control_field = 0;
	DataField_st data;
	DataField_st send_buf;
	uint8_t reply_control_field = 0;

	if( NULL == pMsgNode ) {
		return KET_ERR_INVALID_PARAM;
	}

#if 0 // Just for debug
	iKonkeAfSelfPrint("\r\n-- MSG INCOMING[%d]:\r\n", pMsgNode->length);
	iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length, true);
	iKonkeAfSelfPrint("\r\n--------------------\r\n");
#endif

	// check for parsable packets
	if( pMsgNode->length < 5 /* Minimum Packet Length */ ) {
		iKonkeAfSelfPrint("Err: Unparsable Packets!!\r\n");
		return KET_ERR_INVALID_PARAM;
	}
	//length(1) pid(4) ch(1) opcode(1) arg
	if (port == ECOM_PORT_FCC0) {
		length = pMsgNode->length;
		//control_field = pMsgNode->buffer[4];
		data.seq = 0x00;
		data.u8Datalen = pMsgNode->buffer[0];
		data.u8ArgLen = data.u8Datalen - 6; // fcc0 - id (4) - ch(1) - opcode(1)
		data.u8ChannelID = pMsgNode->buffer[5];
		data.u16Opcode = kCmdOpcodeRemap((uint16_t)(pMsgNode->buffer[6]), 0);

		if(data.u16Opcode == 0xFFFF) {
			return KET_ERR_INVALID_PARAM;
		}

		memcpy(data.u8ARG,&pMsgNode->buffer[7], data.u8ArgLen); //6 =  pid(4) + ch(1) + opcode(1)

		send_buf.seq = data.seq;
		send_buf.u8ChannelID = data.u8ChannelID;
		send_buf.u16Opcode = data.u16Opcode;
	} else {
		length = ((uint16_t)pMsgNode->buffer[2] << 8) | (uint16_t)(pMsgNode->buffer[3]);
		control_field = pMsgNode->buffer[4];

		data.seq = ((uint16_t)pMsgNode->buffer[5] << 8) | (uint16_t)(pMsgNode->buffer[6]);

		data.u8Datalen = pMsgNode->buffer[7];
		data.u8ArgLen = data.u8Datalen - 3; // aa55 - ch(1) - opcode(2)
		data.u8ChannelID = pMsgNode->buffer[8];
		data.u16Opcode = ((uint16_t)pMsgNode->buffer[9] << 8) |  (uint16_t)(pMsgNode->buffer[10]);
		memcpy(data.u8ARG,&pMsgNode->buffer[11],data.u8Datalen - 3);

		send_buf.seq = data.seq;
		send_buf.u8ChannelID = data.u8ChannelID;
		send_buf.u16Opcode = data.u16Opcode;
	}

	send_buf.u8Datalen = 0;

	switch (data.u16Opcode) {
	case (UART_MSG_QUERY_INFO_OPCODE):
	{
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ArgLen = 1;
		reply_control_field = Z_TO_H_NO_ACK;
		break;
	}
	case (UART_MSG_QUERY_DEVICE_VERSION_OPCODE):
	{
		send_buf.u8ARG[0] = ERR_OK;
		uint8_t hardversion = 0;
		uint8_t softversion = 0;

		status_t status;
		zclAttrInfo_t *hwattrInfo = ReadServerAttribute(1,ZCL_CLUSTER_GEN_BASIC,ZCL_ATTRID_BASIC_HW_VER,&status);
		hardversion = hwattrInfo->data[0];
		iKonkeAfSelfPrint("hardversion = %x\r\n",hwattrInfo->data[0]);

		zclAttrInfo_t *appattrInfo = ReadServerAttribute(1,ZCL_CLUSTER_GEN_BASIC,ZCL_ATTRID_BASIC_APP_VER,&status);
		softversion = appattrInfo->data[0];
		iKonkeAfSelfPrint("softversion = %x\r\n",appattrInfo->data[0]);

    	send_buf.u8ARG[1] = hardversion;
    	send_buf.u8ARG[2] = softversion;
		send_buf.u8ARG[3] = 0XFF;
		send_buf.u8ARG[4] = 0XFF;
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ArgLen = 5;
		reply_control_field = Z_TO_H_NO_ACK;
		break;
	}
	case (UART_MSG_QUERY_DEVICE_INFO_OPCODE):
	{
		addrExt_t addr;
		flash_read(CFG_MAC_ADDRESS,8,(uint8_t*)addr);

		send_buf.u8ARG[0] = ERR_OK;
		SWAP_EUI64((uint8_t *)addr);
		memcpy(&send_buf.u8ARG[1],addr,8);

		send_buf.u8ArgLen = 9;
		reply_control_field = Z_TO_H_NO_ACK;
		break;
	}
	case (UART_MSG_CONFIG_DEVICE_SLEEP_OPCODE):
	{
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ArgLen = 1;
		reply_control_field = Z_TO_H_NO_ACK;
		break;
	}
	case (UART_MSG_EXIT_FACTORY_TEST_OPCODE):
	{
		if(data.u8ARG[0]&0x01)
		{
			kSetSingleBoardValue(SINGLE_BOARD_TEST_DONE_VALUE);
			send_buf.u8ARG[0] = ERR_OK;
			g_eFactoryTestStatus = FTS_SINGLE_BOARD_TEST_DONE;
			//单板结束，一直快闪
			kLedOptTrigger(g_u8FactoryTestLedId, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, BLINK_DEAD, LED_ON, LED_ON);
		}
		if(data.u8ARG[0]&0x02)
		{
			kSetFullDeviceValue(FULL_DEVICE_TEST_DONE_VALUE);
			send_buf.u8ARG[0] = ERR_OK;
			g_eFactoryTestStatus = FTS_FULL_DEVICE_TEST_DONE;
			//整机结束，一直快闪
			kLedOptTrigger(g_u8FactoryTestLedId, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, BLINK_DEAD, LED_ON, LED_ON);
		}
		if((data.u8ARG[0]&0x03) == 0x03 || (data.u8ARG[0]&0x04) == 0x04)
		{
			kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
			send_buf.u8ARG[0] = ERR_OK;
			//g_eFactoryTestStatus = FTS_AGING_DONE;//指令退老化和正常4h退老化区分
		}
		send_buf.u8ARG[1] = data.u8ARG[0];
		send_buf.u8ArgLen = 2;
		reply_control_field = Z_TO_H_NO_ACK;
		break;
	}
	case (UART_MSG_QUERY_FACTORY_INFO_OPCODE):
	{
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ARG[1] = kGetFactoryTestValueStatus();
		send_buf.u8ArgLen = 2;
		reply_control_field = Z_TO_H_NO_ACK;
		iKonkeAfSelfPrint("######UART_MSG_QUERY_FACTORY_INFO_OPCODE(%d)\r\n", send_buf.u8ArgLen);
		break;
	}
	case (UART_MSG_QUERY_SWITCH_ONOFF_OPCODE):
	{
		extern uint8_t  Key_Press_Test_Flag[5];
		for (uint8_t i = 0; i < 6; i++){
			if(i < 5){
				send_buf.u8ARG[i+1] = Key_Press_Test_Flag[i];
			}
			else{
				send_buf.u8ARG[i+1] = 0xff;
			}
		}
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ArgLen = 7;
		break;
	}
	case (UART_MSG_ENTER_FACTORY_TEST_OPCODE):
	{
		uint8_t tmp_value = data.u8ARG[0];
		reply_control_field = Z_TO_H_NO_ACK;
		if ((tmp_value & 0x01) == 0x01) {
			kSetSingleBoardValue(0x00);
		}

		if ((tmp_value & 0x02) == 0x02) {
			kSetFullDeviceValue(0x00);
		}

		if ((tmp_value & 0x04) == 0x04) {
			kSetAgingTestValue(0x00);
		}
		send_buf.u8ArgLen = 2;
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ARG[1] = kGetFactoryTestValueStatus();
		break;
	}
	case UART_MSG_ONOFF_SWITCH_OPCODE: {
		uint8_t err = 0;
		if (data.u8ARG[0] == 0x01) {
			for (uint8_t i = 1; i < 9; i++) {
				if (data.u8ARG[i] == 0x00) { // on
					kZclOnOffClusterServerOnOffControl(i, EOOC_OFF);
				} else if (data.u8ARG[i] == 0x01) {
					kZclOnOffClusterServerOnOffControl(i, EOOC_ON);
				}
			}
		}
		//get onoff state
		for (uint8_t i = 1; i < 9; i++) {
			err = kZclOnOffClusterServerOnOffGet(i);
			send_buf.u8ARG[i] = (err == EOOS_ON)?1:(err == EOOS_UNKNOW?0xFF:0);
		}
		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ArgLen = 9;
		break;
	}
	//Auth: han_frc.20220105.
	case UART_MSG_QUERY_FACTORY_STATE_OPCODE: {
		uint8_t factoryTest = 0;
		uint8_t singleBoardTest = 0;
		uint8_t fullDeviceTest = 0;
		uint8_t agingTest = 0;

		singleBoardTest = kGetSingleBoardValue();
		fullDeviceTest = kGetFullDeviceValue();
        agingTest = kGetAgingTestValue();

		if (((singleBoardTest == FORCE_FACTORY_TEST_VALUE) || (singleBoardTest == SINGLE_BOARD_TEST_DONE_VALUE)) \
			&& ((fullDeviceTest == FULL_DEVICE_TEST_DONE_VALUE) || (fullDeviceTest == SINGLE_BOARD_TEST_DONE_VALUE))) {
			factoryTest = 0x00;
		} else {
			factoryTest = 0x01;
		}
#if Z30_DEVICE_SINGLE_BOARD_ENABLE
		if (singleBoardTest == SINGLE_BOARD_TEST_DONE_VALUE) {
			singleBoardTest = 0x01;
		} else if (singleBoardTest == FORCE_FACTORY_TEST_VALUE) {
			singleBoardTest = 0x02;
		} else {
			singleBoardTest = 0x00;
		}
#else
		singleBoardTest = 0xff;
#endif

#if Z30_DEVICE_FULL_DEVICE_ENBALE
		if (fullDeviceTest == FULL_DEVICE_TEST_DONE_VALUE) {
			fullDeviceTest = 0x01;
		} else if (fullDeviceTest == FORCE_FACTORY_TEST_VALUE) {
			fullDeviceTest = 0x02;
		} else {
			fullDeviceTest = 0x00;
		}
#else
		fullDeviceTest = 0xff;
#endif

#if Z30_DEVICE_AGING_ENABLE
		if (agingTest == AGINE_TEST_DONE_VALUE) {
			agingTest = 0x01;
		} else if (agingTest == FORCE_FACTORY_TEST_VALUE) {
			agingTest = 0x02;
		} else {
			agingTest = 0x00;
		}
#else
		agingTest = 0xff;
#endif

		send_buf.u8ARG[0] = ERR_OK;
		send_buf.u8ARG[1] = factoryTest;
		send_buf.u8ARG[2] = singleBoardTest;
		send_buf.u8ARG[3] = fullDeviceTest;
		send_buf.u8ARG[4] = agingTest;
		send_buf.u8ArgLen = 5;
		break;
	}
	//Auth: han_frc.20220105.
	case UART_MSG_LED_GROUP_CONTROL_OPCODE: {

		for (uint8_t i = 5; i < 9; i++){
			if(data.u8ARG[i] != 0x00){
				send_buf.u8ARG[0] = ERR_EXEC_FAILED;
			}
		}

		for (uint8_t i = 0; i < 5; i++){
			if(data.u8ARG[i] == 0x81){
				if(send_buf.u8ARG[0] != ERR_EXEC_FAILED){
					LED_OPT_ON(i+1);
					send_buf.u8ARG[0] = ERR_OK;
				}
			}else if(data.u8ARG[i] == 0x80){
				if(send_buf.u8ARG[0] != ERR_EXEC_FAILED){
					LED_OPT_OFF(i+1);
					send_buf.u8ARG[0] = ERR_OK;
				}
			}else{
				if(data.u8ARG[i] == 0x00 && send_buf.u8ARG[0] != ERR_EXEC_FAILED){
				send_buf.u8ARG[0] = ERR_OK;
			  }else{
				send_buf.u8ARG[0] = ERR_EXEC_FAILED;
			  }
			}
		}
		send_buf.u8ArgLen = 1;
		break;
	}
	default:
		break;
	}

	memcpy(pDataOut, (uint8_t *)&send_buf, sizeof(DataField_st));

	if (send_buf.u8ArgLen == 0) { //if cmd exist, lengtg must > 0
		return KET_ERR_CMD_INVALID;
	} else {
		if (port == ECOM_PORT_FCC0) {
			pDataOut->u8Datalen = pDataOut->u8ArgLen;
		} else {
			pDataOut->u8Datalen = pDataOut->u8ArgLen + 3; //AA 55 (opcode(2), ch(1))
		}
		return KET_OK;
	}

}
void kFactoryTestInit(pFactoryTestPollCallback callback, FactoryTestConfSt conf_list[], uint8_t btn_num,uint8_t led_id)
{
	g_eFactoryTestStatus = FTS_NORMAL;
#if FACTORY_TEST_ENABLE
	iKonkeAfSelfPrint("######kFactoryTestInit11111111111111111111111111111111111111\r\n");
	if(NULL == callback || NULL == conf_list || btn_num > AGING_EXIT_MAX_BTN_NUM) {
		return;
	}
	for (uint8_t i = 0; i < btn_num; i++){
		g_stFactoryTestControllerList[i].u8BtnId = conf_list[i].u8BtnId;
		g_stFactoryTestControllerList[i].u8BtnLongPressTimes = conf_list[i].u8BtnLongPressTimes;
		g_stFactoryTestControllerList[i].u32AgingForceExitTimeMs = conf_list[i].u32AgingForceExitTimeMs;
	}


	iKonkeAfSelfPrint("######g_stFactoryTestControllerList[0].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[0].u8BtnId,  g_stFactoryTestControllerList[0].u8BtnLongPressTimes);
	iKonkeAfSelfPrint("######g_stFactoryTestControllerList[1].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[1].u8BtnId,  g_stFactoryTestControllerList[1].u8BtnLongPressTimes);

#if Z30_DEVICE_SINGLE_BOARD_ENABLE //优先级 单板 老化 整机
	if ((g_eFactoryTestStatus == FTS_NORMAL) && (kGetSingleBoardValue() != SINGLE_BOARD_TEST_DONE_VALUE) \
			&& (kGetSingleBoardValue() != FORCE_FACTORY_TEST_VALUE)){

		kBtnaIRQCallbackRegister(kFactoryTestBtnActionCallback);

		g_eFactoryTestStatus = FTS_SINGLE_BOARD_TEST;
		g_pFactoryTestPollCallback = callback;
		g_u8FactoryTestLedId = led_id;

		if(kFactoryTestEvt){
			TL_ZB_TIMER_CANCEL(&kFactoryTestEvt);
		}
		kFactoryTestEvt = TL_ZB_TIMER_SCHEDULE(kFactoryTestEventHandler, NULL, 1000);
	}
#endif

#if Z30_DEVICE_AGING_ENABLE
	if ((g_eFactoryTestStatus == FTS_NORMAL) && (kGetAgingTestValue() != AGINE_TEST_DONE_VALUE) \
			&& (kGetAgingTestValue() != FORCE_FACTORY_TEST_VALUE)){
		kSetAgingTestValue(AGING_TEST_15MIN_VALUE);
		kBtnaIRQCallbackRegister(kFactoryTestBtnActionCallback);

		g_eFactoryTestStatus = FTS_START;
		g_pFactoryTestPollCallback = callback;
		g_u8FactoryTestLedId = led_id;
		g_u32AgingTotalTimeMS = 0;
		//load aging time
		g_u32AgingMaxTimeMS = kGetAgingMaxTime();

		if(kFactoryTestEvt){
			TL_ZB_TIMER_CANCEL(&kFactoryTestEvt);
		}
		kFactoryTestEvt = TL_ZB_TIMER_SCHEDULE(kFactoryTestEventHandler, NULL, 1000);
	}
#endif

#if Z30_DEVICE_FULL_DEVICE_ENBALE
	if ((g_eFactoryTestStatus == FTS_NORMAL) && (kGetFullDeviceValue() != FULL_DEVICE_TEST_DONE_VALUE) \
			&& (kGetFullDeviceValue() != FORCE_FACTORY_TEST_VALUE)){

		kBtnaIRQCallbackRegister(kFactoryTestBtnActionCallback);
		g_eFactoryTestStatus = FTS_FULL_DEVICE_TEST;
		g_pFactoryTestPollCallback = callback;
		g_u8FactoryTestLedId = led_id;

		if(kFactoryTestEvt){
			TL_ZB_TIMER_CANCEL(&kFactoryTestEvt);
		}
		kFactoryTestEvt = TL_ZB_TIMER_SCHEDULE(kFactoryTestEventHandler, NULL, 1000);
	}
#endif
	iKonkeAfSelfPrint("\r\n######kFactoryTestInit status1111111111111111111111111(%d)\r\n", g_eFactoryTestStatus);
	//led indicate
	if (g_eFactoryTestStatus == FTS_SINGLE_BOARD_TEST) {
		kLedOptTrigger(g_u8FactoryTestLedId, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_OFF);
	} else if (g_eFactoryTestStatus == FTS_FULL_DEVICE_TEST) {
		kLedOptTrigger(g_u8FactoryTestLedId, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 2, LED_ON, LED_OFF);
	} else if (g_eFactoryTestStatus == FTS_START) {
		kLedOptTrigger(g_u8FactoryTestLedId, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_OFF);
	}

#else
	uint8_t value = TEST_INIT_VALUE;
	kSetAgingTestValue(value);
	kSetSingleBoardValue(value);
	kSetFullDeviceValue(value);
	g_eFactoryTestStatus = FTS_NORMAL;
#endif
}


s32 kFactoryTestEventHandler(void *arg)
{
//	iKonkeAfSelfPrint("######kFactoryTestEventHandler status(%d)\r\n", g_eFactoryTestStatus);

	g_u32AgingTotalTimeMS += FACTORY_TEST_POLL_TTME_1S;

	if (g_eFactoryTestStatus != FTS_WAITING_RELEASED && g_eFactoryTestStatus != FTS_WAITING_SECOND_PRESS){
		switch (g_eFactoryTestStatus)
		{
			case (FTS_START):
				//g_eFactoryTestStatus = FTS_AGING_15MIN;
				g_u32Count = FACTORY_TEST_POLL_TIMES;
				break;
			case (FTS_AGING_15MIN):
				//上电后15分钟时间到，15分钟内可以短按按键和长按，但不能组网
				if (g_u32AgingTotalTimeMS >= FACTORY_TEST_15MIN_MS){
					kSetAgingTestValue(AGING_TEST_4HOU_VALUE);
					g_eFactoryTestStatus = FTS_AGING_4HOU_START;
					//15分钟后重新开始计时
					g_u32AgingTotalTimeMS = 0;
					g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
				}
				break;
			case (FTS_AGING_4HOU_START):
					//可以设置所有的LED状态一致，在回调函数实现
					g_eFactoryTestStatus = FTS_AGING_4HOU;
				break;
			case (FTS_AGING_4HOU):
				//上电后4小时老化时间到，4小时内不可以短按按键和长按，不能组网
				if (g_u32AgingTotalTimeMS >= g_u32AgingMaxTimeMS){
					kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
					g_eFactoryTestStatus = FTS_AGING_DONE;
				}
				break;
			case (FTS_AGING_DONE):
				//老化完退出当前事件
				//return;
				g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
				break;
			case (FTS_FORCE_EXIT):
				g_eFactoryTestStatus = FTS_WAITING_RELEASED;
				break;
			case (FTS_WAITING_RELEASED):
				break;
			case (FTS_FIRST_LONG_PRESSED):
				g_eFactoryTestStatus = 	FTS_WAITING_SECOND_PRESS;
				break;
			case (FTS_WAITING_SECOND_PRESS):
				break;
			//Auth: han_frc.20220105.
			case (FTS_NORMAL):
		        iKonkeAfSelfPrint("######FTS_NORMAL STOP EVENT!!!!!!!!!!!\r\n");
				return -1;
			default:
				break;
		}
	}

	for (uint8_t index = 0; index < AGING_EXIT_MAX_BTN_NUM; index++){
		if (g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ){
			if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED \
					&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_PRESSED){

				g_stFactoryTestControllerList[index].elastBtnAction = EBA_PRESSED;
				//g_stFactoryTestControllerList[index].eCurrentBtnAction = EBA_PRESSING;
				//重置长按倒计时计数
				g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = \
						g_stFactoryTestControllerList[index].u32AgingForceExitTimeMs / FACTORY_TEST_POLL_TTME_1S;
			}else if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_RELEASED \
					&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_RELEASED){
				iKonkeAfSelfPrint("&&&&&&& EBA_RELEASED u32AgingForceExitTimeCounter == %d\r\n",\
						g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter);
				g_stFactoryTestControllerList[index].elastBtnAction = EBA_RELEASED;
				g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = 0;
			}else {
				 g_stFactoryTestControllerList[index].elastBtnAction  = g_stFactoryTestControllerList[index].eCurrentBtnAction;
			}
			//倒计时20S或5S
			if (g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter > 0 \
					&& g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED){

				iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter-- %d\r\n", \
						g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter);

				if (--g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter == 0){

					iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter == 0\r\n");

					if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_1_TIMES \
							|| g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed == true){
						//successfully exit aging test
						g_eFactoryTestStatus = FTS_FORCE_EXIT;
						kSetAgingTestValue(FORCE_FACTORY_TEST_VALUE);
#if Z30_DEVICE_SINGLE_BOARD_ENABLE
						if(kGetSingleBoardValue() != SINGLE_BOARD_TEST_DONE_VALUE)
							kSetSingleBoardValue(FORCE_FACTORY_TEST_VALUE);
#endif
#if Z30_DEVICE_FULL_DEVICE_ENBALE
						if(kGetFullDeviceValue() != FULL_DEVICE_TEST_DONE_VALUE)
							kSetFullDeviceValue(FORCE_FACTORY_TEST_VALUE);
#endif
						g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数
						//防止老化状态被重置
						g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = 0;
						g_u8LongPressedKeyIndex = index;
						//g_u32AgingTotalTimeMS = FACTORY_TEST_12HOU_MS;
						iKonkeAfSelfPrint("######11111111111 == 0\r\n");
					}else if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){
						//触摸按键需要长按两次才能退出老化
						g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = true;
						g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = \
								(FIRST_BTN_LONG_PRESSED_VALIED_TIME_MS + FACTORY_TEST_POLL_TTME_1S)/ FACTORY_TEST_POLL_TTME_1S;
						g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
						//记录当前的老化状态
						g_eLastFactoryTestStatus = g_eFactoryTestStatus;
						g_eFactoryTestStatus = FTS_FIRST_LONG_PRESSED;

						iKonkeAfSelfPrint("######2222222222222222222222 == 0\r\n");
					}
				}
			}else {
				//g_stFactoryTestControllerList[index].elastBtnAction = g_stFactoryTestControllerList[index].eCurrentBtnAction;
			}

			//第二次长按有效时间倒计时
			if (g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown > 0 && g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){
				if (--g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown == 0){
					g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = false;
					//恢复之前老化状态
					g_eFactoryTestStatus = g_eLastFactoryTestStatus;
				}
			}
		}
	}

	//10S执行一次自定义老化,有时会根据不同状态会更新减短时间，让更快执行
	if (g_u32Count++ >= FACTORY_TEST_POLL_TIMES){
		g_u32Count = 0;
		//用户自定义老化测试方案
		if (g_pFactoryTestPollCallback){
			g_pFactoryTestPollCallback(g_eFactoryTestStatus);
		}

		if (g_eFactoryTestStatus == FTS_START){
			g_eFactoryTestStatus = FTS_AGING_15MIN;
		}else if (g_eFactoryTestStatus == FTS_AGING_DONE){
			//老化结束退出当前事件
			return 0;
		}
	}
	return 0;
}

//Auth: han_frc.20220105.
void kSetAgingTestDone(void)
{
  kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
  g_eFactoryTestStatus = FTS_NORMAL;
}

void kSetNetworkSteeringInfo(uint8_t channel, uint16_t PanId)
{
  if (channel >= 15 && channel <= 26){
    g_u8NetworkSteeringChannel = channel;
  }

  if (0xFFFF != PanId){
    g_u16NetworkSteeringPanId = PanId;
  }
}
