📄 paypass_tcl.c
字号:
unsigned char l_bRFReceiveEOF;
// Initialize retry count to TCL_RETRY_COUNT
l_iRetryCount = TCL_RETRY_COUNT;
l_iRetryCount2 = TCL_RETRY_COUNT;
//INITIALIZE STEP
l_eTransmitStep = CST_tcltsDESELECT;
l_iTCLFrameInLength = 0;
l_iTCLFrameOutLength = 0;
//LOOP UNTIL EXCHANGE DONE
while ( l_eTransmitStep != CST_tcltsEnd )
{
// CASE STEP
switch (l_eTransmitStep)
{
case CST_tcltsDESELECT:
//BUILD S(DESELECT) TCL FRAME
v_fnTCLFrameBuild(CST_pcbtDESELECT, NULL, NULL, 0, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
//RECEIVE THE SAME LENGTH AS INPUT S(DESELECT)
l_iTCLFrameOutLength = l_iTCLFrameInLength;
break;
case CST_tcltsRNACK:
//BUILD RNACK TCL FRAME
v_fnTCLFrameBuild(CST_pcbtRNACK, NULL, NULL, 0, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
//UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
break;
case CST_tcltsSWTX:
//BUILD RNACK TCL FRAME
v_fnTCLFrameBuild(CST_pcbtSWTX, NULL, l_abDataIn, 1, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
//UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
break;
}
//PROTOCOL CHOICE
if(g_TCLCard.f_eCardType == CST_tclctISO_14443_A_4)
{
l_bRFReceiveEOF = g_bRFReceiveEOFA;
}
else
{
l_bRFReceiveEOF = g_bRFReceiveEOFB;
}
// INITIALIZE THE TIME OUT + PICOREAD OFFSET
p_pStructReader->s_bRTimeoutUsed = _FWT_DEACTIVATION;
if (p_pStructReader->s_bRProtocol == ISOA_PROTOCOL)
{
p_pStructReader->s_bRTimeoutUsed +=_PICOREAD_TIMEOUT_OFFSET_A;
}
if (p_pStructReader->s_bRProtocol == ISOB_PROTOCOL)
{
p_pStructReader->s_bRTimeoutUsed +=_PICOREAD_TIMEOUT_OFFSET_B;
}
// Execute TRANSMIT command
if (l_iTCLFrameOutLength != -1)
{
v_fnSendBuffer(_SENDCRC,l_iTCLFrameInLength,0,&l_abTCLFrame[0],p_pStructReader);
l_wStatus = b_fnReceiveBuffer(_CHECKCRC,&l_abTCLFrame[0],p_pStructReader,&l_iTCLFrameOutLength,&g_bDataBitsReceived,&g_bPicoReadStatus,&l_bRFReceiveEOF,&g_bBitsToReceive);
}
else
{
//THE MAXIMUM FRAME LENGHT IS PCB(1) + WTX(1) + CRC(2) = 4
l_iTCLFrameOutLength = 4;
v_fnSendBuffer(_SENDCRC,l_iTCLFrameInLength,0,&l_abTCLFrame[0],p_pStructReader);
l_wStatus = b_fnReceiveBuffer(_CHECKCRC,&l_abTCLFrame[0],p_pStructReader,&l_iTCLFrameOutLength,&g_bDataBitsReceived,&g_bPicoReadStatus,&l_bRFReceiveEOF,&g_bBitsToReceive);
}
//printf("\nERROR DESELECT : %d",l_wStatus);
// IF FRAME > FSD=256 bytes --> PROTOCOL ERROR (Requirements 10.1)
if (l_iTCLFrameOutLength > 256)
{
return PROTOCOL_ERROR;
}
// Test TA 416.2 & 416.3 & 416.5 (TB)
if ( ( l_eTransmitStep == CST_tcltsDESELECT )
&& ( l_abTCLFrame[0] != 0xC2 ) )
{
return PROTOCOL_ERROR;
}
//CHECK IF DATA RECEIVED
if (l_wStatus == ERR_NO_ERROR)
{
l_ePCBType = b_fnTCLFrameExtract(&l_iTCLFrameOutLength, &l_abTCLFrame[0], l_abDataOut, &l_wStatus);
// IF PROTOCOL ERROR IN DATA RECEIVED(Requirements 10.2)
if (l_ePCBType == CST_pcbPROTOCOL_ERROR)
{
return PROTOCOL_ERROR;
}
if (l_ePCBType == CST_pcbtError)
{
// DECREMENT RETRY COUNT
l_iRetryCount--;
}
}
else
{
// TIMEOUT ERROR
if (l_wStatus == ERR_NOCARD)
{
l_ePCBType = CST_pcbtError;
// DECREMENT RETRY COUNT
l_iRetryCount2--;
}
// TRANSMISSION ERROR
else
{
l_ePCBType = CST_pcbtError;
// DECREMENT RETRY COUNT
l_iRetryCount--;
}
}
// CASE PCB TYPE
switch (l_ePCBType)
{
case CST_pcbtDESELECT:
#ifdef MODE_DEBUG_TCL
printf("Deselect\n");
#endif
// CARD DESELECTED
l_eTransmitStep = CST_tcltsEnd;
// SET RESULT
return TRUE;
break;
case CST_pcbtRNACK:
// R(NAK) RECEIVED CONSIDERED AS PROTOCOL ERROR (Requirements 10.9)
return PROTOCOL_ERROR;
break;
case CST_pcbtSWTX:
// GET SWTX
l_bWTX = l_abDataOut[0];
// SET WTX VALUE (THE 2 UPPER BITS SHOULD BE RESET TO ZERO)
l_abDataIn[0] = l_bWTX & 0x3F ;
// PROTOCOL ERROR IF WTXM = 0 (Requirements 10.4)
if ( l_abDataIn[0] == 0 )
{
return PROTOCOL_ERROR;
}
// IF WTXM > 59 (60 to 63) --> WTXM = 59 =(0x3B) (Requirements 10.4)
if ( l_abDataIn[0] > 0x3B )
{
l_abDataIn[0] = 0x3B;
}
// TRANSMIT SWTX
l_eTransmitStep = CST_tcltsSWTX;
break;
case CST_pcbtError:
// CHECK IF RETRY COUNT ELLAPSED
if (l_iRetryCount == 0)
{
return TRANSMISSION_ERROR;
}
if (l_iRetryCount2 == 0)
{
return TIME_OUT_ERROR;
}
else
{
l_eTransmitStep = CST_tcltsDESELECT;
}
break;
}
}
// Default path: return error
return FALSE;
}
//-----------------------------------------------------------------------------
// Function name : b_fnCardTransmit_PayPass
//-----------------------------------------------------------------------------
// Description : This function sends an APDU using the ISO-14443-4 T=CL protocol.
//
// IN : p_pStructReader Pointer to the used StructReader structure
// p_iDataInLength Size of data sent to the card
// p_pabCommand T=CL Command (Class,Instruction,Param1,Param2,Param3 = Lc)
// p_pabDataIn T=CL command's Data In (C-APDU)
//
// OUT : p_piDataOutLength Size of data returned by the chip
// p_pabDataOut Card's response (R-APDU)
//
// RETURN : Status word
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned short b_fnCardTransmit_PayPass( unsigned short *p_piDataOutLength, //Length of data received
unsigned short p_iDataInLength, //Length of data to send
unsigned char *p_pabCommand,
unsigned char *p_pabDataIn,
unsigned char *p_pabDataOut,
StructReader *p_pStructReader)
{
unsigned char l_abTCLFrame[300];
unsigned short l_iTCLFrameInLength;
unsigned short l_iTCLFrameOutLength;
unsigned short l_iDataInLength;
unsigned short l_wStatus;
unsigned short l_iLength;
unsigned char l_ePCBType;
unsigned char l_ePCBTypeInitial;
unsigned char l_eTransmitStep;
unsigned char l_eTransmitStepToResend;
unsigned char l_bWTX;
unsigned short l_iRetryCount;
unsigned short l_iRetryCount2;
unsigned short l_iDataInPrologueEpilogue;
unsigned char l_aiDataInListLength[300]; // Table of all segment length of data to send
unsigned short l_iDataInBlockCount;
unsigned short l_iIndexDataIn;
unsigned short l_iCurrentOutIndex;
unsigned short l_iDataInIndex; // Current number of the packet to send
unsigned short l_iDataCursor;
unsigned char l_bRFReceiveEOF;
unsigned char l_ErrorType;
unsigned char l_AddARetry=1; // According to TA401.11
unsigned char i;
i=0;
// INITIALIZE STEP
l_eTransmitStep = CST_tcltsCommand; // First step is to send a command
// INITIALIZE RETRY COUNT TO TCL_RETRY_COUNT
l_iRetryCount = TCL_RETRY_COUNT; /* FP DEBUG TA401.14 (+1) */
l_iRetryCount2 = TCL_RETRY_COUNT;
// CREATE DATA IN LIST
l_iDataInIndex = 0; //Packet to send = number 0
// GET STRING
l_iDataCursor = 0;
l_iDataInBlockCount = 0; // number of packet to send
l_iCurrentOutIndex = 0; // number of packet received
/*------------------------------------------------------------------------------------------------*/
/*--------------------------PACKETS LENGTH STORAGE------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
while (l_iDataCursor < p_iDataInLength)
{
// GET PROLOGUE EPILOGUE SIZE PCB(1) = 1 byte
l_iDataInPrologueEpilogue = 1;
// ADD COMMAND SIZE (5) IF FIRST PASS
if (l_iDataInBlockCount == 0)
{
l_iDataInPrologueEpilogue += 5;
}
// GET SIZE OF THE CURRENT PACKET
// IF (DATA LEN - CURSOR)+ (PCB+COMMAND)> PICC FSD
if ((p_iDataInLength - l_iDataCursor + l_iDataInPrologueEpilogue +2) > g_TCLCard.f_iPICCMaximumInputFrameSize)
{
//LEN = PICC MAX- (PCB+COMMAND)- 2 BYTE OF CRC
l_iLength = g_TCLCard.f_iPICCMaximumInputFrameSize - l_iDataInPrologueEpilogue-2;
// MOVE CURSOR : CURSOR = CURSOR + LEN
l_iDataCursor += l_iLength;
}
else
{
//LEN = DATA LEN- CURSOR
l_iLength = p_iDataInLength - l_iDataCursor;
// MOVE CURSOR AT THE LAST DATA
l_iDataCursor = p_iDataInLength;
}
// ADD LENGTH TO LIST
l_aiDataInListLength[l_iDataInBlockCount] = l_iLength;
l_iDataInBlockCount++;
}
/*------------------------------------------------------------------------------------------------*/
// IF LC = 0 (NO DATA)
if (p_iDataInLength == 0)
{
//SET PROLOGUEEPILOGUE SIZE TO 6
l_iDataInPrologueEpilogue = 6;
//SET DATA IN LEN = 0
l_aiDataInListLength[0] = 0;
}
l_iIndexDataIn = 0;
/*------------------------------------------------------------------------------------------------*/
/*------------------UNIT FRAME BUILD--------SENDING-----------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
// LOOP UNTIL EXCHANGE DONE
while (l_eTransmitStep != CST_tcltsEnd)
{
/* BUILD FRAME */
// CASE STEP
switch (l_eTransmitStep)
{
case CST_tcltsCommand:
// SIZE OF FIRST DATA
l_iDataInLength = l_aiDataInListLength[0];
// SET CHAINING IF MORE THAN ONE DATA IN LIST
if (l_iDataInBlockCount > 1)
{
l_ePCBType = CST_pcbtIWithChaining;
}
// ONLY ONE DATA IN LIST
else
{
l_ePCBType = CST_pcbtINoChaining;
}
// BUILD I TCL FRAME
l_iTCLFrameInLength = 0;
l_iTCLFrameOutLength = 0;
v_fnTCLFrameBuild(l_ePCBType, p_pabCommand, &p_pabDataIn[0], l_iDataInLength, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
// IN CASE OF RESENDING (TIMEOUT)
l_eTransmitStepToResend = CST_tcltsCommand;
// FOR Test TA 408.4 and Test TA 408.5
l_ePCBTypeInitial = l_ePCBType;
break;
case CST_tcltsChaining:
// LENGTH OF DATA TO SEND
l_iDataInLength = l_aiDataInListLength[l_iDataInIndex];
// SET CHAINING BIT IF STRING LEFT IN LIST
if (l_iDataInIndex < (l_iDataInBlockCount - 1))
{
l_ePCBType = CST_pcbtIWithChaining;
}
else
{
l_ePCBType = CST_pcbtINoChaining;
}
// BUILD I TCL FRAME
v_fnTCLFrameBuild(l_ePCBType, NULL, &p_pabDataIn[l_iIndexDataIn], l_iDataInLength, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
// UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
// IN CASE OF RESENDING (TIMEOUT)
l_eTransmitStepToResend = CST_tcltsChaining;
// FOR Test TA 408.4 and Test TA 408.5
l_ePCBTypeInitial = l_ePCBType;
break;
case CST_tcltsRACK:
// BUILD RACK TCL FRAME
v_fnTCLFrameBuild(CST_pcbtRACK, NULL, NULL, 0, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
// UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
break;
case CST_tcltsRNACK:
// BUILD RNACK TCL FRAME
v_fnTCLFrameBuild(CST_pcbtRNACK, NULL, NULL, 0, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
// UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
break;
case CST_tcltsSWTX:
// BUILD SWTX TCL FRAME
v_fnTCLFrameBuild(CST_pcbtSWTX, NULL, p_pabDataIn, 1, l_abTCLFrame, &l_iTCLFrameInLength, &l_iTCLFrameOutLength);
// FP DEBUG
// IN CASE OF RESENDING (TIMEOUT)
l_eTransmitStepToResend = CST_tcltsSWTX;
// UNKNOWN FRAME OUT LENGTH
l_iTCLFrameOutLength = -1;
//break; ////////////////DEBUG 240707
}
/* SET PARAMETERS ACCORDING TO THE PROTOCOL -- REVEIVE EOF -- TIMEOUT -- BEFORE SEND */
//PROTOCOL CHOICE
if(g_TCLCard.f_eCardType == CST_tclctISO_14443_A_4)
{
l_bRFReceiveEOF = g_bRFReceiveEOFA;
}
else
{
l_bRFReceiveEOF = g_bRFReceiveEOFB;
}
// INITIALIZE THE TIME OUT
if(l_eTransmitStep == CST_tcltsSWTX)
{
// TIME OUT IF WAITING TIME EXTENSION IS NEEDED(FWTtemp = FWT * WTXM)
g_TCLCard.f_dPICCMaximumFrameWaitingTime = g_FWT_SFGT * l_bWTX ;
}
else
{
g_TCLCard.f_dPICCMaximumFrameWaitingTime = g_FWT_SFGT ;
}
p_pStructReader->s_bRTimeoutUsed = g_TCLCard.f_dPICCMaximumFrameWaitingTime;
if (p_pStructReader->s_bRProtocol == ISOA_PROTOCOL)
{
p_pStructReader->s_bRTimeoutUsed += _PICOREAD_TIMEOUT_OFFSET_A;
}
if (p_pStructReader->s_bRProtocol == ISOB_PROTOCOL)
{
p_pStructReader->s_bRTimeoutUsed += _PICOREAD_TIMEOUT_OFFSET_B;
}
g_bPayPassTimeoutValue = p_pStructReader->s_bRTimeoutUsed;
/*------------------------------------------------------------------------------------------------*/
#ifdef TTAL1
// Option for Host mode
if (g_sLog.enable)
{
// CONCATENATION BUFFER
sprintf(g_sLog.buffer,"C-APDU: ");
for (i=0;i<l_iTCLFrameInLength;i++)
{
sprintf(g_sLog.buffer + strlen(g_sLog.buffer),"%02x",l_abTCLFrame[i]);
}
sprintf(g_sLog.buffer + strlen(g_sLog.buffer),"\n");
v_fnSendToHostEcho(g_sLog.buffer);
}
#endif
/*------------------------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -