DLCamCardManager.cpp 7.13 KB
#include "stdafx.h"
#include <exception>
#include <cstdint>
#include <sstream>
#include <iomanip> // hex conversion.
#include <intrin.h>
#include "etradeclient/hardware/DLCamCardManager.h"
#include "etradeclient/hardware/ex_reference/bank_card_reader/dcrf32.h"
#include "ETradeClient/hardware/dili_card_device.h"
 // Endian conversion.

static const uint8_t CARD_CHIP_NUM_LEN = 12; // 卡面号
static const uint8_t CARD_TYPE_CODE_LEN = 16; // 卡片类型码(卡类型编码)
static const uint8_t CARD_ISSUER_CODE_LEN = 20; // 发卡机构编码
static const uint8_t CARD_VERIFY_CODE_LEN = 8; // 校验码(安全码编码(3位数))
static const uint8_t CARD_SN_LEN = 32; // 卡片内码, 卡序列号SN

static const uint8_t CARD_TYPE_CODE_LEN_USE = 6;
static const uint8_t CARD_ISSUER_CODE_LEN_USE = 4;
static const uint8_t CARD_VERIFY_CODE_LEN_USE = 3;

static const char PADDING_CHAR = 'f';

template <typename T>
std::string DecToHex(T d, bool show_base = false)
{
	std::stringstream ss;
	if (show_base)
		ss << "0x";
	ss << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << static_cast<int>(d);
	return ss.str();
}

DLCamCardManager::DLCamCardManager() :
m_icdev(NULL)
{}

DLCamCardManager::~DLCamCardManager()
{
	DisConnect();
}

std::string DLCamCardManager::HexToChar(unsigned char* pHex, int iLen)
{
	std::string sResult;
	if (pHex && iLen)
	{
		for (int index = 0; index < iLen; ++index)
		{
			char cNum[3] = { 0 };
			sprintf_s(cNum, "%2X", pHex[index]);
			sResult.append(cNum, 2);
		}
	}
	return sResult;
}

bool DLCamCardManager::CheckOrderResult(unsigned char* pResult, unsigned char cLen)
{
	bool bResult = false;
	if (pResult[(int)cLen - 2] == 0x90 &&
		pResult[(int)cLen - 1] == 0x00)
	{
		bResult = true;
	}
	return bResult;
}

bool DLCamCardManager::Connect()
{
	static const uint8_t RETRY_COUNT = 10;

	const int kUSBPort = 100, kBaudRate = 0; // port 为 100时,表示使用USB接口通讯,则波特率无效,因此设置为0.
	const int kBeepMs = 10;
	uint8_t conn_count = 0;
	do
	{
		m_icdev = dc_init(kUSBPort, kBaudRate);
		if (0 < (int)m_icdev)
		{
			dc_beep(m_icdev, kBeepMs);
			return true;
		}
		++conn_count;
	} while (conn_count < RETRY_COUNT);
	return false;
}

bool DLCamCardManager::DisConnect()
{
	bool bResult = false;
	if (m_icdev)
	{
		int iResult = dc_exit(m_icdev);
		if (iResult)
		{
			bResult = false;
		}
		else
		{
			bResult = true;
		}
	}
	return bResult;
}

bool DLCamCardManager::SelectMF()
{
	bool bResult = true;

	const int kOK = 0;
	const unsigned int kTimeout = 7; // 延迟时间,单位为:10ms, 7 来自与官方示例,该值如果设过大会导致操作失败.
	const unsigned int kMaxDataSize = 512;
	const unsigned char kSendDataLen = 7; // 发送的信息长度
	unsigned char recv_data_len = 0; // 读取信息的长度
	unsigned char send_data[kMaxDataSize] = { 0 }, recv_data[kMaxDataSize] = { 0 };

	send_data[0] = 0x00; // CLA
	send_data[1] = 0xA4; // INS
	send_data[2] = 0x00; // P1,按文件名选择DF
	send_data[3] = 0x00; // P2
	send_data[4] = 0x02; // Lc 数据长度
	// Data:DF文件名
	send_data[5] = 0x3F;
	send_data[6] = 0x00;

	__int16 iResult = 0;
	if (m_icdev)
	{
		iResult = dc_pro_command(m_icdev, kSendDataLen, send_data, &recv_data_len, recv_data, kTimeout);
	}
	else
	{
		bResult = false;
		throw std::exception("Card reader handle is empty!");
	}
	
	
	if (iResult != kOK || !CheckOrderResult(recv_data, recv_data_len))
	{
		bResult = false;
		throw std::exception("Select MF failed!");
	}

	return bResult;
}

