#include <stdarg.h>
#include "yc11xx_uart.h"
#include "yc11xx_gpio.h"
#include "yc_timer.h"
#include "ipc.h"
#include "yc11xx_wdt.h"
#include "Drv_debug.h"
#include "yc_lpm.h"
#include "att.h"
#include "yc11xx_bt_interface.h"
#include "system.h"
#include "core_cm0.h"

SYS_TIMER_TYPE gAdv_Timer;
SYS_TIMER_TYPE gConnect_Timer;
BLE_STATE gBLEState;

void Bt_init()
{
	gBLEState.topState = BLE_IDLE;
	gBLEState.secondState = BLE_IDLE;
}

void Bt_setBLEState(uint8_t inState)
{
	switch (inState){
		case BLE_IDLE:
		case BLE_ADV:
		case BLE_CONNECTED:
		case BLE_CONNECTING:
		case BLE_DIRECT_ADV:
		case BLE_PAIRED:
			gBLEState.topState = inState;
		default:
			break;
	}
}

void Bt_StartAdv(int time_10ms,uint16_t gap){
	Bt_setBLEState(BLE_ADV);
	Bt_SetLeAdvInterval(gap);
	Lpm_Set_Interval(gap);
//	SYS_SetTimer(&gAdv_Timer,time_10ms,TIMER_SINGLE|TIMER_TYPE_BIT,Bt_stop_adv);
	Bt_SndCmdLeStartAdv();
}

void Bt_lpm_enable(int none){
	Lpm_unLockLpm(CONNECT_WAKE_FLAG);
}

void Bt_EvtCallBack(uint8_t len,uint8_t *dataPtr)
{

	switch(*dataPtr)
	{	
		case IPC_EVT_LE_DISCONNECTED:		//断连
			gBLEState.topState = BLE_IDLE;
			Lpm_ClearLpmFlag();
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n***************IPC_EVT_LE_DISCONNECTED***************\r\n");
			#endif
			Bt_StartAdv(60,0x80);
			break;
		case IPC_EVT_LE_CONNECTED:			//连接
			Bt_SndCmdLeUpdateAttMTU();
			IPC_TxControlCmd(IPC_CMD_UPDATE_CONN);
			SYS_ReleaseTimer(&gAdv_Timer);
			Lpm_unLockLpm(ADV_FLAG);
			Lpm_LockLpm(CONNECT_WAKE_FLAG);
			Bt_setBLEState(BLE_CONNECTED);
			SYS_SetTimer(&gConnect_Timer,400,TIMER_SINGLE|TIMER_TYPE_BIT,Bt_lpm_enable);
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n***************IPC_EVT_LE_CONNECTED***************\r\n");
			#endif
			break;
		case IPC_EVT_BB_CONNECTED:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_BB_CONNECTED*****************\r\n");
			#endif
			break;
		case IPC_EVT_SETUP_COMPLETE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_SETUP_COMPLETE*****************\r\n");
			#endif
			break;
		case IPC_EVT_BT_PAIRING_SUCCESS:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_BT_PAIRING_SUCCESS*****************\r\n");
			#endif
			break;
		case IPC_EVT_LINKKEY_GENERATE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_LINKKEY_GENERATE*****************\r\n");
			#endif
			break;
		case IPC_EVT_RESET:	//上电
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_RESET*****************\r\n");
			#endif
		//	Bt_Reset();	
			break;
		case IPC_EVT_WAKEUP:		//唤醒
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_WAKEUP*****************\r\n");
			#endif
//			SysTick_Config(SYSTEM_CLOCK/100); //each  systick interrupt is 10ms
			OS_EXIT_CRITICAL();		
			break;
		case IPC_EVT_LE_TK_GENERATE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_LE_TK_GENERATE*****************\r\n");
			#endif			
			break;
		
		case IPC_EVT_LE_DISCONNECTED_ABNORMAL:
				#ifdef DEBUG_DRV_BT
				MyPrintf("\r\n******************IPC_EVT_LE_DISCONNECTED_ABNORMAL******************\r\n");
				#endif
				break;
		default:
			break;
	}
	HWRITE(mem_save_state,gBLEState.topState);
	return;
}

#define ATT_WRITE_REQUEST 0x12
#define ATT_PREPARE_WRITE_REQUEST	0x16
#define ATT_WRITE_COMMAND 0X52

