#include "stdafx.h"
#include "UHFCaenProtocol.h"
#include "Utility.h"


typedef struct _CAEN_CMD 
{
	BYTE*	pCmd;
	BYTE	bCmdData;
}CAEN_CMD, *PCAEN_CMD;

CAEN_CMD tbCmd[] =
{
	{(BYTE*)"\x9E", 0x01}, // get reader name 
	{(BYTE*)"\x9E", 0x01}, // get serial 
	{(BYTE*)"\x7C", 0x01}, // get firmware rev
	{(BYTE*)"\x73", 0x01}, // get antenna power
	{(BYTE*)"\x79", 0x01}, // get protocol
	{(BYTE*)"\xA4", 0x01}, // get rfchannel
	{(BYTE*)"\x74", 0x01}, // set protocol
	{(BYTE*)"\x13", 0x01}, // get cards
	{(BYTE*)"\x96", 0x01}, // read
	{(BYTE*)"\x97", 0x01}, // write
	{(BYTE*)"\x98", 0x01}, // lock
	{(BYTE*)"\x99", 0x01}, // kill
};

CUHFCaenProtocol::CUHFCaenProtocol()
{

}

CUHFCaenProtocol::~CUHFCaenProtocol()
{

}

EERROR CUHFCaenProtocol::Open()
{
	return m_clsTransport.Open();
}

void CUHFCaenProtocol::SetCom(UINT nCom)
{
	m_clsTransport.SetOption(nCom, 115200);
}

void CUHFCaenProtocol::SetReadWriteInfo(READ_WRITE_INFO* pReadWriteInfo)
{
	if(pReadWriteInfo != NULL)
	{
		m_stReadWriteInfo = *pReadWriteInfo;
	}
}

#define CAEN_ANTET	0x0A
#define CMD_ANTET	0x08
#define DATA_ANTET	0x03
#define ERROR_ANTET	0x08

#define START_CAEN_ANTET	"\x80\x01\x00\x00\x00\x00\x53\x58\x00\x00"
#define START_CMD_ANTET		"\x00\x00\x00\x08\x00\x01\x00\x00"
EERROR CUHFCaenProtocol::SendCmd(ERF_CMD eCmd, BYTE* pData, DWORD dwData)
{
	// total Len = 3 bytes RFE + cmd +  2 bytes len + data + 2 bytes check sum
	DWORD dwCmdLen = CAEN_ANTET + CMD_ANTET + dwData;

	BYTE* pDataSend = new BYTE[dwCmdLen];
	ZeroMemory(pDataSend, dwCmdLen);

	// START + CMD tag
	BYTE* pDataNav = pDataSend;
	memcpy_s(pDataNav, dwCmdLen, START_CAEN_ANTET, CAEN_ANTET);				pDataNav = pDataNav + CAEN_ANTET;
	memcpy_s(pDataNav, dwCmdLen, START_CMD_ANTET, CMD_ANTET);				pDataNav = pDataNav + CMD_ANTET;

	DATA_STRUCT* pDataInfo = (DATA_STRUCT*)pDataSend;	// navigate to caen antet
	if(pDataInfo != NULL)
	{
		pDataInfo->stProt.bLength[0x00] = (BYTE)(dwCmdLen >> 0x08);
		pDataInfo->stProt.bLength[0x01] = (BYTE)(dwCmdLen & 0xFF);
	}

	pDataInfo = (DATA_STRUCT*)(pDataSend + CAEN_ANTET);	// navigate to caen cmd
	if(pDataInfo != NULL)
	{
		pDataInfo->stCmd.bCmdVal[0x01] = tbCmd[eCmd].pCmd[0x00];
	}
	memcpy_s(pDataNav, dwCmdLen, pData, dwData);

	EERROR eRet = m_clsTransport.Write(pDataSend, dwCmdLen);
	delete[] pDataSend;

	return eRet;
}

