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

#if (NFC==1)//#if defined(NFC)&&(NFC==1)
//sdk写的信息，键盘刷过一次后就无效了!
struct nfc_app_STR nfc_app={
	.card_write_cnt_addr=0,
	
};


//-------------T2 NFC infor ------------------------------
#ifdef NFC_T2
//write
#define 	STUD_ID_ADDR				22
#define 	STUD_ID_BLK_CNT			4

#define 	STUD_NAME_ADDR			30
#define 	STUD_NAME_BLK_CNT		4

#define 	MONEY_ADDR					34
#define 	MONEY_BLK_CNT				1


#define 	MACTH_CHAN_ADDR			10

//read 
#define 	KEYPAD_SN_ADDR			8
#define 	KEYPAD_SN2_ADDR			8	//add by Gavin 20201222
#define 	READ_SNID_BLK_CNT				2//1
#endif



////---------G1 keypad  EVS200 --------------------------
#ifdef NFC_G1
//write 
#define 	MACTH_ADDR					25
#define 	CHAN_ADDR						26

//read 
#define 	KEYPAD_SN_ADDR			6
#define 	KEYPAD_SN_BLK_CNT		1
#define 	KEYPAD_SN1_ADDR			7
#define 	KEYPAD_SN1_BLK_CNT	1
#define 	KEYPAD_ID_ADDR			8
#define 	KEYPAD_ID_BLK_CNT		1

#define 	READ_SNID_BLK_CNT		(KEYPAD_SN_BLK_CNT + KEYPAD_SN1_BLK_CNT +KEYPAD_ID_BLK_CNT )



#define 	AES_KEY_ADDR			 27
#endif //G1


//----------- T1lite CRS200  ------------------------------------
#ifdef NFC_STD
//mathcode , channel
#define		MACTH_ADDR					32
#define 	CHAN_ADDR						33

//sn id 
#define 	KEYPAD_SN_ADDR			24
#define 	KEYPAD_SN1_ADDR			25
#define 	KEYPAD_ID_ADDR			26
#define 	READ_SNID_BLK_CNT		3

//student id,name 
#define 	STUD_ID_ADDR				40
#define 	STUD_ID_BLK_CNT			4
#define 	STUD_NAME_ADDR			36
#define 	STUD_NAME_BLK_CNT		4
//money
#define 	MONEY_ADDR					76
#define 	MONEY_BLK_CNT				1

//special
#define 	WRITE_CNT_ADDR			18
#endif 





#ifdef NFC_STD
/* 根据NFC std 协议;计算出修改的区域 flag;addr16-17
*/
unsigned char calc_update_flag(unsigned char *block,unsigned char cnt)
{
	unsigned char i,tmp;
	unsigned char flag[8];
	unsigned char byte_seq,bit_seq;
	
	for(i=0;i<8;i++){//clear all flag
		flag[i] =0;
	}
		
	for(i=0;i<cnt;i++){
		if( block[i] <4) return 0;
		tmp =((block[i] -4)>>2);//(block[i] -4)/4
		byte_seq = tmp>>3;// /8
		bit_seq = tmp%8;		
		flag[byte_seq] |= 1<<bit_seq;
	}//for
	
	memcpy(nfc_app.wbuf[cnt],flag,4);
	nfc_app.waddr[cnt] =16;
	memcpy(nfc_app.wbuf[cnt+1],flag+4,4);	
	nfc_app.waddr[cnt+1] =17;	
	
	return 2;
}
#endif


