/**********************************************************************
 * INCLUDES
 */
#include "tl_common.h"
#include "zb_api.h"
#include "zcl_include.h"
#include "ikk-interpan.h"
#include "ikk-debug.h"
#include "ikk-token.h"
#include "ikk-network.h"


static bool gInterPanEnabled;  // 1:enable
static uint16_t gInterPanID  = 0x1111;  // 1:enable
static uint8_t  g_interpanChannel = 20;

pInterPanMsgIncomingCallback gInterPanMsgIncomingCallback;

static ev_timer_event_t *Interpan_timerEvt = NULL;
static ev_timer_event_t *Interpan_DelaySendEvt = NULL;

static INCOM_MESSAGE_INFO  sIncomingMessageInfo = {0};

static  s32 kInterPanEventHandler(void);
static s32 kInterPanDelaySendTestDataEventHandler(void );
/**
 *  @brief Definition for Incoming cluster / Sever Cluster
 */
const u16 kInterpan_inClusterList[] =
{
	ZCL_CLUSTER_INTERPAN_REQ,
};


/**
 *  @brief Definition for Outgoing cluster / Client Cluster
 */
const u16 kInterpan_outClusterList[] =
{
	ZCL_CLUSTER_INTERPAN_REQ,
};

/**
 *  @brief Definition for Server cluster number and Client cluster number
 */
#define KINTERPAN_IN_CLUSTER_NUM		(sizeof(kInterpan_inClusterList)/sizeof(kInterpan_inClusterList[0]))
#define KINTERPAN_OUT_CLUSTER_NUM		(sizeof(kInterpan_outClusterList)/sizeof(kInterpan_outClusterList[0]))

/**
 *  @brief Definition for simple description for HA profile
 */
const af_simple_descriptor_t kInterpanSimpleDesc =
{
	ZDO_PROFILE_ID,                      /* Application profile identifier */
	HA_DEV_ONOFF_LIGHT_SWITCH,           /* Application device identifier */
	INTERPAN_ENDPOINT,               /* Endpoint */
	0,                                  /* Application device version */
	0,									/* Reserved */
	KINTERPAN_IN_CLUSTER_NUM,         /* Application input cluster count */
	KINTERPAN_OUT_CLUSTER_NUM,        /* Application output cluster count */
	(u16 *)kInterpan_inClusterList,    /* Application input cluster list */
	(u16 *)kInterpan_outClusterList,   /* Application output cluster list */
};



void afInterpan_rx_handler(void *arg)
{
	apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
	UMsgNodeSt *pMsgNode = (UMsgNodeSt *)pApsdeInd->indInfo.asdu;
	pMsgNode->length	 = pApsdeInd->indInfo.asduLength;
	sIncomingMessageInfo.seq 		= pApsdeInd->indInfo.aps_counter;
	sIncomingMessageInfo.src_ep 	= pApsdeInd->indInfo.src_ep;
	sIncomingMessageInfo.src_addr_mode = pApsdeInd->indInfo.src_addr_mode;

	if(pApsdeInd->indInfo.src_addr_mode == APS_LONG_DSTADDR_WITHEP)
		memcpy(sIncomingMessageInfo.src_ext_addr,pApsdeInd->indInfo.src_ext_addr,8);
	else if(pApsdeInd->indInfo.src_addr_mode == APS_SHORT_DSTADDR_WITHEP)
		sIncomingMessageInfo.src_short_id = pApsdeInd->indInfo.src_short_addr;

	iKonkeAfSelfPrint("afInterpan_rx_handler,data len =%d\r\n",pApsdeInd->indInfo.asduLength);
	iKonkeAfSelfPrintBuffer(pApsdeInd->indInfo.asdu,pApsdeInd->indInfo.asduLength);
	switch(pApsdeInd->indInfo.cluster_id){
		case ZCL_CLUSTER_INTERPAN_REQ:
			gInterPanMsgIncomingCallback(pMsgNode);
			break;
		default:
			break;
	}

	/* Must be free here. */
	ev_buf_free((u8 *)arg);
}

void afInterpan_dataSendConfirm(void *arg)
{
	apsdeDataConf_t *pApsDataCnf = (apsdeDataConf_t *)arg;
	printf("afInterpan_dataSendConfirm,dest ep = %d\r\n!!\r\n",pApsDataCnf->dstEndpoint);
}



void kInterPanEnable(uint8_t channel)
{
	rf_setChannel(channel);
	printf("kInterPanEnable enable,Regesiter Interpan Func,network = %d\r\n!!\r\n",kNwkGetCurrentStatus());
	if (kNwkGetCurrentStatus() == ENS_LEAVED) {

		af_endpointRegister(INTERPAN_ENDPOINT, (af_simple_descriptor_t *)&kInterpanSimpleDesc, afInterpan_rx_handler, afInterpan_dataSendConfirm);
	}
	else{
		kNwkFactoryReset(false);
	}
}

void kInterpanDisable(void)
{
	if (gInterPanEnabled ==true) {
		af_endpointUnregister(INTERPAN_ENDPOINT);

		kInterPanSetEnableStatus(false);

		if(Interpan_DelaySendEvt){
			TL_ZB_TIMER_CANCEL(&Interpan_DelaySendEvt);
		}
	}
}