#define ATTRIB_ANTET	0x06
void CUHFCaenProtocol::CreateAtribb(EATTRIB_TYPE eAttrib, BYTE* pData, DWORD dwSize, BYTE** pRetData, DWORD& dwRetSize)
{
	if((pData != NULL) && (pRetData != NULL))
	{
		DWORD dwAttribLen = ATTRIB_ANTET + dwSize;

		BYTE* pDataAttrib = new BYTE[dwAttribLen];
		ZeroMemory(pDataAttrib, dwAttribLen);

		pDataAttrib[0x03] = (BYTE)dwAttribLen;
		pDataAttrib[0x05] = (BYTE)eAttrib;
		memcpy_s(pDataAttrib + 0x06, dwAttribLen, pData, dwSize);
		*pRetData = pDataAttrib;
		dwRetSize = dwAttribLen;
	}
}


EERROR CUHFCaenProtocol::GetAttribData(DWORD dwCmd, BYTE** pData, DWORD& dwData, BOOL bError)
{
	EERROR eRet = ER_INVALID_DATA;
	if(pData != NULL)
	{
		// read first only anttent
		BYTE pDataAnt[CAEN_ANTET];
		ULONG ulRead = CAEN_ANTET;

		// read first antet and then calculate rest of data
		if((eRet = m_clsTransport.Read(pDataAnt, ulRead)) == ER_OK)
		{
			DWORD dwRetData = CUtility::GetShort(pDataAnt + (CAEN_ANTET - 0x02));
			BYTE* pDataRcv = new BYTE[dwRetData];
			memcpy_s(pDataRcv, dwRetData, pDataAnt, CAEN_ANTET);
			dwRetData -= ulRead;

			if((eRet = m_clsTransport.Read(pDataRcv + ulRead, dwRetData)) == ER_OK)
			{
				dwRetData += ulRead;

				if(bError)
				{
					eRet = GetErrorAttrib(pDataRcv + (dwRetData - ERROR_ANTET), ERROR_ANTET);
				}

				if(eRet == ER_OK)
				{
					eRet = ER_INVALID_POINTER;
					DATA_STRUCT* pDataInfo = (DATA_STRUCT*)(pDataRcv + CAEN_ANTET);	// navigate to caen cmd
					if(pDataInfo != NULL)
					{
						eRet = ER_TAG_CMD;
						if(pDataInfo->stCmd.bCmdVal[0x01] == tbCmd[dwCmd].pCmd[0x00])
						{
							eRet = ER_OK;
							dwData = dwRetData - (CAEN_ANTET + CMD_ANTET + (bError ? ERROR_ANTET : 0x00)) ;
							if(dwData > 0x00)
							{
								*pData = new BYTE[dwData];
								eRet = CUtility::SetDataByte(pDataRcv + (CAEN_ANTET + CMD_ANTET), dwData, *pData, dwData);
							}
						}
					}
				}
			}
			delete[] pDataRcv;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::ProcessAttrib(BYTE bAttribType, BYTE* pData, DWORD dwSize, BYTE** pRetData, DWORD& dwRetSize, DWORD& dwTotalSize)
{
	EERROR eRet = ER_INVALID_POINTER;
	if((pData != NULL) && (pRetData != NULL))
	{
		DATA_STRUCT* pDataInfo = (DATA_STRUCT*)pData;
		if(pDataInfo != NULL)
		{
			eRet = ER_NAK;
			if(bAttribType == pDataInfo->stAttrib.bSourceName[0x01])
			{
				dwTotalSize = CUtility::GetShort(pDataInfo->stAttrib.bLength);
				dwRetSize	= dwTotalSize - ATTRIB_ANTET;
				*pRetData	= new BYTE[dwRetSize];
				eRet = CUtility::SetDataByte(pDataInfo->stAttrib.bData, dwRetSize, *pRetData, dwRetSize);
			}
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetErrorAttrib(BYTE* pData, DWORD dwSize)
{
	BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00, dwTotalData = 0x00;
	EERROR eRet = ProcessAttrib(ATTRIB_ERROR, pData, dwSize, &pDataRet, dwDataRet, dwTotalData);
	if(eRet == ER_OK)
	{
		eRet = ER_TAG_LEN;
		if(dwDataRet == 0x02)
		{
			eRet = ER_OTHER_ERROR;
			if(CUtility::GetShort(pDataRet) == 0x00)
			{
				eRet = ER_OK;
			}
		}
	}
	delete[] pDataRet;

	return eRet;
}

EERROR CUHFCaenProtocol::GetReaderName(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_READER_NAME, NULL, 0x00);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_READER_NAME, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_READER_INFO, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				BYTE* pDataEnd = (BYTE*)strstr((CHAR*)pDataAttrib, " ");
				DWORD dwDataSize = (DWORD)(pDataEnd - pDataAttrib);
				eRet = CUtility::SetDataByte(pDataAttrib, dwDataSize, pData, dwSize);

				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetReaderSerial(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_READER_NAME, NULL, 0);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_READER_NAME, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_READER_INFO, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				BYTE* pDataEnd = (BYTE*)strstr((CHAR*)pDataAttrib, " ");
				DWORD dwDataSize = dwDataRet - ((DWORD)(pDataEnd - pDataAttrib) + 0x01);
				eRet = CUtility::SetDataByte(pDataEnd + 0x01, dwDataSize, pData, dwSize);

				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetFirmwareRaw(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_GET_FIRMWARE, NULL, 0);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_GET_FIRMWARE, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_FIRMWARE, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				eRet = CUtility::SetDataByte(pDataAttrib, dwDataAttrib, pData, dwSize);
				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetAntennaPower(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_ANTENNA_POWER, NULL, 0);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_ANTENNA_POWER, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_ANT_POWER, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				eRet = CUtility::SetDataByte(pDataAttrib, dwDataAttrib, pData, dwSize);
				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetProtocol(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_GET_PROTOCOL, NULL, 0);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_GET_PROTOCOL, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_PROTOCOL, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				eRet = CUtility::SetDataByte(pDataAttrib, dwDataAttrib, pData, dwSize);
				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::SetProtocol(BYTE* pData, DWORD dwSize)
{
	EERROR eRet = ER_INVALID_DATA;
	if(dwSize == 0x01)
	{
		eRet = ER_NOT_IMPLEMENTED;
		if(*pData == 0x03)
		{
			BYTE* pDataRet = NULL; DWORD dwRetData;
			CreateAtribb(ATTRIB_PROTOCOL, (BYTE*)"\x00\x00\x00\x03", 0x04, &pDataRet, dwRetData);
			if((eRet = SendCmd(RF_SET_PROTOCOL, pDataRet, dwRetData)) == ER_OK)
			{
				BYTE* pDataProt = NULL;DWORD dwDataProt;
				eRet = GetAttribData(RF_SET_PROTOCOL, &pDataProt, dwDataProt);
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::GetRFChannel(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = SendCmd(RF_GET_RFCHANNEL, NULL, 0);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_GET_RFCHANNEL, &pDataRet, dwDataRet)) == ER_OK)
		{
			BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
			if((eRet = ProcessAttrib(ATTRIB_RFCHANNEL, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
			{
				eRet = CUtility::SetDataByte(pDataAttrib, dwDataAttrib, pData, dwSize);
				delete[] pDataAttrib;
			}
			delete[] pDataRet;
		}
	}
	return eRet;
}

#define CARD_INFO_LEN	0x4A
#define CARD_INFO		0x31

EERROR CUHFCaenProtocol::GetCard(BYTE* pData, DWORD& dwData)
{
	BYTE* pDataRet = NULL; DWORD dwRetData;
	CreateAtribb(ATTRIB_SOURCE, (BYTE*)"Source_0", strlen("Source_0") + 0x01, &pDataRet, dwRetData);

	EERROR eRet = SendCmd(RF_GET_CARDS, pDataRet, dwRetData);
	if(eRet == ER_OK)
	{
		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = GetAttribData(RF_GET_CARDS, &pDataRet, dwDataRet)) == ER_OK)
		{
			DWORD dwTotalCards = (dwDataRet / CARD_INFO_LEN);
			BYTE* pCardData = new BYTE[CARD_INFO * dwTotalCards];

			DWORD dwNav = 0x00, dwCardNav = 0x00;
			while((dwNav < dwDataRet) && (eRet == ER_OK))
			{
				DATA_STRUCT* pDataStruct = (DATA_STRUCT*)(pDataRet + dwNav);
				DATA_STRUCT* pCardStruct = (DATA_STRUCT*)(pCardData + dwCardNav);
				WORD wAttrib = CUtility::GetShort(pDataStruct->stAttrib.bSourceName);

				BYTE* pAttribData = NULL; DWORD dwAttribData = 0x00, dwTotalData = 0x00;
				eRet = ProcessAttrib((BYTE)wAttrib, pDataRet + dwNav, dwDataRet - dwNav, &pAttribData, dwAttribData, dwTotalData);

				if(eRet == ER_OK)
				{
					switch(wAttrib)
					{
						case ATTRIB_CARD_LEN:
						{
							pCardStruct->stCardInfo.nLength = (BYTE)CUtility::GetShort(pAttribData);
						}break;

						case ATTRIB_TIME:
						{
							ZeroMemory(pCardStruct->stCardInfo.pTime, 0x10);
							memcpy_s(pCardStruct->stCardInfo.pTime, 0x10, pAttribData, dwAttribData);
						}break;

						case ATTRIB_ID:
						{
							ZeroMemory(pCardStruct->stCardInfo.pCardId, 0x20);
							memcpy_s(pCardStruct->stCardInfo.pCardId, 0x20, pAttribData, dwAttribData);
							dwCardNav += CARD_INFO;
						}break;
					}
				}

				delete[] pAttribData;
				dwNav += dwTotalData;
			}

			delete[] pDataRet;
			if(eRet == ER_OK)
			{
				CUtility::SetDataByte(pCardData, CARD_INFO * dwTotalCards, pData, dwData);
			}
		}
	}
	return eRet;
}

EERROR CUHFCaenProtocol::Read(BYTE* pData, DWORD& dwData)
{
	EERROR eRet = ER_INVALID_DATA;
	if(pData != NULL)
	{
		BYTE pDataSend[MAX_PATH]; DWORD dwNav = 0x00; BYTE pDataTmp[0x20];
		ZeroMemory(pDataSend, MAX_PATH);

		BYTE* pDataRet = NULL; DWORD dwRetData;
		CreateAtribb(ATTRIB_SOURCE, (BYTE*)"Source_0", strlen("Source_0") + 0x01, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = m_stReadWriteInfo.nCardIdLen;

		CreateAtribb(ATTRIB_CARD_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, m_stReadWriteInfo.pCardId, m_stReadWriteInfo.nCardIdLen);
		CreateAtribb(ATTRIB_ID, pDataTmp, m_stReadWriteInfo.nCardIdLen, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = m_stReadWriteInfo.bBank;
		CreateAtribb(ATTRIB_BANK_ID, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = (BYTE)(m_stReadWriteInfo.ulStartAddress >> 0x08);
		pDataTmp[0x01] = (BYTE)m_stReadWriteInfo.ulStartAddress;
		CreateAtribb(ATTRIB_ADDRESS, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = (BYTE)(dwData >> 0x08);
		pDataTmp[0x01] = (BYTE)dwData;
		CreateAtribb(ATTRIB_OP_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		eRet = SendCmd(RF_READ, pDataSend, dwNav);
		if(eRet == ER_OK)
		{
			BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
			if((eRet = GetAttribData(RF_READ, &pDataRet, dwDataRet)) == ER_OK)
			{
				BYTE* pDataAttrib = NULL; DWORD dwDataAttrib = 0x00, dwTotalDataAttrib = 0x00;
				if((eRet = ProcessAttrib(ATTRIB_DATA_READ, pDataRet, dwDataRet, &pDataAttrib, dwDataAttrib, dwTotalDataAttrib)) == ER_OK)
				{
					eRet = CUtility::SetDataByte(pDataAttrib, dwDataAttrib, pData, dwData);
					delete[] pDataAttrib;
				}
				delete[] pDataRet;
			}
		}
	}

	return eRet;
}

EERROR CUHFCaenProtocol::Write(BYTE* pData, DWORD dwData)
{
	EERROR eRet = ER_INVALID_DATA;
	if(pData != NULL)
	{
		BYTE* pDataSend = new BYTE[MAX_PATH + dwData];
		DWORD dwNav = 0x00; BYTE pDataTmp[0x20];
		ZeroMemory(pDataSend, MAX_PATH + dwData);

		BYTE* pDataRet = NULL; DWORD dwRetData;
		CreateAtribb(ATTRIB_SOURCE, (BYTE*)"Source_0", strlen("Source_0") + 0x01, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = m_stReadWriteInfo.nCardIdLen;

		CreateAtribb(ATTRIB_CARD_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, m_stReadWriteInfo.pCardId, m_stReadWriteInfo.nCardIdLen);
		CreateAtribb(ATTRIB_ID, pDataTmp, m_stReadWriteInfo.nCardIdLen, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = m_stReadWriteInfo.bBank;
		CreateAtribb(ATTRIB_BANK_ID, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = (BYTE)(m_stReadWriteInfo.ulStartAddress >> 0x08);
		pDataTmp[0x01] = (BYTE)m_stReadWriteInfo.ulStartAddress;
		CreateAtribb(ATTRIB_ADDRESS, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = (BYTE)(dwData >> 0x08);
		pDataTmp[0x01] = (BYTE)dwData;
		CreateAtribb(ATTRIB_OP_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		CreateAtribb(ATTRIB_DATA_READ, pData, dwData, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		eRet = SendCmd(RF_WRITE, pDataSend, dwNav);
		if(eRet == ER_OK)
		{
			BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
			eRet = GetAttribData(RF_WRITE, &pDataRet, dwDataRet);
			delete[] pDataRet;
		}
	}

	return eRet;
}

EERROR CUHFCaenProtocol::KillTag(KILL_TAG_INFO* pKillTag)
{
	EERROR eRet = ER_INVALID_DATA;
	if(pKillTag != NULL)
	{
		BYTE* pDataSend = new BYTE[MAX_PATH];
		DWORD dwNav = 0x00; BYTE pDataTmp[0x20];
		ZeroMemory(pDataSend, MAX_PATH);

		BYTE* pDataRet = NULL; DWORD dwRetData;
		CreateAtribb(ATTRIB_SOURCE, (BYTE*)"Source_0", strlen("Source_0") + 0x01, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = pKillTag->nCardIdLen;

		CreateAtribb(ATTRIB_CARD_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, pKillTag->pCardId, pKillTag->nCardIdLen);
		CreateAtribb(ATTRIB_ID, pDataTmp, pKillTag->nCardIdLen, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, pKillTag->pPass, 0x04);
		CreateAtribb(ATTRIB_CARD_PASS, pDataTmp, 0x04, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		eRet = SendCmd(RF_KILL, pDataSend, dwNav);
		if(eRet == ER_OK)
		{
			BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
			eRet = GetAttribData(RF_KILL, &pDataRet, dwDataRet);
			delete[] pDataRet;
		}

	}
	return eRet;
}

EERROR CUHFCaenProtocol::LockTag(LOCK_TYPE_INFO* pLockType)
{
	EERROR eRet = ER_INVALID_DATA;
	if(pLockType != NULL)
	{
		BYTE* pDataSend = new BYTE[MAX_PATH];
		DWORD dwNav = 0x00; BYTE pDataTmp[0x20];
		ZeroMemory(pDataSend, MAX_PATH);

		BYTE* pDataRet = NULL; DWORD dwRetData;
		CreateAtribb(ATTRIB_SOURCE, (BYTE*)"Source_0", strlen("Source_0") + 0x01, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		pDataTmp[0x00] = 0x00;
		pDataTmp[0x01] = pLockType->nCardIdLen;

		CreateAtribb(ATTRIB_CARD_LEN, pDataTmp, 0x02, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, pLockType->pCardId, pLockType->nCardIdLen);
		CreateAtribb(ATTRIB_ID, pDataTmp, pLockType->nCardIdLen, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		memcpy_s(pDataTmp, 0x20, pLockType->pPass, 0x04);
		CreateAtribb(ATTRIB_CARD_PASS, pDataTmp, 0x04, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		ZeroMemory(pDataTmp, 0x20);
		pDataTmp[0x02] = pLockType->bLockType;
		pDataTmp[0x03] = pLockType->bBank;
		CreateAtribb(ATTRIB_LOCK_TYPE, pDataTmp, 0x04, &pDataRet, dwRetData);
		memcpy_s(pDataSend + dwNav, MAX_PATH, pDataRet, dwRetData);
		dwNav += dwRetData;
		delete[] pDataRet;

		eRet = SendCmd(RF_LOCK_TAG, pDataSend, dwNav);
		if(eRet == ER_OK)
		{
			BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
			eRet = GetAttribData(RF_LOCK_TAG, &pDataRet, dwDataRet);
			delete[] pDataRet;
		}

	}
	return eRet;
}

EERROR CUHFCaenProtocol::Close()
{
	return m_clsTransport.Close();
}