/*
* 加载基站配对码和 主频点信息,为写给键盘做准备
* return :配对码和频点所占用的NFC block个数;
* 需要参考具体型号的键盘nfc地址对照表！！！！
*/
static unsigned char load_write_info__matchcode_chan(unsigned char indx)
{
		unsigned char block_cnt,tmp[32],i;
		
		//1, load match code and channel
		#ifdef NFC_T2 
		//load  match code and chan, write to keypad
		base_core.get_match_code(nfc_app.wbuf[indx]);
		nfc_app.wbuf[indx][3]=base_core.get_main_rf_chan();
		nfc_app.waddr[indx] =MACTH_CHAN_ADDR;	
		block_cnt = 1;
		#else		//(NFC_G1),(NFC_STD)
		//load  match code and chan, write to keypad
		base_core.get_match_code(nfc_app.wbuf[indx]);
		nfc_app.waddr[indx] =MACTH_ADDR;
		//main channel 
		nfc_app.wbuf[indx+1][0] =base_core.get_main_rf_chan();
		nfc_app.waddr[indx+1] =CHAN_ADDR;
		block_cnt = 2;
		#endif
	
		//2, special process
		#ifdef NFC_G1	
		//write aes key 
		function.aes__get_key(tmp);
		for(i=0;i<8;i++){
			memcpy(nfc_app.wbuf[indx+2+i],tmp+i*4,4);
			nfc_app.waddr[indx+2+i] =AES_KEY_ADDR+i;
		}
		block_cnt += 8;
		#endif 
		
		return block_cnt;
}

/*
* 加载读取键盘NFC 的SN ID地址;
* return :SN ID 占用NFC block个数;
* 需要参考具体型号的键盘nfc地址对照表！！！！
*/
static unsigned char load_read_info__idsn(unsigned char indx)
{
		unsigned char block_cnt;	
		unsigned char i;
		for(i=0;i<NFC_BLOCK_CNT;i++)
			memset(nfc_app.rbuf[i],0,4);				

		#ifdef NFC_T2 
		//ready read keypad sn 
		nfc_app.raddr[0]= KEYPAD_SN_ADDR;
		nfc_app.raddr[1]= KEYPAD_SN2_ADDR;		
		block_cnt =READ_SNID_BLK_CNT;			
		#else //NFC_G1,NFC_STD	
		//ready read keypad SN and/or ID 
		nfc_app.raddr[0]= KEYPAD_SN_ADDR;
		nfc_app.raddr[1]= KEYPAD_SN1_ADDR;
		nfc_app.raddr[2]= KEYPAD_ID_ADDR;		
		block_cnt =READ_SNID_BLK_CNT;
		#endif
	
		#ifdef NFC_STD	//此处与读没有关系，只是放在这里而已
		nfc_app.card_write_cnt_addr=WRITE_CNT_ADDR;
		#endif	
	
		return block_cnt;
}




