#include <stdio.h>
#include "Drv_bt.h"
#include "ipc.h"
#include "yc_timer.h"
#include "yc_it.h"
#include "drv_ota.h"
#include "yc_drv_common.h"
#include "yc_lpm.h"
#include "system.h"
#include "core_cm0.h"

#define DEBUG_DRV_BT

#undef INFO_HEADER
#define INFO_HEADER "DRVBT"

#ifndef ATT_LIST_LEN
#define	ATT_LIST_LEN    mem_rc_att_list_end-mem_rc_att_list
#endif

SYS_TIMER_TYPE OTA_sleep_timer;
SYS_TIMER_TYPE gAdv_Timer;
BR_STATE gBRState;
BLE_STATE gBLEState;
#ifdef PACKET_LEN_100

//SYS_TIMER_TYPE gMTU_Timer;
#endif
#define Flash_BLE_ADDR 0x7f000	
SYS_TIMER_TYPE gConnect_Timer;


void Ble_SendBleData(uint16_t BLE_WRITE_HANDLE,uint8_t* data, uint16_t len)//eg handle = 0x0008
{
  uint8_t buf[len+2];		
  if(len<0 || len>20)
  	 return;
  uint8_t BleSendData[30]={0};
  buf[0]= BLE_WRITE_HANDLE&0xff; 
  buf[1]= (BLE_WRITE_HANDLE>>8)&0xff;
  memcpy(buf+2,data,len);
  Bt_SndBleData(buf,len+2);
}

void Bt_SetBleAddr(unsigned char* pAddr)
{
	int AddrLen = 6;
	for(int i=0; i<AddrLen; i++){
		HWRITE(mem_le_lap+i,pAddr[i]);
	}
}

void Bt_SetSppAddr(unsigned char* pAddr)
{
	int AddrLen = 6;
	for(int i=0; i<AddrLen; i++){
		HWRITE(mem_lap+i,pAddr[i]);
	}
}

void Bt_SetSppName(unsigned char* Name,int Len)
{
	if(Len>27)
		return;
	for(int i=0;i<Len;i++)
	{
		HWRITE(mem_local_name_length+1+i,*(Name+i));
	}	
}



void Bt_Re_BleAdvName(uint8_t *name,uint8_t len)
{
	HWRITE(mem_le_adv_data,len+1);
	HWRITE(mem_le_adv_data+1,Adv_Type_CompleteLocalName);	
	for(uint8_t i=0;i<len; i++)
		{
		/* adv data add name  */
		HWRITE(mem_le_adv_data+2+i,name[i]);
	}
	HWRITE(mem_le_adv_data_len,len+1);
}

void Bt_Re_BleDeivcename(uint8_t *name,uint8_t len)
{
	int i;
	int cache_len,oldname_len;

	uint8_t att_list[ATT_LIST_LEN];
	memset(att_list,0,ATT_LIST_LEN);
	oldname_len=HREAD(mem_rc_att_list+20);
	cache_len =  ATT_LIST_LEN-21-oldname_len;
	#ifdef DEBUG_DRV_BT
	MyPrintf("cache_len=%d\r\n",cache_len);
	#endif
	for(i=0;i<cache_len;i++)
	{
		att_list[i]=HREAD(mem_rc_att_list+21+oldname_len+i);
	}
	#ifdef DEBUG_DRV_BT
	for(i=0;i<20;i++)
	{
		MyPrintf("att_list[%d]=%02x  \r\n",i,att_list[i]);
	}
	#endif
	HWRITE(mem_rc_att_list+20,len);
	for(i=0; i<len; i++){
		HWRITE(mem_rc_att_list+21+i,*(name+i));
	}

	for(i=0;i<cache_len;i++){
		HWRITE(mem_rc_att_list+21+len+i,att_list[i]);
	}
}

void Bt_Renew_Adv_Data(uint8_t *data,uint8_t len)
{
	uint8_t length=0;
	if(len > LE_ADV_DATA_MAX_LENGTH)
		return;
	HWRITE(mem_le_adv_enable,ADV_DISABLE);
	while(len--)
	{
		HWRITE(mem_le_adv_data+length,*data);
		data++;
		length++;
	}
	HWRITE(mem_le_adv_data_len,length);
}