bool DLCamCardManager::SelectFile()
{
	bool bResult = false;
	
	const int kOK = 0;
	const unsigned int kTimeout = 7; // 延迟时间,单位为:10ms, 7 来自与官方示例,该值如果设过大会导致操作失败.
	const unsigned int kMaxDataSize = 512;
	const unsigned char kSendDataLen = 7; // 发送的信息长度
	unsigned char recv_data_len = 0; // 读取信息的长度
	unsigned char send_data[kMaxDataSize] = { 0 }, recv_data[kMaxDataSize] = { 0 };

	send_data[0] = 0x00; // CLA
	send_data[1] = 0xA4; // INS
	send_data[2] = 0x00; // P1,按文件名选择DF
	send_data[3] = 0x00; // P2
	send_data[4] = 0x02; // Lc 数据长度
	// Data:DF文件名
	send_data[5] = 0x00;
	send_data[6] = 0x05;

	__int16 iResult = 0;
	if (m_icdev)
	{
		iResult = dc_pro_command(m_icdev, kSendDataLen, send_data, &recv_data_len, recv_data, kTimeout);
	}
	else
	{
		bResult = false;
		throw std::exception("Card reader handle is empty!");
	}
	if (iResult != kOK || !CheckOrderResult(recv_data, recv_data_len))
	{
		bResult = false;
		throw std::exception("Select 0x05 file failed!");
	}

	return bResult;
}


std::string DLCamCardManager::ReadCardBasicFile()
{
	std::string sResult;
	const int kOK = 0;
	const unsigned int kTimeout = 7; // 延迟时间,单位为:10ms, 7 来自与官方示例,该值如果设过大会导致操作失败.
	const unsigned int kMaxDataSize = 512;
	const unsigned char kSendDataLen = 5; // 发送的信息长度
	unsigned char recv_data_len = 0; // 读取信息的长度
	unsigned char send_data[kMaxDataSize] = { 0 }, recv_data[kMaxDataSize] = { 0 };


	send_data[0] = 0x00; // CLA
	send_data[1] = 0xB0; // INS
	send_data[2] = 0x85; // P1
	send_data[3] = 0x00; // P2,按文件记录号访问
	send_data[4] = 0x2C; // Le

	bool bResult = true;
	__int16 iResult = 0;
	if (m_icdev)
	{
		iResult = dc_pro_command(m_icdev, kSendDataLen, send_data, &recv_data_len, recv_data, kTimeout);
	}
	else
	{
		bResult = false;
		throw std::exception("Card reader handle is empty!");
	}
	if (iResult != kOK || !CheckOrderResult(recv_data, recv_data_len))
	{
		bResult = false;
		throw std::exception("Read data at 0x05 file failed!");
	}

	if (bResult)
	{
		RecordDataT sTemp = RecordDataT(recv_data, recv_data_len);
		for (int index = 0; index < (int)recv_data_len - 2; ++index)
			sResult.append(DecToHex(sTemp.at(index)));
	}
	return sResult;
}

DILICard::BasicInfo DLCamCardManager::ReadCardBasicInfo()
{
	std::string basic_info_str = ReadCardBasicFile();
	int iTotalLength = basic_info_str.size();
	if (basic_info_str.size() < iTotalLength)
	{
		throw std::exception("Card basic info error!");
	}
	DILICard::BasicInfo basic_info;

	uint32_t offset = 0;
	basic_info.chip_num = basic_info_str.substr(offset, CARD_CHIP_NUM_LEN);
	offset += CARD_CHIP_NUM_LEN;

	std::string field;
	field = basic_info_str.substr(offset, CARD_TYPE_CODE_LEN);
	basic_info.type_code = field.substr(0, CARD_TYPE_CODE_LEN_USE);
	offset += CARD_TYPE_CODE_LEN;

	field = basic_info_str.substr(offset, CARD_ISSUER_CODE_LEN);
	basic_info.issuer_code = field.substr(0, CARD_ISSUER_CODE_LEN_USE);
	offset += CARD_ISSUER_CODE_LEN;

	field = basic_info_str.substr(offset, CARD_VERIFY_CODE_LEN);
	basic_info.verify_code = field.substr(0, CARD_VERIFY_CODE_LEN_USE);
	offset += CARD_VERIFY_CODE_LEN;

	//sn号全为f或者全为0时,入库会有问题,暂时用卡面号替代sn号 add by liuye 2017.7.27
	//basic_info.device_id = basic_info_str.substr(offset, CARD_SN_LEN);
	basic_info.device_id = basic_info.chip_num;
	//

	return basic_info;
}

void DLCamCardManager::FindAndResetCard()  // 寻卡并复位卡片
{
	unsigned long snr = 0;
	unsigned char lenth[128] = { 0 };
	unsigned char data[128] = { 0 };
	int st = 0;

	if (m_icdev)
	{
		st = dc_card(m_icdev, 0, &snr); // 一定要先寻卡
		if (0 != st)
			throw std::exception("Find dili card failed!");
		st = dc_pro_reset(m_icdev, lenth, data);
		if (0 != st)
			throw std::exception("Reset dili card failed!");
	}
	else
	{
		throw std::exception("Card reader handle is empty!");
	}
	
}