
#include "function_interface.h"
#include "platform_interface.h"
#include "base_core_user.h"
#include "function.h"
#include "string.h"


struct fastmatch_STR{
	volatile unsigned char flag;
	unsigned char chan;
	unsigned short keypad_id;	
	unsigned char lowPA;
};
struct fastmatch_STR fastmatch={
	.flag =0,
};






/*
检测 pc设置投票信标类型是否是快速配对 40 
called by pc设置投票信标
*/
void fastmatch_enter_exit(const unsigned char *rxpc)
{
	//表决器协议 2.2.16 
	//fast match enter
	if(rxpc[5]==40){
		if(rxpc[6]==0) return;
		fastmatch.flag=1;
		fastmatch.keypad_id= (rxpc[8]<<8)+rxpc[9];
		if(rxpc[6]==1)
			fastmatch.chan =0;
		else
			fastmatch.chan =81;	//?? 快速配对2 ??
		
		//AES --进入快速配对时，更新一次秘钥
		function.aes__keycode_upgrade();		
	}
	else{
		if(fastmatch.flag){//exit fast match,切换到配对前的频点
			fastmatch.flag=0;
			platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_mainRF_hard_id());//platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_main_rf_id());		
		}
	}
	
}




/*
快速配对模式下，加载相关数据到投票信标中
called by 基站发送投票信标
*/
unsigned char fastmatch_load_info_to_vote_beacon(unsigned char *ptr)
{
		static unsigned char chan_trigger=0;//做频率交替标志flag //??????Gavin 
		if(!fastmatch.flag) return 0;	
	
		//CRS2模式下如何处理 ?? 为何CRS2协议下不切换到工作频点发数据??
		if(chan_trigger==0){
//		if(chan_trigger){			
			platform.rf_set_freq(fastmatch.chan,base_core.get_mainRF_hard_id());//platform.rf_set_freq(fastmatch.chan,base_core.get_main_rf_id());
			ptr[10] =1;
			ptr[11] =base_core.get_main_rf_chan();//get_base_main_rfchannel();
			ptr[12] =fastmatch.keypad_id>>8;
			ptr[13] =fastmatch.keypad_id;			
		}
		else{		
			platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_mainRF_hard_id());//platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_main_rf_id());
			if(function.crs2__SW){//crs2协议下??
				ptr[10] =1;
				ptr[11] =base_core.get_main_rf_chan();//get_base_main_rfchannel();
				ptr[12] =fastmatch.keypad_id>>8;
				ptr[13] =fastmatch.keypad_id;	
			}
			else{
				ptr[10] =0;
				ptr[11] =0;
				ptr[12] =0;
				ptr[13] =0;
			}
		}
		
		//AES---
		function.aes__load_fastmatch(ptr);
		
		chan_trigger ^=1;	

		return 1;
}


unsigned char fastmatch_status(void)
{
	return fastmatch.flag;
}


/*
检测接收到的键盘数据是否正确，如果正确配对成功，切换到下一个快速配对id
配对id在键盘数据中的位置是不同的
	id模式下byte6-7
	SN模式下byte11-12
	CRS2模式下 byte19-20
called by 接收键盘函数
*/
unsigned char fastmatch_success_check(const unsigned char *rxkp) 
{
		if(!fastmatch.flag) return 0;	
		if( (fastmatch.keypad_id>0)&&(fastmatch.keypad_id ==(rxkp[0]<<8)+rxkp[1]) ){//fast match sucess,
			fastmatch.keypad_id++;//pointer next id		
			return 1;
		}
		return 0;
}


//------------------------- 快速配对时 低功耗处理 --------------------------------
/*
快速配对开关函数，
*/
void fastmatch_switch(unsigned char on_off)
{
		fastmatch.flag =on_off;
		platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_mainRF_hard_id());//platform.rf_set_freq(base_core.get_main_rf_chan(),base_core.get_main_rf_id());
}


/*
sdk设置快速配对下无线模块低功率设置开关*/
void fastmatch_lowerPA_setup(const unsigned char *rxpc)
{
	//fastmatch_lowerPA.lower_PA =rxpc[5];
	fastmatch.lowPA=rxpc[5];
}

static void fastmatch_lowerPA_ack_sub(unsigned char type,const unsigned char *ack_buf,unsigned char type_data_len)
{
		unsigned char tmp[64]; //whitelist 需要的buf长些

		memset(tmp,0,sizeof(tmp)/sizeof(tmp[0]));//mem_set(tmp,sizeof(tmp)/sizeof(tmp[0]),0);
		tmp[0]= 31;
//		if(type ==_0x61_WHITE_LIST)	tmp[0]= 60; //白名单已经单独处理了
		tmp[1]= 0xE1;
		tmp[2]= base_core.get_id();//get_base_id();//pc2bs_Bb.bs_id;
		tmp[3]= type;
		memcpy( tmp+4,ack_buf,type_data_len);//mem_cpy( ack_buf,tmp+4,type_data_len);
		
		//send to pc 
		base_core.send_data_to_pc(tmp);//user__base_tx_to_pc_sub(tmp);
}

/*
sdk读取快速配对下低功耗设置状态*/
void fastmatch_lowerPA_ack(void)
{
	unsigned char ack_buf[2];
	ack_buf[0] =15;
	//ack_buf[1] =fastmatch_lowerPA.lower_PA;
	ack_buf[1] =fastmatch.lowPA;
	//pc_cmd_0x61_ack(11,ack_buf,2);	
	fastmatch_lowerPA_ack_sub(11,ack_buf,2);	

}



/*
检测快速配对下，基站是否降低功率配对
called by 24L01*/
unsigned char check_fastmatch_lowerPA(void)
{
	if( fastmatch.flag && fastmatch.lowPA) return 1;
	return 0;
}





//------------------------- 快速配对时下载 姓名 -----------------------------------------------
/*
原理： 快速配对完成后，sdk会通过基站转发姓名数据给键盘，此时，基站检测到此动作后，
关闭快速配对并且保证基站在主频点(非0频点)。
键盘收到姓名后会通过基站转发回应信息，此时，基站检测到此动作后，
重新打开快速配对，便于下一个键盘写姓名。
为了避免某个键盘不回应数据导致基站一直关闭快速配对从而导致无法进行下一个键盘 的问题
解决办法：关闭快速配对时，开启定时器，定时时间到后就重新打开快速配对。
*/
#ifdef 	DOWNLOAD_NAME

static unsigned char down_name_20msN = 0;
/*
called by 20ms timer isr*/
void down_name_20ms_timer(void)
{
	if(!down_name_20msN) 		return;
	if(++down_name_20msN<50) return ;
	down_name_20msN =0;
	fastmatch_switch(1);//open fast match
}

/*
called by sdk通过基站转发给键盘的函数  */
unsigned char down_name_enter(unsigned char *rxpc)
{
		if( (rxpc[1]==0x30)&&(rxpc[5]==4) ){		
			fastmatch_switch(0);//close fast match
			down_name_20msN =1;//start timer
			return 1;
		}
		return 0;
}


/*
called by 键盘通过基站转发给sdk的函数  */
unsigned char down_name_exit(unsigned char *rxkp)
{
		if( (rxkp[5]==0xB0)&&(rxkp[9]==4) ){
			fastmatch_switch(1);//open fast match
			down_name_20msN =0;//stop timer
			return 1;
		}
		return 0;
}

#endif 

