/**
***********************************************************************************************
* @file cpu_card.c
* @brief cpu card函数实现.
* @author ginger
* @date 2023.12.01
* @version v1.0
* @par Copyright (c):
*
* @par History:
*
**********************************************************************************************
*/
#include "cpu_card.h"
#include "COUNT_DES.h"

uint8_t PassWd_EX_AUTH[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//
uint8_t PassWd2[8]={0x11,0X22,0X33,0X44,0X55,0X66,0X77,0X88};//
uint8_t PassWd3[8]={0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08};//
uint8_t MK_MF[16]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; // User-defined master key 
uint8_t write_data[32]= {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 
uint8_t read_data[64];

/**
 ****************************************************************
 * @brief CardCpu_SelectMainFileOnlyRead() 
 *
 * 功能： Select Main File (skip authentication method) 选中00 1F文件
 *
 * @param: 
 * @param: 
 * @param: 
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_SelectMainFileOnlyRead(void)
{
	uint8_t status;
	uint8_t  tx_buf[] = {0x00, 0xA4, 0x00, 0x00, 0x02, 0x00, 0x1F};  //选中00 1F文件

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 7, rx_buf, &rx_len);

  if (status == MI_OK) ///
	{
		user_print_hex("CardCpu_SelectMainFileOnlyRead : ", rx_buf,rx_len);
		dbg_printf("\n");
	 }
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_SelectMainFile() 
 *
 * 功能：Select Main File 选择3F 00 的MF文件
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  6F······
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_SelectMainFile(void)
{
	uint8_t status;

	tx_buf[0] = 0x00;    //CLA
	tx_buf[1] = 0xA4;    //INS
  tx_buf[2] = 0x00;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x02;    //LC
	tx_buf[5] = 0x3F;    //DATA
	tx_buf[6] = 0x00;    //DATA
	
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 7, rx_buf, &rx_len);
  if (status == MI_OK) ///
	{
		user_print_hex("CardCpu_SelectMainFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	 }

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_authentication() 
 *
 * 功能：取随机数和外部认证
 *
 * @param: Plaintext =获取到的随机数
 * @param: Ciphetext = 加密数据
 * @param: rx_buf = 
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_authentication(void)
{
	uint8_t status,i;

	uint8_t Car_key[5]={0x00,0x84,0x00,0x00,0x08}; //get 8-byte random number
	uint8_t Ex_Key0[5]={0x00,0x82,0x00,0x00,0x08}; //The default card external authentication command
  //uint8_t Ex_Key1[5]={0x00,0x82,0x00,0x01,0x08}; //An external authentication command with key identification number 1
	//uint8_t Ex_Key2[5]={0x00,0x82,0x00,0x02,0x08}; //An external authentication command with key identification number 2
	uint8_t Plaintext[8];//DES Plaintext
	uint8_t Ciphetext[8];//DE ciphertext
	uint8_t Ex_key[13];//External AUTHENTICION 

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, Car_key, sizeof(Car_key), rx_buf, &rx_len);  //获取随机数

	if (status == MI_OK) 
	{
		user_print_hex("get random number : ", rx_buf,rx_len);  //
		dbg_printf("\n");
		for(i = 0;i<8;i++)
		{
			Plaintext[i]=rx_buf[i];
		}
		des3_cbc_encrypt(Ciphetext, Plaintext, 0x08, MK_MF, 0x10, NULL); 
		//user_print_hex("Ciphetext : ", Ciphetext,0x08);
		memset(Plaintext,0,8);
		des3_cbc_decrypt(Plaintext, Ciphetext, 0x08, MK_MF, 0x10, NULL); 		
		user_print_hex("des3_cbc_decrypt random number : ", Ciphetext,0x08);  //
		dbg_printf("\n");
		for(i=0;i<5;i++)
		{
			Ex_key[i]=Ex_Key0[i];
		}
		for(i=0;i<8;i++)
		{
			Ex_key[i+5]=Ciphetext[i];
		}	
		memset(rx_buf,0,sizeof(rx_buf));
		status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, Ex_key, 13, rx_buf, &rx_len);   //外部认证
		if(status == MI_OK)
	 {
		  user_print_hex("CardCpu_authentication : ", rx_buf,rx_len);
		  dbg_printf("\n");
		}
	}
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_ClearMfAllFile() 
 *
 * 功能：擦除卡片里面的所有数据
 *
 * @param: 
 * @param: 
 * @param: rx_buf = 90 00 
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_ClearMfAllFile(void)
{
	uint8_t status;
	
	tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0x0E;    //INS
  tx_buf[2] = 0x00;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x00;    //LC

  status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 5, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_ClearMfAllFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_CreatMfFile() 
 *
 * 功能：创建MF文件
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_CreatMfFile(void)
{
	uint8_t status;
	
	tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xE0;    //INS
  tx_buf[2] = 0x3F;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x0D;    //LC
	tx_buf[5] = 0x38;    //文件类型
	tx_buf[6] = 0xFF;    //文件空间
	tx_buf[7] = 0xFF;    //文件空间
	tx_buf[8] = 0xF0;    //建立权限
  tx_buf[9] = 0xF0;    //擦除权限
	tx_buf[10] = 0x01;    //应用文件ID
	tx_buf[11] = 0xFF;    //保留字
	tx_buf[12] = 0xFF;    //保留字
	tx_buf[13] = 0xFF;    /*****DF名称******/
	tx_buf[14] = 0xFF;    
	tx_buf[15] = 0xFF;     
	tx_buf[16] = 0xFF;    
	tx_buf[17] = 0xFF;
	
 status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 18, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_CreatMfFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_CreatMf_Keyfile() 
 *
 * 功能：建立秘钥文件 Create a key file FileID=0000 and rewrite the factory default external authentication key
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */

uint8_t CardCpu_CreatMf_Keyfile(void)
{
	uint8_t status;
	
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xE0;    //INS
  tx_buf[2] = 0x00;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x07;    //LC
	tx_buf[5] = 0x3F;    //文件类型
	tx_buf[6] = 0x00;    //文件空间
	tx_buf[7] = 0x50;    //文件空间
	tx_buf[8] = 0x01;    //DF文件短标标识符
  tx_buf[9] = 0xF0;    //增加权限
	tx_buf[10] = 0xFF;    //默认
	tx_buf[11] = 0xFF;    //默认

  status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 12, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_CreatMf_Keyfile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_Add_Line_Protect_Key() 
 *
 * 功能：添加线路保护密钥
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add_Line_Protect_Key(void)
{
	uint8_t status;
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xD4;    //INS
  tx_buf[2] = 0x01;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x0D;    //LC
	tx_buf[5] = 0x36;    //密钥标识
	tx_buf[6] = 0xF0;    //使用权
	tx_buf[7] = 0xF0;    //更改权
	tx_buf[8] = 0xFF;    //默认
  tx_buf[9] = 0x33;    //错误计数器
	tx_buf[10] = 0x11;   /*************** 秘钥************************/
	tx_buf[11] = 0x22;   
	tx_buf[12] = 0x33;    
	tx_buf[13] = 0x44;    
	tx_buf[14] = 0x55;    
	tx_buf[15] = 0x66;    
	tx_buf[16] = 0x77;    
	tx_buf[17] = 0x88;    
	
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 18, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add_Line_Protect_Key : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
 
}

/**
 ****************************************************************
 * @brief CardCpu_Add_External_Auth_Key() 
 *
 * 功能：添加外部验证秘钥
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add_External_Auth_Key(void)
{
	uint8_t status;
	
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xD4;    //INS
  tx_buf[2] = 0x01;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x15;    //LC
	tx_buf[5] = 0x39;    //密钥标识
	tx_buf[6] = 0xF0;    //使用权
	tx_buf[7] = 0xF0;    //更改权
	tx_buf[8] = 0xAA;    //后续状态
  tx_buf[9] = 0x88;    //错误计数器
	tx_buf[10] = 0xFF;   /*************** 秘钥************************/
	tx_buf[11] = 0xFF;   
	tx_buf[12] = 0xFF;    
	tx_buf[13] = 0xFF;    
	tx_buf[14] = 0xFF;    
	tx_buf[15] = 0xFF;    
	tx_buf[16] = 0xFF;    
	tx_buf[17] = 0xFF;    
	tx_buf[18] = 0xFF;    
	tx_buf[19] = 0xFF;    
	tx_buf[20] = 0xFF;    
	tx_buf[21] = 0xFF;    
	tx_buf[22] = 0xFF;    
	tx_buf[23] = 0xFF;    
	tx_buf[24] = 0xFF;    
	tx_buf[25] = 0xFF;   
	
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 26, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add_Line_Protect_Key : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
 
}

/**
 ****************************************************************
 * @brief CardCpu_Creat_BinaryFile() 
 *
 * 功能：创建二进制文件
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Creat_BinaryFile(void)
{
	uint8_t status;
	
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xE0;    //INS
  tx_buf[2] = 0x00;    //P1
  tx_buf[3] = 0x1F;    //P2
	tx_buf[4] = 0x07;    //LC
	tx_buf[5] = 0x28;    //A8（明文MAC 28(二进制文件高位变1)–>A8）
	tx_buf[6] = 0x09;    //文件空间
	tx_buf[7] = 0x00;    //文件空间
	tx_buf[8] = 0xF0;    //读权限
  tx_buf[9] = 0xF0;    //增加权限
	tx_buf[10] = 0xFF;   //默认
	tx_buf[11] = 0xFF;   //默认

  status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 12, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Creat_BinaryFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}
/**
 ****************************************************************
 * @brief CardCpu_Add_Internal_Key() 
 *
 * 功能：添加内部密钥
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add_Internal_Key(void)
{
	uint8_t status;
	
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xD4;    //INS
  tx_buf[2] = 0x01;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x15;    //LC
	tx_buf[5] = 0x34;    //密钥标识
	tx_buf[6] = 0xF0;    //使用权
	tx_buf[7] = 0x02;    //更改权
	tx_buf[8] = 0x00;    //密钥版本号
  tx_buf[9] = 0x01;    //算法标识
	tx_buf[10] = 0x34;   /*************** 秘钥************************/
	tx_buf[11] = 0x34;   
	tx_buf[12] = 0x34;    
	tx_buf[13] = 0x34;    
	tx_buf[14] = 0x34;    
	tx_buf[15] = 0x34;    
	tx_buf[16] = 0x34;    
	tx_buf[17] = 0x34;    
	tx_buf[18] = 0x34;    
	tx_buf[19] = 0x34;    
	tx_buf[20] = 0x34;    
	tx_buf[21] = 0x34;    
	tx_buf[22] = 0x34;    
	tx_buf[23] = 0x34;    
	tx_buf[24] = 0x34;    
	tx_buf[25] = 0x34;    

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 26, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add_Internal_Key : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_Add_Line_Protect_EFKey() 
 *
 * 功能：添加线路保护密钥 （36秘钥）
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add_Line_Protect_EFKey(void)
{
	uint8_t status;
	
  tx_buf[0] = 0x80;    //CLA
	tx_buf[1] = 0xD4;    //INS
  tx_buf[2] = 0x01;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x15;    //LC
	tx_buf[5] = 0x34;    //密钥标识
	tx_buf[6] = 0xF0;    //使用权
	tx_buf[7] = 0x02;    //更改权
	tx_buf[8] = 0x00;    //密钥版本号
  tx_buf[9] = 0x01;    //算法标识
	tx_buf[10] = 0x34;   /*************** 秘钥************************/
	tx_buf[11] = 0x34;   
	tx_buf[12] = 0x34;    
	tx_buf[13] = 0x34;    
	tx_buf[14] = 0x34;    
	tx_buf[15] = 0x34;    
	tx_buf[16] = 0x34;    
	tx_buf[17] = 0x34;    
	tx_buf[18] = 0x34;    
	tx_buf[19] = 0x34;    
	tx_buf[20] = 0x34;    
	tx_buf[21] = 0x34;    
	tx_buf[22] = 0x34;    
	tx_buf[23] = 0x34;    
	tx_buf[24] = 0x34;    
	tx_buf[25] = 0x34;    

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 26, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add_Line_Protect_EFKey : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
}

/*Add 39 types of external authentication keys to the key file (16-byte FF is the default master key value of factory, 
  it is best not to modify it, most system vendors will verify the key before washing the card)
*/
/**
 ****************************************************************
 * @brief CardCpu_Add39TypeExternalAuthenticationKey() 
 *
 * 功能：添加39验证秘钥
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add39TypeExternalAuthenticationKey(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x80, 0xD4, 0x01, 0x00, 0x15, 0x39, 0xF0, 0xF0, 0xAA, 0x88, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 26, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add39TypeExternalAuthenticationKey : ", rx_buf,rx_len);
		dbg_printf("\n");

	}
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_Add30TypeEncryptionKey() 
 *
 * 功能：添加30验证秘钥
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Add30TypeEncryptionKey(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x80, 0xD4, 0x01, 0x00, 0x15, 0x30, 0xF0, 0xF0, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};


	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf,20, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Add30TypeEncryptionKey : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_AddFileLineProtection() 
 *
 * 功能：Add file line protection to the key file
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_AddFileLineProtection(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x80, 0xD4, 0x01, 0x00, 0x0D, 0x36, 0xF0, 0xF0, 0xFF, 0x33, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};


	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 18, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_AddFileLineProtection : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_AddFileLineProtection() 
 *
 * 功能：Add file line protection to the key file
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_KeyFileAddPasswordKey(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x80, 0xD4, 0x01, 0x00, 0x0D, 0x3A, 0xF0, 0xEF, 0x01, 0x33, 0x12, 0x34, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};


	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 18, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_KeyFileAddPasswordKey : ", rx_buf,rx_len);
		dbg_printf("\n");

	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_InternalAuthenticate() 
 *
 * 功能：Internal Authentication - Cryptographic Computing
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_InternalAuthenticate(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x00, 0x88, 0x00, 0x00, 0x08, 0x19, 0x83, 0x07, 0x05, 0x19, 0x83, 0x07, 0x05};


	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 13, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_InternalAuthenticate : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_AuthenticateKey() 
 *
 * 功能：Iauthentication password
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_AuthenticateKey(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x00, 0x20, 0x00, 0x00, 0x03, 0x12, 0x34, 0x56};  //  0x12, 0x34, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
	//uint8_t tx_buf[] = {0x00, 0x20, 0x00, 0x00, 0x06, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
	//uint8_t tx_buf[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 8, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_AuthenticateKey : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_BuildBinarySystemFile() 
 *
 * 功能：Build File (FID=31 Lc=07 FTY=Binary Len=1900)
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_BuildBinarySystemFile(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0X80, 0XE0, 0X00, 0X1F, 0X07, 0X28, 0X19, 0X00, 0XF0, 0XF0, 0XFF, 0XFF};

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 12, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_BuildBinarySystemFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_SelectFile() 
 *
 * 功能：Select File (FID=31)
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_SelectFile(void)
{
	uint8_t status;
//	uint8_t tx_buf[] = {0X00, 0XA4, 0X00, 0X00, 0X02, 0X00, 0X1F};
  tx_buf[0] = 0x00;    //CLA
	tx_buf[1] = 0xA4;    //INS
  tx_buf[2] = 0x00;    //P1
  tx_buf[3] = 0x00;    //P2
	tx_buf[4] = 0x02;    //LC
	tx_buf[5] = 0x00;    //密钥标识
	tx_buf[6] = 0x1F;    //使用权
	
  status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 7, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_SelectFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_WriteBinarySystemFile() 
 *
 * 功能：Write binary (P1P2=offset Len=16 bytes)
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_WriteBinarySystemFile(void)
{
	
	uint8_t status;
	uint8_t tx_buf[60] = {0x00, 0xD6, 0x08, 0x00, 0x20, 0xAA, 0x55, 0x66, 0x99, 0x00, 0xFF, 0xA5, 0x69, 0xF0, 0x0F, 0x96, 0x5A, 0x00, 0x00, 0x00, 0x01};
	

	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, sizeof(tx_buf), rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_WriteBinarySystemFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}

	return status;
}


/**
 ****************************************************************
 * @brief CardCpu_ReadBinarySystemFile() 
 *
 * 功能：Read binary (P1P2=offset Len=16 bytes)
 *
 * @param: 
 * @param: 
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_ReadBinarySystemFile(void)
{
	uint8_t status;
	uint8_t tx_buf[] = {0x00, 0xB0, 0x08, 0x00, 0x6d};


	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 5, rx_buf, &rx_len);
	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_ReadBinarySystemFile : ", rx_buf,rx_len);
	}
	return status;
}

/**
 ****************************************************************
 * @brief CardCpu_Write_BinaryFile() 
 *
 * 功能：写二进制文件
 *
 * @param: 
 * @param: Write binary (P1P2=offset Len=16 bytes)
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */

uint8_t CardCpu_Write_BinaryFilel(uint8_t *WriteBuff, uint8_t WriteLen)//(uint8_t *WriteBuff, uint8_t WriteLen)
{
	uint8_t status;

  tx_buf[0] = 0x00;    //CLA
	tx_buf[1] = 0xD6;    //INS
  tx_buf[2] = 0x01;    //文件标识
  tx_buf[3] = 0x00;    //写入数据偏移量
	tx_buf[4] = WriteLen;  //LC +data
	memcpy(&tx_buf[5], WriteBuff, WriteLen);

		
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, WriteLen+5, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Write_BinaryFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;

}

uint8_t CardCpu_Write_BinaryFile(uint8_t *WriteBuff, uint8_t WriteLen)//(uint8_t *WriteBuff, uint8_t WriteLen)
{
	
	uint8_t status;

  tx_buf[0] = 0x00;    //CLA
	tx_buf[1] = 0xD6;    //INS
  tx_buf[2] = 0x01;    //文件标识
  tx_buf[3] = 0x00;    //写入数据偏移量
	//tx_buf[4] = 0x20;    //LC +data
  tx_buf[4] = WriteLen;  //LC +data
	memcpy(&tx_buf[5], WriteBuff, WriteLen);  /***************data************************/
		
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 37, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Write_BinaryFile : ", rx_buf,rx_len);
		dbg_printf("\n");
	}
	return status;
}


/**
 ****************************************************************
 * @brief CardCpu_Read_BinaryFile() 
 *
 * 功能：读二进制文件
 *
 * @param: 
 * @param: Read binary (P1P2=offset Len=16 bytes)
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CardCpu_Read_BinaryFile(uint8_t *pReadBuff,  uint8_t ReadLen)
{
	
	uint8_t status;
//	uint8_t tx_buf[];[60] = {0x00, 0xD6, 0x08, 0x00, 0x20, 0xAA, 0x55, 0x66, 0x99, 0x00, 0xFF, 0xA5, 0x69, 0xF0, 0x0F, 0x96, 0x5A, 0x00, 0x00, 0x00, 0x01};

  tx_buf[0] = 0x00;    //CLA
	tx_buf[1] = 0xB0;    //INS
  tx_buf[2] = 0x01;    //文件标识
  tx_buf[3] = 0x00;    //写入数据偏移量
	tx_buf[4] = ReadLen; //data len
	

		
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buf, 5, rx_buf, &rx_len);

	if (status == MI_OK) 
	{
		user_print_hex("CardCpu_Read_BinaryFile : ", rx_buf,rx_len);
		dbg_printf("\n");
		memcpy(pReadBuff, &rx_buf[0], rx_len);
		
	}
	return status;
}

/**
 ****************************************************************
 * @brief CpuCard_Write_BinaryFile_Exp() 
 *
 * 功能：添加线路保护密钥 （36秘钥）
 *
 * @param: 
 * @param: Write binary (P1P2=offset Len=16 bytes)
 * @param: rx_buf =  90 00
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CpuCard_Write_BinaryFile_Exp(void)
{
	uint8_t status = MI_OK;
 
 	if(CardCpu_SelectMainFile()!=MI_OK)
		return MI_ERR; 
	
	if(CardCpu_authentication()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_ClearMfAllFile()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_CreatMf_Keyfile()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_Add_External_Auth_Key()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_Add_Line_Protect_Key()!=MI_OK)
	return MI_ERR; 
	
	delay_ms(20);			
			
	if(CardCpu_Creat_BinaryFile()!=MI_OK)
	return MI_ERR;

	if(CardCpu_SelectFile()!=MI_OK)
	return MI_ERR;

	if(CardCpu_Write_BinaryFile(write_data,32)!=MI_OK)
	return MI_ERR;
//	delay_ms(20);		
	if(CardCpu_Read_BinaryFile(read_data,64)!=MI_OK)
	return MI_ERR;

	user_print_hex("write_data : ", write_data,32);
	user_print_hex("read_data : ", read_data,64);
	return status;
}


/**
 ****************************************************************
 * * @brief CpuCard_Read_BinaryFile_Exp() 

 * 功能：写完二进制文件之后读目录下的数据
 *
 * @param: 
 * @param: 
 * @param: 
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CpuCard_Read_BinaryFile_Exp(void)
{
	uint8_t status = MI_OK;
	
	if(CardCpu_SelectFile()!=MI_OK)
	return MI_ERR;
//	if(CardCpu_authentication()!=MI_OK)
//	return MI_ERR;	
	if(CardCpu_Read_BinaryFile(read_data,64)!=MI_OK)
	return MI_ERR;

	return status;
}

/**
 ****************************************************************
 * * @brief CpuCard_Operation() 

 * 功能：复旦微cos指令操作示例
 *
 * @param: 
 * @param: 
 * @param: 
 * @return: status 值为MI_OK:成功
 *
 ****************************************************************
 */
uint8_t CpuCard_Operation(void)
{
	uint8_t status = MI_OK;
	
 	if(CardCpu_SelectMainFile()!=MI_OK)
		return MI_ERR; 
	delay_ms(20);
	if(CardCpu_authentication()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_ClearMfAllFile()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_CreatMfFile()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_Add39TypeExternalAuthenticationKey()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_Add30TypeEncryptionKey()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_AddFileLineProtection()!=MI_OK)
	return MI_ERR; 
	
	if(CardCpu_InternalAuthenticate()!=MI_OK)
	return MI_ERR;
		
	if(CardCpu_InternalAuthenticate()!=MI_OK)
	return MI_ERR;
			
	if(CardCpu_InternalAuthenticate()!=MI_OK)
	return MI_ERR;
	delay_ms(20);			
//	if(CardCpu_AuthenticateKey()!=MI_OK)
//	return MI_ERR;				
	if(CardCpu_BuildBinarySystemFile()!=MI_OK)
	return MI_ERR;

	if(CardCpu_SelectFile()!=MI_OK)
	return MI_ERR;

	if(CardCpu_WriteBinarySystemFile!=MI_OK)
	return MI_ERR;
	delay_ms(20);		
	if(CardCpu_ReadBinarySystemFile()!=MI_OK)
	return MI_ERR;

	
	return status;
}
