
#include "base_pc_protocol.h"
#include "platform_interface.h"
#include "function_interface.h"
#include "base_core.h"
#include "base_core_user.h"


struct BASE_Bbeacon_STR  basic_beacon;
struct BASE_ext_Bbeacon_STR  basic_ext_beacon;
struct BASE_Bbeacon_CRS2_STR  basic_beacon_crs2;
struct BASE_Vbeacon_STR  vote_beacon;
struct ext_vbeacon_STR ext_vbeacon;
struct bs_cfg_STR  base_config;
struct bs_hdinfo_STR  base_hdinfo;
struct bs_match_code_STR  base_mac;
//struct general_aux_config_STR aux_config;
	 struct general_aux_config_mode1_2_STR base_name_log_mode;
	 struct general_aux_config_mode7_8_STR aux_beats;	
	 struct general_aux_config_mode11_12_STR aux_att;
	 struct general_aux_config_mode3_4_STR multi_freq_setup;
     struct general_aux_config_mode23_24_STR base_name_setup;
     struct general_aux_config_mode25_26_STR base_pwd_setup;
	 //struct general_aux_config_mode15_16_STR fastmatch_lowerPA;
//struct base_test_STR base_test;
#ifdef 	EXTEND_VBEACON2
struct ext_vbeacon_STR ext_vbeacon_2;
#endif

/*----------------------------------------
获取和 check log mode是否合法*/
unsigned char get_base_log_mode(void)
{		
	return base_name_log_mode.log_mode;
}

unsigned char assert_base_log_mode(void)
{
	if(function.lock_logmode)//指定log mode 
		base_name_log_mode.log_mode = function.lock_logmode;
	
	if(function.no_ID_mode__SW){//不支持id mode 
		if(base_name_log_mode.log_mode<4)
			base_name_log_mode.log_mode=4;
	}
	
	//目前只是1-9种模式
	if( (base_name_log_mode.log_mode<1)||(base_name_log_mode.log_mode>9) ){
		base_name_log_mode.log_mode =1;
		return 0;
	}
	
	return 1;
}



/*------------------------------
获取基站的id*/
unsigned char get_base_id(void)
{
	return base_config.bs_id;
}
/*
判断基站id是否合法*/
unsigned char assert_base_id(void)
{	
	if( (base_config.bs_id <1)||(base_config.bs_id>32) ){
		base_config.bs_id =1;
		return 0;
	}
	return 1;
}



/*
复制配对码 */
void get_base_match_code(unsigned char *mac)
{
	if( (base_name_log_mode.log_mode==3)||(base_name_log_mode.log_mode ==6) ){//if( log_mode__auto_match()){//20200401增加免配对功能
		mac[0]=0xAA;
		mac[1]=0xBB;
		mac[2]=0xCC;
		mac[3]=0xDD;		
	}
	else
		mem_cpy(base_mac.match_code,mac,BASE_MAC_LEN);		
}


void base_tx_to_pc_sub(const unsigned char *dt)	
{
	unsigned char tmp[USB_REPORT_MAX];

	tmp[0] =0xF5;	
	tmp[1] =0xAA;
	tmp[2] =0xAA;	
#ifdef 	_RPT_PKT_CNT_
	mem_cpy(dt,tmp+3,dt[0]+2);
	mem_set(tmp+tmp[3]+3+1,USB_REPORT_MAX-(tmp[3]+3),0);		
#else
	mem_cpy(dt,tmp+3,dt[0]+1);			 	
//	//#ifdef ENCRC
//	{
//	unsigned short crc =crc16(tmp+4,tmp[3]-2);			
//	tmp[tmp[3]+3-1] = crc>>8;
//	tmp[tmp[3]+3] = crc&0xff;			
//	}
//	//#endif 			
	//无效数据都清除
	mem_set(tmp+tmp[3]+3,USB_REPORT_MAX-(tmp[3]+3),0);
#endif

	platform.base_send_data_to_pc(tmp,USB_REPORT_MAX);
}

//void user__base_tx_to_pc_sub( unsigned char *dt)	
//{
//	unsigned char tmp[USB_REPORT_LEN];

//	tmp[0] =0xF5;	
//	tmp[1] =0xAA;
//	tmp[2] =0xAA;	
//	mem_cpy(dt,tmp+3,dt[0]+1);
//		 	
////	//#ifdef ENCRC
////	{
////	unsigned short crc =crc16(tmp+4,tmp[3]-2);			
////	tmp[tmp[3]+3-1] = crc>>8;
////	tmp[tmp[3]+3] = crc&0xff;			
////	}
////	//#endif 		
//	
//	//无效数据都清除
//	mem_set(tmp+tmp[3]+3,USB_REPORT_LEN-(tmp[3]+3),0);
//	platform.base_send_data_to_pc(tmp,USB_REPORT_LEN);
//}

/*//------------------------------------------------------------------------
开辟一个缓冲区用于存放接收pc的数据
*/
#define 	PCRX_NODE_SIZE		17//10//5 	 	//节点个数，即缓冲区长度 17 =16+1 keypad update???
#define 	PCRX_DATA_SIZE  	64	//数据的最大长度
struct fifo_queue_STR  pcrx_queue;
unsigned  char pcrx_buf[PCRX_NODE_SIZE][PCRX_DATA_SIZE];
/*
初始化用于保持sdk的数据buffer */
void pcrx_init_queue(void)
{
	queue_init(&pcrx_queue,(unsigned char **)pcrx_buf,PCRX_NODE_SIZE,PCRX_DATA_SIZE);
}

#ifdef USB_RX_REMOVE_DUPLICATE
unsigned char check_1ask10answer(const unsigned char *rxpc)
{
	if( (rxpc[1] == 0x60) && (rxpc[3] == 5) ){
		unsigned char *ptmp;
		for(unsigned short i=0;i<pcrx_fifo__get_length();i++){
			ptmp = pcrx_fifo__get_ele(i);
			if( (ptmp[1] ==rxpc[1]) && (ptmp[3] ==rxpc[3]) ){
//				my_debug.printf(1,"%s(),monitor 1ask cmd is exsit\n ",__FUNCTION__);
				return 1;
			}
		}//for
	}
	return 0;
}
#endif

/*
基站接收pc的usb数据，保存到 队列中
此函数被usb endpoint callback 调用*/
unsigned char pcrx_data_save(const unsigned char *pc_buf)	
{
#ifdef USB_RX_REMOVE_DUPLICATE
	if( check_1ask10answer(pc_buf)) return 0;
#endif
	return queue_in(&pcrx_queue,pc_buf,PCRX_NODE_SIZE,PCRX_DATA_SIZE);
}

/*
从buffer里取出数据 */
static unsigned char pcrx_data_fetch(unsigned char *pc_buf)	
{	
	unsigned char ret_val;
//	platform.disable_interrupt();
	ret_val =queue_out(&pcrx_queue,pc_buf,PCRX_NODE_SIZE,PCRX_DATA_SIZE);
//	platform.enable_interrupt();
	return ret_val;
}



/* ------------------------------------------------------
基站处理pc数据的总入口
called by mainloop*/
//	unsigned char rx_pc_buf[64]; //定义成全局变量便于调试
void base_process_pc_data(void)
{
	unsigned char rx_pc_buf[64+4];
	
	if(!pcrx_data_fetch(rx_pc_buf))return ;
	
	//核对sdk的命令是不是发给本基站的!!!//多基站时有用;sdk 转发给键盘的数据没有id，不做判断!!!!
	if( ((rx_pc_buf[1]==0x60)||(rx_pc_buf[1]==0x61)) &&(rx_pc_buf[2] !=0) && (rx_pc_buf[2] !=get_base_id()) )	return;
	
	#if defined(_SDK_OFFLINE_) || defined(_SDK_SYSMODE0_KEEPTIMER_)
	if( (rx_pc_buf[1]==0x60)&&( (rx_pc_buf[3]==5)||(rx_pc_buf[3]==6)) ){
		//除了一问十答外，其他sdk命令都可以激活检测sdk offline和sysmode===0 定时关闭键盘功能
	}
	else{
		reset__monitor_sdkoffline_sysmode0();
	}
	#endif
	
	//buf0 -len
	//buf1开始正好与协议中的byte位相同！！		
	refresh_pc_connect_status();
	
	//process pc data/cmd 
	if(rx_pc_buf[1] ==0x60){
			pc_cmd_0x60_process(rx_pc_buf); 
	}
	else if(rx_pc_buf[1] ==0x61){
		pc_cmd_0x61_process(rx_pc_buf);	
	}
	else
	{
//		function.user_pc_transfer2keypad(rx_pc_buf);
		pc_transfer2keypad_data_save(rx_pc_buf);

	}
}


/*
初始化处理 基站和sdk/PC的数据通信
a,初始化 接收pc数据的队列
b,初始化 键盘转发给pc的数据队列 */
void base_process_pc_init(void)
{
	pcrx_init_queue();
	transfer2pc_init_queue();	
}