void Bt_SndWriteResponse()
{
	IPC_TxControlCmd(IPC_CMD_SEND_WRITE_RESPONSE);
}

void Bt_BleCallBack(uint8_t len,uint8_t *dataPtr)
{
	uint16_t handle;
	uint8_t opcode;
	opcode = dataPtr[0];
	handle = dataPtr[1] +(dataPtr[2]<<8);
//	MyPrintf("opcode=%x\r\n",opcode);
//	MyPrintf("handle=%x\r\n",handle);
	switch(opcode) 
	{
		case ATT_WRITE_REQUEST:
			switch(handle)
			{
				case 0x0004:
					break;
				case 0x000e:
					break;
				case 0x0011:
					break;
			}
			Bt_SndWriteResponse();
			
			 break;
		case ATT_PREPARE_WRITE_REQUEST:
			switch(handle)
			{
				case 0x001c:
					break;
			}			
			 break;
		case ATT_WRITE_COMMAND:	
			switch(handle)
			{
				case 0x001c:
					USART_SendDataFromBuff(UARTB,dataPtr+3,len-3);
		//			Bt_SndBleData(0x001e,dataPtr+2,len-2);
				break;
			}	
				break;
	}
}

void Bt_Reset()
{
	uint8_t advD[19] = {0x02,0x01,0x06,0x05,0x03,0x12,0x18,0x0f,0x18,0x03,0x19,0x80,0x01};
	uint8_t addr[6]  = {0xac,0x02,0x78,0x11,0x43,0Xac};
	uint8_t name[11] = {"11XXBLE"};
	Bt_Re_LeAdvName(name,11);
	Bt_Renew_Le_ScanRsp(advD,19);							//设置广播参数
 	Bt_SetLeMac(addr);									//设置蓝牙地址
	Bt_Re_LeDeivcename(name,11);
	Bt_init();
//	Lpm_enter();					//
	Lpm_Set_Conn_Interval(0x1a0);
	Bt_StartAdv(100,0x80);
}


tIPCHandleCb gTIPCHandleCb[IPC_TYPE_NUM]=
{
	0,
	IpcDefaultCallBack,//cmd
	Bt_EvtCallBack,//evt					//evt回调函数,函数在drv_bt.c实现
	IpcDefaultCallBack,//hid
	IpcDefaultCallBack,//spp
	Bt_BleCallBack,//ble					//ble data回调函数,函数在drv_bt.c实现
	IpcDefaultCallBack,//24g
	IpcDefaultCallBack,//mesh
	IpcDefaultCallBack,//mesh
	IpcDefaultCallBack,//mesh
	IpcDefaultCallBack,//a2dp
	IpcDefaultCallBack,//hfp
	IpcDefaultCallBack
};

int main()
{
	if(HREAD(mem_wake_flag)==POWERON_WAKE)
	{
			IPC_init(&gTIPCHandleCb);			//蓝牙回调函数初始化
			SYS_TimerInit();
			Att_profile_Config();   // ble profile set
			
			printport_init();
			MyPrintf("\r\n************************This is Lpm test demo*************\r\n");
			Bt_Reset();	
			Lpm_enter();
	}
	else
	{
		printport_init();
		SysTick_Config(SYSTEM_CLOCK/1000); 
	}
	SYS_ClkTicks();
	while (1) {
		switch (HREAD(IPC_MCU_STATE))
		{
			case IPC_MCU_STATE_RUNNING:
				IPC_HandleRxPacket();						//m0和bt交互数据类型判断,是evt还是ble data?并执行对应回调函数
				SYS_timerPolling();
				Lpm_unLockLpm(M0_LPM_FLAG);		
				break;
			case IPC_MCU_STATE_LMP:			//lpm
				if (IPC_IsTxBuffEmpty())
				{
					OS_ENTER_CRITICAL();
					Bt_ActionBeforeLpm();
					HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_STOP);
				}
				else{
					HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_RUNNING);
				}
				break;
			case IPC_MCU_STATE_HIBERNATE:		//	HIBERNATE
				OS_ENTER_CRITICAL();
				Bt_ActionBeforeHibernate();
				HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_STOP);
				break;
			case IPC_MCU_STATE_STOP:
				break;
		}
	}
}