void kInterPanMoudleInit(pInterPanMsgIncomingCallback pfunc_incoming)
{

	bool interPanEnabledFlg = kGetInterpanEnableFlg();
	if (interPanEnabledFlg) {
		gInterPanEnabled = true;
	}
	if (gInterPanEnabled == true) {
		kInterPanEnable(INTERPAN_CHANNEL);

		if(Interpan_timerEvt){
			TL_ZB_TIMER_CANCEL(&Interpan_timerEvt);
		}
		Interpan_timerEvt = TL_ZB_TIMER_SCHEDULE(kInterPanEventHandler, NULL, INTERPAN_AUTO_OFF_TIME);
		if (kNwkGetCurrentStatus() == ENS_LEAVED) {
			if(Interpan_DelaySendEvt)
				TL_ZB_TIMER_CANCEL(&Interpan_DelaySendEvt);

			Interpan_DelaySendEvt = TL_ZB_TIMER_SCHEDULE(kInterPanDelaySendTestDataEventHandler, NULL, INTERPAN_DELAY_SEND_INTERVAL);
		}
	}
	gInterPanMsgIncomingCallback = pfunc_incoming;
}
static void afTest_dataSendDemo(void)
{
	epInfo_t dstEp;
	TL_SETSTRUCTCONTENT(dstEp, 0);

	//uint8_t aucData[] = {0x5C,0x2B,0xCD,0xFE,0xFF,0x27,0xFD,0x84};

	dstEp.dstAddrMode 		= APS_SHORT_DSTADDR_WITHEP;
	dstEp.dstEp 			= 5;
	dstEp.dstAddr.shortAddr	= 0xFFFF;
	dstEp.profileId			= ZDO_PROFILE_ID;
	dstEp.txOptions			= APS_TX_OPT_INTRA_PAN;
	dstEp.radius			= 0;

	g_zbMacPib.panId        = gInterPanID;

	u8 apsCnt = 0;

	u8 asdu[] = {0xAA, 0x55, 0x00, 0x09, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0d, 0x00, 0xF3, 0xD0,0xFF};
	u8 asdulength = sizeof(asdu);
	af_dataSend(5, &dstEp, 0x0001, asdulength, asdu, &apsCnt);
	printf("afTest_Receive--------------ok!!\r\n");
}

/**
 * @description:
 * @param {*}
 * @return {*}
 */
bool kInterPanSetEnableStatus(uint8_t enable)
{
	gInterPanEnabled = enable;

	kSetInterpanEnableFlg(!gInterPanEnabled);
}
void SetInterpanPara(uint8_t channel,uint16_t panid,bool is_enable)
{

	if(panid != 0xffff)
		gInterPanID = panid;
	if((channel != 0xff)&&(channel>=11)&&(channel<=26))
		g_interpanChannel = channel;
	if(is_enable)
	{
		gInterPanEnabled = TRUE;
		kSetInterpanEnableFlg(gInterPanEnabled);
	}
	else
		kInterpanDisable();
}
static uint8_t sSend_Count = 0;
static s32 kInterPanDelaySendTestDataEventHandler(void )
{
	if(sSend_Count < INTERPAN_DELAY_SEND_TIMES)
	{
		sSend_Count++;
		afTest_dataSendDemo();			//for coo find this device
		return 0;
	}
	sSend_Count = 0;
	return -1;
}
static s32 kInterPanEventHandler(void)
{
	iKonkeAfSelfPrint("kInterPanEventHandler\r\n");

	if (gInterPanEnabled ==true) {
		af_endpointUnregister(INTERPAN_ENDPOINT);

		kInterPanSetEnableStatus(false);
	}
	return -1;
}

kk_err_t kInterPanSend(UMsgNodeSt *pMsgNode)
{
	epInfo_t dstEp;
	kk_err_t err = KET_OK;
	TL_SETSTRUCTCONTENT(dstEp, 0);

	dstEp.dstAddrMode	= sIncomingMessageInfo.src_addr_mode;

	if(sIncomingMessageInfo.src_addr_mode == APS_LONG_DSTADDR_WITHEP)
		memcpy(dstEp.dstAddr.extAddr,sIncomingMessageInfo.src_ext_addr,8);
	else if(sIncomingMessageInfo.src_addr_mode == APS_SHORT_DSTADDR_WITHEP)
		dstEp.dstAddr.shortAddr = sIncomingMessageInfo.src_short_id;

	dstEp.dstEp 			= sIncomingMessageInfo.src_ep;
	dstEp.profileId			= ZDO_PROFILE_ID;
	dstEp.txOptions			= APS_TX_OPT_INTRA_PAN;
	dstEp.radius			= 0;
	g_zbMacPib.panId        = gInterPanID;

	u8 apsCnt = sIncomingMessageInfo.seq;

	af_dataSend(INTERPAN_ENDPOINT, &dstEp, ZCL_CLUSTER_INTERPAN_REQ, pMsgNode->length, pMsgNode->buffer, &apsCnt);
	return err;
}

/**
 * @description:
 * @param {*}
 * @return {*}
 */
bool kInterPanGetEnableStatus(void)
{
	return gInterPanEnabled;
}