/*
将来自sdk的NFC信息复制到 写nfc缓冲区里;
receive sdk data,
input *info-sdk data 
*see base protocol V0.95 section5.2.10;
实现方法：必须要写入的基础信息(频点配对码等，每类键盘都必须要写入的) 排在写入buf的最前面
sdk设置下来的键盘用户信息跟随其后;
*/
void base_record_keypad_NFC_info(const unsigned char *info)
{
		unsigned char i,ack_buf[2];
	
		if(info[4]==19){ //write cmd 
				//2020.09.18 add by Gavin, 必须保持nfc_app.wblock_cnt的初始值;
				nfc_app.wblock_cnt = load_write_info__matchcode_chan(0);
			
				//---1，student id,name ; money----------------------------------------
				if(info[5]==1){ //msg type common info 									
					#if defined(NFC_T2)||defined(NFC_STD_T1LITE) 
					/*20200317 修改成与G1 相同的处理方法*/
					//student id 16bytes store front of block22-29;
					for(i=0;i<4;i++){
						if( nfc_app.wblock_cnt+i >=NFC_BLOCK_CNT) return; //防止用户连续多次写入导致数组越界
						memcpy(nfc_app.wbuf[nfc_app.wblock_cnt+i],info+6+i*4,4);	//mem_cpy(info+6+i*4,nfc.buf[1+i],4);		
						nfc_app.waddr[nfc_app.wblock_cnt+i] = STUD_ID_ADDR+i;//block
					}//for	
					nfc_app.wblock_cnt+=4;
					
					//b, student name 16bytes store  block30-33;
					for(i=0;i<4;i++){
						if( nfc_app.wblock_cnt+i >=NFC_BLOCK_CNT) return; //防止用户连续多次写入导致数组越界
						memcpy(nfc_app.wbuf[nfc_app.wblock_cnt+i],info+22+i*4,4);	//mem_cpy(info+22+i*4,nfc.buf[5+i],4);		
						nfc_app.waddr[nfc_app.wblock_cnt+i] = STUD_NAME_ADDR+i;//block
					}//for
					nfc_app.wblock_cnt+=4;
					
					//b, money 4bytes store  block30-33;
					for(i=0;i<1;i++){
						if( nfc_app.wblock_cnt+i >=NFC_BLOCK_CNT) return; //防止用户连续多次写入导致数组越界
						memcpy(nfc_app.wbuf[nfc_app.wblock_cnt+i],info+38+i*4,4);//mem_cpy(info+38+i*4,nfc.buf[9+i],4);		
						nfc_app.waddr[nfc_app.wblock_cnt+i] = MONEY_ADDR+i;//block
					}//for
					nfc_app.wblock_cnt+=1;
					#endif
										
					ack_buf[1] =1;//used ack adk 	
				}
				
				//--------------2，股东姓名 ----------------------
				#ifdef NFC_G1
				/*20200317修改,sdk下发 股权人和股权数到基站，基站一次性写入到键盘*/
				else if(info[5]==2){ //store name 					
					for(i=0;i<13;i++){
						if( nfc_app.wblock_cnt+i >=NFC_BLOCK_CNT) return; //防止用户连续多次写入导致数组越界
						memcpy(nfc_app.wbuf[nfc_app.wblock_cnt+i],info+6+i*4,4);
						nfc_app.waddr[nfc_app.wblock_cnt+i] =10+i; //G1 NFC地址说明
					}
					nfc_app.wblock_cnt +=13;
					ack_buf[1] =2;//used ack adk 				
				}
				//--------------,3，股票数量--------------------------
				else if(info[5]==3){ //store  count
					for(i=0;i<2;i++){
						if( nfc_app.wblock_cnt+i >=NFC_BLOCK_CNT) return; //防止用户连续多次写入导致数组越界
						memcpy(nfc_app.wbuf[nfc_app.wblock_cnt+i],info+6+i*4,4);
						nfc_app.waddr[nfc_app.wblock_cnt+i] =23+i; //G1 NFC地址说明
					}
					nfc_app.wblock_cnt +=2;
					ack_buf[1] =3;//used ack adk 	
				}				
				#endif
				
				#ifdef NFC_STD
				nfc_app.wblock_cnt +=calc_update_flag(nfc_app.waddr,nfc_app.wblock_cnt);
				#endif
				
				#ifdef 	_NFC_DEBUG_
				for(i=0;i<4;i++)
					memcpy(nfc_app.kp_nfc_info[nfc_app.ok_cnt].name+i*4,nfc_app.wbuf[6+i],4);				
				nfc_app.debug_sdk_down_cnt++;
				#endif
				
				nfc_app.mode_status =1; //sdk write flag 				
		}
		else{ //------------------------------read nfc infor 
						
		}		
		
		ack_buf[0] =info[4]; //19,20
//		ack_buf[1] =1; 				//收到指令，在后续操作中才返回真正的数据!!
		user__pc_cmd_ack(0x61,11,ack_buf,2);//nfc_ack_pc(ack_buf,2);
}




/*
*刷卡后将键盘信息反馈给sdk
*/
static void responce_keypad_info_to_pc(void)
{
		unsigned char ack_buf[32];
		ack_buf[0] =20; //19,20
		ack_buf[1] =2; 	//responce keypad info

		#ifdef NFC_T2 //T2的sdk把前4个字节作为SN；其他的用后4个作为SN
		// ack_buf[2] =nfc_app.rbuf[0][0]; //4byte SN
		// ack_buf[3] =nfc_app.rbuf[0][1];
		ack_buf[2] =nfc_app.rbuf[0][2];
		ack_buf[3] =nfc_app.rbuf[0][3];
		ack_buf[4] =nfc_app.rbuf[1][0]; //2bytes of 6bytes SN remain
		ack_buf[5] =nfc_app.rbuf[1][1];
		ack_buf[6] =0x00;//nfc_app.rbuf[0][2];
		ack_buf[7] =0x00;//nfc_app.rbuf[0][3];
		#else
		ack_buf[2] =nfc_app.rbuf[0][0]; //4byte SN
		ack_buf[3] =nfc_app.rbuf[0][1];
		ack_buf[4] =nfc_app.rbuf[0][2];
		ack_buf[5] =nfc_app.rbuf[0][3];
		ack_buf[6] =nfc_app.rbuf[1][0]; //2bytes of 6bytes SN remain
		ack_buf[7] =nfc_app.rbuf[1][1];
		#endif
		ack_buf[8] =nfc_app.rbuf[2][0]; //id
		ack_buf[9] =nfc_app.rbuf[2][1];		
		user__pc_cmd_ack(0x61,11,ack_buf,10);
}


