#pragma once

#include "Def.h"
#include "TransportSerial.h"

enum EHF_CMD
{
	HF_SET_ADDRESS	= 0,
	HF_SET_SPEED,
	HF_SET_SERIAL,
	HF_GET_SERIAL,
	HF_GET_USER_INFO,
	HF_GET_VERSION,
	HF_SET_LED1,
	HF_SET_LED2,
	HF_SET_BUZZ,

	HF_GET_CARDS,
	HF_READ_CARD,
	HF_WRITE_CARD,
	HF_STAY_QUIET,
	HF_SELECT_CARD,
	HF_RESET_CARD,
	HF_WRITE_AFI,
	HF_LOCK_AFI,
	HF_WRITE_DSFID,
	HF_LOCK_DSFID,

	HF_SYS_INFO,

	HF_GET_CARDS14443A,
	HF_READ_CARDS14443A,
	HF_WRITE_CARDS14443A,
	HF_INIT_VALUE14443A,
	HF_DECREASE_VALUE14443A,
	HF_INCREASE_VALUE14443A,

	HF_UNKNOWN
};

#define ISO14443A_KEY_LENGTH	0x06
typedef struct _ISO14443A_INFO
{
	BYTE pKey[ISO14443A_KEY_LENGTH];
	BYTE bKeyA;
	DWORD dwStartBlock;
	DWORD dwNrBlocks;
}ISO14443A_INFO, *PISO14443A_INFO;

typedef struct _ISO15693_INFO
{
	DWORD dwStartBlock;
	DWORD dwNrBlocks;
}ISO15693_INFO, *PISO15693_INFO;

class CHFProtocol
{
private:
	CTransportSerial	m_clsTransport;
	BYTE				m_bAddress;
	ISO14443A_INFO		m_stInfoIso14443A;
	ISO15693_INFO		m_stInfoIso15693;
	ECARDTYPE			m_eCardType;

private:
	EERROR SendCmd(EHF_CMD eCmd, BYTE* pData, DWORD dwData);
	EERROR RecvData(BYTE** pData, DWORD& dwSize);
	EERROR CheckProtocol(BYTE* pData, DWORD dwSize);
	EERROR WriteBlock15693(DWORD dwStartBlock, BYTE* pData, DWORD dwSize);
	EERROR ReadBlock15693(DWORD dwStartBlock, DWORD dwNrBlocks,  BYTE** pData, DWORD& dwData);
	EERROR Read14443AMaxBlock(BYTE* pKey, BOOL bKeyA, DWORD dwStartBlock, DWORD dwNrBlocks,  BYTE* pData, DWORD& dwData);
	EERROR Write14443AMaxBlock(BYTE* pKey, BOOL bKeyA, DWORD dwStartBlock, DWORD dwNrBlocks,  BYTE* pData, DWORD& dwData);

public:
	CHFProtocol();
	virtual ~CHFProtocol();

	virtual EERROR Open();
	virtual void SetCom(UINT nCom, UINT nSpeed);
	EERROR SetAddress(BYTE bAddress);
	EERROR SetSpeed(BYTE bSpeed);
	EERROR GetSerial(BYTE* pData, DWORD& dwSize);
	EERROR SetSerial(BYTE* pData, DWORD dwSize);
	EERROR GetFirmware(BYTE* pData, DWORD& dwSize);
	EERROR SetLed(UINT nLed, DWORD dwTimeUnit, DWORD dwTime);
	EERROR SetBuzz(DWORD dwTimeUnit, DWORD dwTime);

	virtual EERROR GetCards15693(BYTE** pCards, DWORD& dwSize);
	virtual EERROR ReadAFI_DSFID(BYTE& bAFI, BYTE& bDSFID);
	virtual EERROR Read15693(BYTE** pData, DWORD& dwData);
	virtual EERROR Write15693(BYTE* pData, DWORD dwSize);
	virtual EERROR Lock15693(DWORD dwAntena, CHAR* szCard, DWORD dwStartBlock, DWORD dwNrBlocks);
	virtual EERROR WriteAFI(BYTE bAFI);
	virtual EERROR WriteDSFID(BYTE bDSFID);
	virtual EERROR LockAFI();
	virtual EERROR LockDSFID();
	virtual EERROR Reset(CHAR* szCard);
	virtual EERROR StayQuiet(CHAR* szCard);
	virtual EERROR Select(CHAR* szCard);

	virtual EERROR GetCards14443A(BYTE** pCards, DWORD& dwSize);
	virtual EERROR GetUserDataInfo(CHAR* szCard, DWORD& dwBlocks, DWORD& dwBlockSize);
	virtual EERROR Read14443A(BYTE** pData, DWORD& dwData);
	virtual EERROR Write14443A(BYTE* pData, DWORD dwData);
	virtual EERROR Close();

	virtual void SetIso14443Info(ISO14443A_INFO* pstIso14443AInfo);
	virtual void SetIso15693Info(ISO15693_INFO* pstIso15693Info);
	virtual ECARDTYPE GetCardType();

};