#include "Platform.h"
#include <string.h>
#include <stdio.h>
#include "ONEReader.h"
#include "BaseCommunication.h"

#define base CCGOReader

CONEReader::CONEReader(CReader *Owner, CBaseCommunication *Communicator)
	:base(Owner, Communicator)
{
}

CONEReader::~CONEReader(void)
{
}

CJ_RESULT CONEReader::BuildReaderInfo()
{
	CJ_RESULT Res;

	Res = base::BuildReaderInfo();

	//KSE 12.6.2024    m_ReaderInfo.HardwareMask |= RSCT_READER_HARDWARE_MASK_RFID; //BKu: Warum? One hat kein RFID!

	return Res;
}



void CONEReader::SetHWString(char *String)
{
	if (m_ReaderInfo.HardwareVersion == 2 || m_ReaderInfo.HardwareVersion == 3)
		strcpy(String, "ON1_");  //STM32
	else
		strcpy(String, "ONE_");
}

void CONEReader::GetProductString(uint8_t *Product)
{
	if (m_ReaderInfo.HardwareVersion == 2 || m_ReaderInfo.HardwareVersion == 3)
	   memcpy(Product, "CJON1", 5);  //STM32
	else
	memcpy(Product, "CJONE", 5);
}

void CONEReader::CompressModifyStructure(CCID_Message& Message)
{
	if (Message.Data.Secure.Data.Modify.bNumberMessage == 0)
	{
		memmove(&(Message.Data.Secure.Data.Modify.bMsgIndex2), Message.Data.Secure.Data.Modify.bTeoPrologue, Message.dwLength - 17);
		Message.dwLength -= 2;
	}
	else if (Message.Data.Secure.Data.Modify.bNumberMessage != 3)
	{
		memmove(&(Message.Data.Secure.Data.Modify.bMsgIndex3), Message.Data.Secure.Data.Modify.bTeoPrologue, Message.dwLength - 17);
		Message.dwLength -= 1;
	}
}

uint32_t CONEReader::GetReadersInputBufferSize()
{
	return 2048;
}

#ifdef WITH_SECODER_INFO_OVERRIDE
CJ_RESULT CONEReader::KTLightCall(uint8_t *sad, uint8_t *dad, uint8_t *cmd, uint16_t lenc, int32_t Lc, uint8_t *data_ptr, int32_t Le, uint8_t *response, uint16_t *lenr)
{
	static const uint8_t SECODER3_INFO_0[] = {
		"\x40\x07""Secoder"
		"\x80\x05""1.2.0"
		"\x80\x05""1.1.2"
		"\x81\x21""Reiner Kartenger\x7b""te GmbH & Co.KG."
	};
	static const uint8_t SECODER3_INFO_1[] = {
		"\x84\x02""de"
		"\x90\x01\x01"
		"\xa0\x13\x40\x03""tan\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""aut\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""sig\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""gkp\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x16\x40\x03""ctn\x80\x05""1.2.1\x83\x05""1.0.0\x84\x01\x33"
		"\x90\x00"
	};

	CJ_RESULT res;
	uint16_t InLenr = *lenr;
	uint8_t ReaderId[20 + 2];
	uint8_t SWImpVers[10 + 2];
	uint8_t ReaderPorp[9 + 2];
	int lenReaderId = 0;
	int lenSWImpVers = 0;
	int lenReaderProp = 0;
	uint8_t *Tag92 = NULL;
	uint8_t *Tag83 = NULL;
	uint8_t *Tag91 = NULL;
	uint8_t inCmd1 = *(cmd + 1);

	memset(ReaderId, 0, sizeof(ReaderId)); 
	memset(SWImpVers, 0, sizeof(SWImpVers));

	if ((res = base::KTLightCall(sad, dad, cmd, lenc, Lc, data_ptr, Le, response, lenr)) == CJ_SUCCESS)
	{
		if (inCmd1 == 0x70 && m_ReaderInfo.Version >= 0x11)
		{
			if (GetEnviroment("SecoderInfoOverride", 0x00000001) > 0)
			{
				if (GetEnviroment("SecoderInfoOverride_ONE", 0x00000001) > 0)
				{
					if (((Tag91 = GetTag(response, *lenr - 2, 0x91, &lenReaderProp)) != NULL) &&
						((Tag92 = GetTag(response, *lenr - 2, 0x92, &lenReaderId)) != NULL) &&
						((Tag83 = GetTag(response, *lenr - 2, 0x83, &lenSWImpVers)) != NULL) &&
						(lenReaderId <= 20) && (lenSWImpVers <= 10) && (lenReaderProp == 9))
					{
						lenReaderProp += 2;
						memcpy(ReaderPorp, Tag91 - 2, lenReaderProp);

						lenReaderId += 2;
						memcpy(ReaderId, Tag92 - 2, lenReaderId);

						lenSWImpVers += 2;
						memcpy(SWImpVers, Tag83 - 2, lenSWImpVers);

						if (InLenr >= (sizeof(SECODER3_INFO_0) + lenReaderProp + lenReaderId + lenSWImpVers + sizeof(SECODER3_INFO_1)))
						{
							memcpy(response, SECODER3_INFO_0, sizeof(SECODER3_INFO_0) - 1);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1, ReaderPorp, lenReaderProp);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp, ReaderId, lenReaderId);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp + lenReaderId, SWImpVers, lenSWImpVers);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp + lenReaderId + lenSWImpVers, SECODER3_INFO_1, sizeof(SECODER3_INFO_1) - 1);
							*lenr = sizeof(SECODER3_INFO_0) - 1 + (USHORT)lenReaderProp + (USHORT)lenReaderId + (USHORT)lenSWImpVers + sizeof(SECODER3_INFO_1) - 1;
						}
						else
						{
							return CJ_ERR_RBUFFER_TO_SMALL;
						}
					}
				}
			}
		}
	}
	return res;
}
#endif