void Bt_Renew_Scan_Rsp(uint8_t *data,uint8_t len)
{
	uint8_t length=0;
	if(len > LE_SCAN_RSP_MAX_LENGTH)
		return;
	HWRITE(mem_le_adv_enable,ADV_DISABLE);
	while(len--)
	{
		HWRITE(mem_le_scan_data+length,*data);
		data++;
		length++;
	}
	HWRITE(mem_le_scan_data_len,length);
}

void Bt_SetAdvType(advType Type)
{
	HWRITE(mem_le_adv_type, Type);
}

void Bt_SetScanRspType(scanType Type)
{
	HWRITE(mem_le_scan_type, Type);
}

void Update_connection_param(BLE_Conn_param* param)
{
	HWRITEW(mem_le_connection_updata_param,param->min_interval);
	HWRITEW(mem_le_connection_updata_param+2,param->max_interval);
	HWRITEW(mem_le_connection_updata_param+4,param->latency);
	HWRITEW(mem_le_connection_updata_param+6,param->timeout);		
	IPC_TxControlCmd(IPC_CMD_UPDATE_CONN);
}

void Bt_SetAdvInterval(uint16_t gap)
{
	HWRITEW(mem_le_adv_interval_max,gap);
}

void Bt_init()
{
	gBRState.topState = BR_IDLE;
	gBRState.secondState=BR_IDLE;
	gBRState.thirdlyState = BR_IDLE;

	gBLEState.topState = BLE_IDLE;
	gBLEState.secondState = BLE_IDLE;
}

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

void Bt_StartDirectAdv(int time_10ms, uint16_t gap){
	Bt_SetAdvInterval(gap);
	Lpm_Set_Interval(gap);
	Bt_setBLEState(BLE_DIRECT_ADV);
//	SYS_SetTimer(&gAdv_Timer,time_10ms,TIMER_SINGLE|TIMER_TYPE_BIT,Bt_send_stop_direct_adv);
	Bt_SndCmdBleStartDirectAdv();
}


uint8_t Bt_checkBleIsConnected()
{
	if(gBLEState.topState == BLE_CONNECTED)
		return 1;
	return 0;
}

uint8_t Bt_checkBRIsConnected()
{
	if(gBRState.topState == BR_CONNECTED)
		return 1;
	return 0;
}

void BT_OTA_Sleep_func(int i){
	Lpm_unLockLpm(OTA_UPDATE_FLAG);	
}

uint8_t Bt_checkBleIsAdvStart()
{
	
	if(gBLEState.topState == BLE_ADV)
		return 1;
	return 0;
}

BLE_STATE_TYPE Bt_getBLEState(){
	return gBLEState.topState;
}

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;
	}
	//HWRITE(mem_save_state,gBLEState.topState);
}

void Bt_force_disconn(){
	Bt_SndCmdBleDisconnect();
	Bt_SndCmdPwroff();
}

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_BleAdvName(name,11);
	Bt_Renew_Scan_Rsp(advD,19);							//设置广播参数
 	Bt_SetBleAddr(addr);									//设置蓝牙地址
	Bt_Re_BleDeivcename(name,11);
	Bt_init();
//	Lpm_enter();					//
	Lpm_Set_Conn_Interval(0x1a0);
	Bt_StartAdv(100,0x80);
}


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_SndCmdUpdateAttMTU( );
			Bt_SndCmdLeUpdateConn( );
			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;
}

void Bt_BleCallBack(uint8_t len,uint8_t *dataPtr)
{
	uint16_t handle;
	handle = dataPtr[0] +(dataPtr[1]<<8);
	switch(handle){
		case OTA_BLE_WRITE_HANDLE:			//ota write handle
			Lpm_LockLpm(OTA_UPDATE_FLAG);		//停止进入休眠
			Bt_BleOTA(len, dataPtr);			//ota 升级
			SYS_SetTimer(&OTA_sleep_timer,50,TIMER_SINGLE|TIMER_TYPE_BIT,BT_OTA_Sleep_func);
			SYS_ResetTimer(&OTA_sleep_timer);
			break;
		
		case 0x001a:
			for(int i=0;i<len;i++)
			{

			}						
			break;
		case 0x0017:
			for(int i=0;i<len;i++)
			{
			}
			Ble_SendBleData(0x0016,dataPtr,len);
			break;
		default:
			break;
	}
}