/*
* 20ms scan 
*/
void NFC_monitor(void)
{
		//键盘固件升级模式下，不支持NFC刷卡，20201009
		if(function.updatekp__SW && function.update__get_status() ) return;
		
		if( base_core.get_sdk_connect_status() ==0){
			unsigned char i;
			if(++nfc_app.sdk_offline_cnt >=100){	//*20ms
				nfc_app.sdk_offline_cnt=0;
				nfc_app.mode_status =0;			//sdk Nms内不连接，基站就回到基础状态
				#ifdef 	_NFC_DEBUG_
				nfc_app.debug_custom_ok_cnt=0;
				nfc_app.debug_default_ok_cnt =0;
				nfc_app.debug_sdk_down_cnt =0;
				nfc_app.debug_driver_ok_cnt=0;	
				nfc_app.debug_sdk_change_cnt=0;					
				nfc_app.ok_cnt=0;
				nfc_app.debug_driver_start_cnt=0;
				for(i=0;i<8;i++){
					nfc_app.error[i].cnt=0;
					memset(nfc_app.error[i].card_sn,0,8);
				}//for
				#endif
			}				
		}
		else{
			nfc_app.sdk_offline_cnt=0;
		}
		
		
		if(nfc_app.mode_status ==1){ //写完成之后还需要读回被写的键盘的sn id等信息;		
			//a load read info addr
			nfc_app.rblock_cnt =load_read_info__idsn(0);				
			
			//b,write/read data and read the keypad sn 
			if( platform.rfid_write_read_N_block(&nfc_app) == 0x12){
				#ifdef 	_NFC_DEBUG_
				nfc_app.debug_custom_ok_cnt++;
				memcpy(nfc_app.kp_nfc_info[nfc_app.ok_cnt].keypad_sn,nfc_app.rbuf[0]+2,2);
				memcpy(nfc_app.kp_nfc_info[nfc_app.ok_cnt].keypad_sn+2,nfc_app.rbuf[1],2);
				memcpy(&nfc_app.kp_nfc_info[nfc_app.ok_cnt].keep_,&nfc_app.debug_driver_keep_cnt,1);
				memcpy(&nfc_app.kp_nfc_info[nfc_app.ok_cnt].start_,&nfc_app.debug_driver_start_cnt,1);
				memcpy(&nfc_app.kp_nfc_info[nfc_app.ok_cnt].complish_,&nfc_app.debug_custom_ok_cnt,1);
				memcpy(&nfc_app.kp_nfc_info[nfc_app.ok_cnt].card_sn_record,&nfc_app.card_sn,8);					
				nfc_app.ok_cnt++;
				#endif
				platform.buzzer_ctrl(1);
				responce_keypad_info_to_pc();
				//start timer
				nfc_app.wait_sdk_info =200;	//*20ms =
				nfc_app.mode_status =0;
			}				
		}
		else if(nfc_app.mode_status ==2){ //read info from keypad 
			
		}
		else{//只写入配对码和主频点信息
			if( nfc_app.wait_sdk_info ){
				nfc_app.wait_sdk_info--;
				return;
			}
		
			nfc_app.wblock_cnt = load_write_info__matchcode_chan(0);
			#ifdef NFC_STD
			nfc_app.wblock_cnt +=calc_update_flag(nfc_app.waddr,nfc_app.wblock_cnt);
			#endif
			nfc_app.rblock_cnt =load_read_info__idsn(0);
						
			if( platform.rfid_write_read_N_block(&nfc_app)==0x12){	
				#ifdef 	_NFC_DEBUG_
				nfc_app.debug_default_ok_cnt++;		
				#endif				
				platform.buzzer_ctrl(1);
				responce_keypad_info_to_pc();
			}

		}	
}



#endif 