#include "eca_defines.h"

CJ_RESULT CONEReader::CtSetMFT(const uint8_t *const pData, uint32_t DataLen, uint32_t *Result)
{
	UNREFERENCED_PARAMETER(pData);
	UNREFERENCED_PARAMETER(DataLen);
	UNREFERENCED_PARAMETER(Result);

	return CJ_ERR_NOT_SUPPORTED;
}

CJ_RESULT CONEReader::CtGetMFT(cj_MFT_Info *const pData, uint32_t *const pNumElemnts)
{
	uint32_t nCount = 0;


	if (*pNumElemnts < 2)
	{
		*pNumElemnts = 0;
		return CJ_ERR_RBUFFER_TO_SMALL;
	}

	pData[nCount].FID = 1003;
	pData[nCount].Status = 1;
	strcpy((char*)pData[nCount].Name, "Secoder V 2.0");
	nCount++;

	pData[nCount].FID = 1;
	pData[nCount].Status = 1;
	strcpy((char*)pData[nCount].Name, "chipTAN 1.1");
	nCount++;

	*pNumElemnts = nCount;

	return CJ_SUCCESS;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////







CCYOReader::CCYOReader(CReader* Owner, CBaseCommunication* Communicator)
	:CONEReader(Owner, Communicator)
	//:base(Owner, Communicator)
{
}

CCYOReader::~CCYOReader(void)
{
}

CJ_RESULT CCYOReader::BuildReaderInfo()
{
	CJ_RESULT Res;

	Res = base::BuildReaderInfo();

	return Res;
}



void CCYOReader::SetHWString(char* String)
{
	strcpy(String, "CYO_");
	
}

void CCYOReader::GetProductString(uint8_t* Product)
{
    memcpy(Product, "CJCYO", 5);  //STM32
}

void CCYOReader::CompressModifyStructure(CCID_Message& Message)
{
	if (Message.Data.Secure.Data.Modify.bNumberMessage == 0)
	{
		memmove(&(Message.Data.Secure.Data.Modify.bMsgIndex2), Message.Data.Secure.Data.Modify.bTeoPrologue, Message.dwLength - 17);
		Message.dwLength -= 2;
	}
	else if (Message.Data.Secure.Data.Modify.bNumberMessage != 3)
	{
		memmove(&(Message.Data.Secure.Data.Modify.bMsgIndex3), Message.Data.Secure.Data.Modify.bTeoPrologue, Message.dwLength - 17);
		Message.dwLength -= 1;
	}
}

uint32_t CCYOReader::GetReadersInputBufferSize()
{
	return 2048;
}

#ifdef WITH_SECODER_INFO_OVERRIDE
CJ_RESULT CCYOReader::KTLightCall(uint8_t* sad, uint8_t* dad, uint8_t* cmd, uint16_t lenc, int32_t Lc, uint8_t* data_ptr, int32_t Le, uint8_t* response, uint16_t* lenr)
{
	static const uint8_t SECODER3_INFO_0[] = {
		"\x40\x07""Secoder"
		"\x80\x05""1.2.0"
		"\x80\x05""1.1.2"
		"\x81\x21""Reiner Kartenger\x7b""te GmbH & Co.KG."
	};
	static const uint8_t SECODER3_INFO_1[] = {
		"\x84\x02""de"
		"\x90\x01\x01"
		"\xa0\x13\x40\x03""tan\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""aut\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""sig\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x13\x40\x03""gkp\x80\x05""1.1.2\x83\x05""1.0.0"
		"\xa0\x16\x40\x03""ctn\x80\x05""1.2.1\x83\x05""1.0.0\x84\x01\x33"
		"\x90\x00"
	};

	CJ_RESULT res;
	uint16_t InLenr = *lenr;
	uint8_t ReaderId[20 + 2];
	uint8_t SWImpVers[10 + 2];
	uint8_t ReaderPorp[9 + 2];
	int lenReaderId = 0;
	int lenSWImpVers = 0;
	int lenReaderProp = 0;
	uint8_t* Tag92 = NULL;
	uint8_t* Tag83 = NULL;
	uint8_t* Tag91 = NULL;
	uint8_t inCmd1 = *(cmd + 1);

	memset(ReaderId, 0, sizeof(ReaderId));
	memset(SWImpVers, 0, sizeof(SWImpVers));

	if ((res = base::KTLightCall(sad, dad, cmd, lenc, Lc, data_ptr, Le, response, lenr)) == CJ_SUCCESS)
	{
		if (inCmd1 == 0x70 && m_ReaderInfo.Version >= 0x11)
		{
			if (GetEnviroment("SecoderInfoOverride", 0x00000001) > 0)
			{
				if (GetEnviroment("SecoderInfoOverride_ONE", 0x00000001) > 0)
				{
					if (((Tag91 = GetTag(response, *lenr - 2, 0x91, &lenReaderProp)) != NULL) &&
						((Tag92 = GetTag(response, *lenr - 2, 0x92, &lenReaderId)) != NULL) &&
						((Tag83 = GetTag(response, *lenr - 2, 0x83, &lenSWImpVers)) != NULL) &&
						(lenReaderId <= 20) && (lenSWImpVers <= 10) && (lenReaderProp == 9))
					{
						lenReaderProp += 2;
						memcpy(ReaderPorp, Tag91 - 2, lenReaderProp);

						lenReaderId += 2;
						memcpy(ReaderId, Tag92 - 2, lenReaderId);

						lenSWImpVers += 2;
						memcpy(SWImpVers, Tag83 - 2, lenSWImpVers);

						if (InLenr >= (sizeof(SECODER3_INFO_0) + lenReaderProp + lenReaderId + lenSWImpVers + sizeof(SECODER3_INFO_1)))
						{
							memcpy(response, SECODER3_INFO_0, sizeof(SECODER3_INFO_0) - 1);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1, ReaderPorp, lenReaderProp);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp, ReaderId, lenReaderId);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp + lenReaderId, SWImpVers, lenSWImpVers);
							memcpy(response + sizeof(SECODER3_INFO_0) - 1 + lenReaderProp + lenReaderId + lenSWImpVers, SECODER3_INFO_1, sizeof(SECODER3_INFO_1) - 1);
							*lenr = sizeof(SECODER3_INFO_0) - 1 + (USHORT)lenReaderProp + (USHORT)lenReaderId + (USHORT)lenSWImpVers + sizeof(SECODER3_INFO_1) - 1;
						}
						else
						{
							return CJ_ERR_RBUFFER_TO_SMALL;
						}
					}
				}
			}
		}
	}
	return res;
}
#endif


#include "eca_defines.h"

CJ_RESULT CCYOReader::CtSetMFT(const uint8_t* const pData, uint32_t DataLen, uint32_t* Result)
{
	UNREFERENCED_PARAMETER(pData);
	UNREFERENCED_PARAMETER(DataLen);
	UNREFERENCED_PARAMETER(Result);

	return CJ_ERR_NOT_SUPPORTED;
}

CJ_RESULT CCYOReader::CtGetMFT(cj_MFT_Info* const pData, uint32_t* const pNumElemnts)
{
	UNREFERENCED_PARAMETER(pData);

	*pNumElemnts = 0;

	return CJ_SUCCESS;
}
