#pragma once

#include "TransportSerial.h"

typedef struct _READ_WRITE_INFO
{
	BYTE	nCardIdLen;
	BYTE	pCardId[0x20];
	BYTE	pPass[0x04];
	BYTE	bBank;
	ULONG	ulStartAddress;
}READ_WRITE_INFO;

typedef struct _KILL_TAG_INFO
{
	BYTE	nCardIdLen;
	BYTE	pCardId[0x20];
	BYTE	pPass[0x04];
}KILL_TAG_INFO;

typedef struct _LOCK_TYPE_INFO
{
	BYTE	nCardIdLen;
	BYTE	pCardId[0x20];
	BYTE	pPass[0x04];
	BYTE	bBank;
	BYTE	bLockType;
}LOCK_TYPE_INFO;

enum ERF_CMD
{
	RF_READER_NAME	= 0,
	RF_GET_SERIAL,
	RF_GET_FIRMWARE,
	RF_ANTENNA_POWER,
	RF_GET_PROTOCOL,
	RF_GET_RFCHANNEL,
	RF_SET_PROTOCOL,
	RF_GET_CARDS,
	RF_READ,
	RF_WRITE,
	RF_LOCK_TAG,
	RF_KILL,

	RF_UNKNOWN
};

enum EATTRIB_TYPE
{
	ATTRIB_ERROR		= 0x02,
	ATTRIB_CARD_LEN		= 0x0F,
	ATTRIB_TIME			= 0x10,
	ATTRIB_ID			= 0x11,
	ATTRIB_CARD_TYPE	= 0x12,
	ATTRIB_ANT_NAME		= 0x22,
	ATTRIB_DATA_READ	= 0x4D,
	ATTRIB_ADDRESS		= 0x4E,
	ATTRIB_OP_LEN		= 0x50,
	ATTRIB_ANT_POWER	= 0x52,
	ATTRIB_PROTOCOL		= 0x54,
	ATTRIB_FIRMWARE		= 0x5C,
	ATTRIB_BANK_ID		= 0x71,
	ATTRIB_LOCK_TYPE	= 0x72,
	ATTRIB_CARD_PASS	= 0x73,
	ATTRIB_READER_INFO	= 0x76,
	ATTRIB_RFCHANNEL	= 0x78,
	ATTRIB_SOURCE		= 0xFB,
};

class CUHFCaenProtocol
{
private:
	CTransportSerial	m_clsTransport;
	READ_WRITE_INFO		m_stReadWriteInfo;

private:
	EERROR SendCmd(ERF_CMD eCmd, BYTE* pData, DWORD dwData);
	EERROR GetAttribData(DWORD dwCmd, BYTE** pData, DWORD& dwData, BOOL bError = TRUE);
	void CreateAtribb(EATTRIB_TYPE eAttrib, BYTE* pData, DWORD dwSize, BYTE** pRetData, DWORD& dwRetSize);
	EERROR ProcessAttrib(BYTE bAttribType, BYTE* pData, DWORD dwSize, BYTE** pRetData, DWORD& dwRetSize, DWORD& dwTotalSize);
	EERROR GetErrorAttrib(BYTE* pData, DWORD dwSize);
public:
	CUHFCaenProtocol();
	virtual ~CUHFCaenProtocol();

	virtual EERROR Open();
	virtual EERROR GetReaderName(BYTE* pData, DWORD& dwSize);
	virtual EERROR GetReaderSerial(BYTE* pData, DWORD& dwSize);
	virtual EERROR GetFirmwareRaw(BYTE* pData, DWORD& dwSize);
	virtual EERROR GetAntennaPower(BYTE* pData, DWORD& dwSize);
	virtual EERROR GetProtocol(BYTE* pData, DWORD& dwSize);
	virtual EERROR GetRFChannel(BYTE* pData, DWORD& dwSize);
	virtual EERROR SetProtocol(BYTE* pData, DWORD dwSize);
	virtual EERROR GetCard(BYTE* pData, DWORD& dwData);
	virtual EERROR Read(BYTE* pData, DWORD& dwData);
	virtual EERROR Write(BYTE* pData, DWORD dwData);
	virtual EERROR KillTag(KILL_TAG_INFO* pKillTag);
	virtual EERROR LockTag(LOCK_TYPE_INFO* pLockType);

	virtual void SetCom(UINT nCom);
	virtual void SetReadWriteInfo(READ_WRITE_INFO* pReadWrite);
	virtual EERROR Close();
};