/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  ：RFID_IC.c
 * 描  述  ：RFID_IC卡驱动程序    
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/03/06 
*********************************************************************************/
#include "rfid_decode_yn.h"
#include "RFID_IC.h"
#include "string.h" 
#include "stdlib.h" 
#include "my_math.h"
#include "data_typedef.h"

#define secretKey "1357975312468642"				//IC卡号密钥1357975312468642
// #define secretKey "2468642135797531"				//IC卡号密钥2468642135797531

uint8_t secretKeyBit[16];					//分离出来的16位十进制密钥
uint8_t checkBit;									//卡号校验位


static void SecretCardNumHEX2Bit(uint8_t outputBuf[], uint8_t inputBuf[]);


void showCardHex1(uint8_t *buf, uint8_t len)
{
	uint8_t i;
	
	printf("\r\n");
	for(i=0; i<len; i++)
	{
		printf("%02X ",buf[i]);
	}
	printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: SecretCardNumHEX2Bit
*	功能说明: 16进制卡号分离出17位10进制数
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
static void SecretCardNumHEX2Bit(uint8_t outputBuf[], uint8_t inputBuf[])
{
	uint8_t i;
	uint32_t dataTemp;
	
	//区号
	dataTemp = inputBuf[0] << 16;
	dataTemp |= inputBuf[1] << 8;
	dataTemp |= inputBuf[2];	
	
	//分离区号
	outputBuf[0] = dataTemp/Pow(10, 5);
	outputBuf[1] = (dataTemp/Pow(10, 4))%10;
	outputBuf[2] = (dataTemp/Pow(10, 3))%10;
	outputBuf[3] = (dataTemp/Pow(10, 2))%10;
	outputBuf[4] = (dataTemp/Pow(10, 1))%10;
	outputBuf[5] = (dataTemp%10);
	
// 		printf("\r\n%6d", dataTemp);
	
	//流水号
	dataTemp = inputBuf[3] << 24;
	dataTemp |= inputBuf[4] << 16;
	dataTemp |= inputBuf[5] << 8;
	dataTemp |= inputBuf[6];		
	
// 		printf("%8d", dataTemp);
	
	//分离出流水号
	outputBuf[6] = dataTemp/Pow(10, 7);
	outputBuf[7] = (dataTemp/Pow(10, 6))%10;
	outputBuf[8] = (dataTemp/Pow(10, 5))%10;
	outputBuf[9] = (dataTemp/Pow(10, 4))%10;
	outputBuf[10] = (dataTemp/Pow(10, 3))%10;
	outputBuf[11] = (dataTemp/Pow(10, 2))%10;
	outputBuf[12] = (dataTemp/Pow(10, 1))%10;
	outputBuf[13] = (dataTemp%10);
	
	//分离出预留号
	outputBuf[14] = inputBuf[7]/10;
	outputBuf[15] = inputBuf[7]%10;
	
// 		printf("%2d", inputBuf[7]);
	
	//分离出校验位
	outputBuf[16] = (inputBuf[8]%10);

// 		printf("%1d", inputBuf[8]);	
	
// 	printf("\r\n卡号为：");
// 	for(i = 0; i < 17; i++)
// 	{
// 		printf("%d ", outputBuf[i]);
// 	}
// 	printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: SecretKeyHEX2Bit
*	功能说明: 16进制密钥分离出16位10进制数
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void SecretKeyHEX2Bit(uint8_t outputBuf[], char *inputStr)
{
	uint16_t i;
	char keyStr[17];
	
	sprintf(keyStr, "%s", inputStr);
	
// 	printf("\r\n密钥为：");
	for(i = 0; i < 16; i++)
	{
		outputBuf[i] = keyStr[i] - '0';
// 		printf("%d ", outputBuf[i]);
	}
// 	printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: CalculateCheckDigit
*	功能说明: 计算卡号校验位
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
uint8_t CalculateCheckDigit(uint8_t cardNumBit[], uint8_t keyBit[])
{
	uint8_t crc = 0;
	uint16_t i;
	uint16_t encryptionSum = 0;
	uint16_t sum = 0;
	uint8_t remainder = 0;
	
	//计算校验位
	for(i = 0; i < 16; i++)
	{
		sum = cardNumBit[i] * keyBit[i];
		encryptionSum += sum;
	}
// 		printf("\r\n%d \r\n", encryptionSum);
	remainder = encryptionSum % 11;
// 		printf("\r\n%d \r\n", remainder);
	
	if(remainder == 10)
	{
		crc = 0;
	}else if(remainder == 0){
		crc = 5;
	}else{
		crc = remainder;
	}
	
// 	printf("\r\nIC卡校验信息：校验和 = %d, 余数 = %d, 校验位 = %d\r\n", encryptionSum, remainder, crc);
		
	return crc;
}

/*
***********************************************************************
*	函 数 名: IC_CardEncode
*	功能说明: IC卡编码
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void IC_CardEncode_YN(uint32_t areaCode, uint32_t serialNum, uint8_t cardType)
{
	uint8_t i;
	uint8_t cardNumBitBuf[17];				//卡号分离出来的17位十进制数据，用于计算校验位
	uint8_t checkBit = 0;

	memset(createCardNum, 0, 16);
	
	//生成区域号
	createCardNum[0] = (uint8_t)(areaCode >> 16);
	createCardNum[1] = (uint8_t)(areaCode >> 8);
	createCardNum[2] = (uint8_t)areaCode;
	
	//生成流水号
	createCardNum[3] = (uint8_t)(serialNum >> 24);
	createCardNum[4] = (uint8_t)(serialNum >> 16);
	createCardNum[5] = (uint8_t)(serialNum >> 8);
	createCardNum[6] = (uint8_t)serialNum;
	
	//生成卡类型
	createCardNum[7] = cardType;
	
	//生成校验位
	SecretCardNumHEX2Bit(cardNumBitBuf, createCardNum);
	SecretKeyHEX2Bit(secretKeyBit, secretKey);
	checkBit = CalculateCheckDigit(cardNumBitBuf, secretKeyBit);
	createCardNum[8] = checkBit;
	cardNumBitBuf[16] = checkBit;
	
	printf("\r\n生成卡号为：");
	for(i = 0; i < 17; i++)
	{
		printf("%d", cardNumBitBuf[i]);
	}
	printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: IC_CardDecode_YN
*	功能说明: 粤能IC卡解码
*	形    参：无
*	返 回 值: 解码成功返回1，不成功返回0
***********************************************************************
*/
uint8_t IC_CardDecode_YN(void)
{
	uint8_t res = 0;
	uint8_t i;
	uint8_t checkBit;
	
	SecretCardNumHEX2Bit(cardNumberBit, RFID_ID);
	SecretKeyHEX2Bit(secretKeyBit, secretKey);
	checkBit = CalculateCheckDigit(cardNumberBit, secretKeyBit);
	
	if(checkBit == cardNumberBit[16])		//IC卡的校验正确，则标志刷卡有效
	{
		printf("\r\nIC卡号：");
		for(i = 0; i < 17; i++)
		{
			cardNumberStr[i] = cardNumberBit[i] + '0';
			printf("%d", cardNumberBit[i]);
		}
		printf("\r\n");
	
		if((cardNumberBit[14] == 0) && (cardNumberBit[15] == 1))
		{
			RFID_state = 1;						//RFID_IC刷卡状态（有无刷卡：1->有刷卡，0->无刷卡，2->开门卡）外部程序调取后清除
			printf("\r\nIC卡有效，用户卡！！！\r\n");
			res = 1;
		}else if((cardNumberBit[14] == 5) && (cardNumberBit[15] == 5)){
			RFID_state = 2;						//RFID_IC刷卡状态（有无刷卡：1->有刷卡，0->无刷卡，2->开门卡）外部程序调取后清除
			printf("\r\nIC卡有效，收运卡！！！\r\n");
			res = 1;
		}else{
			RFID_state = 0;
		}
		
	}else{
// 		printf("\r\nIC卡无效！！！\r\n");
	}
	
	return res;
}

/******************** (C) COPYRIGHT 2017 ping *****END OF FILE*******************/
