📄 paypass_anticollision.c
字号:
// RETURN : l_bStatus : Error code
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned char b_fnSendReceiveREQBWUPB_PayPass(unsigned char p_pcmd,unsigned char* p_pabBuffer,StructReader* p_pStructReader, unsigned short* p_bATQBLength)
{
unsigned char l_abBuffer[3];
unsigned char l_bStatus;
l_abBuffer[0] = _ISOB_REQB; // 0x05
// Application Family Indicator --> all application families
l_abBuffer[1] = _ISOB_AFI_ALL;
// Coding of PARAM Byte included in REQB and WUPB command
// Number of slots (N) = 'OOO' (Requirements 6.3)
// _ISOB_REQB_NO_SLOT (0X00) or _ISOB_WUPB_NO_SLOT (0x08)
l_abBuffer[2] = p_pcmd;
v_fnSendBuffer(_SENDCRC,3,0,&l_abBuffer[0],p_pStructReader);
l_bStatus = b_fnReceiveBuffer(_CHECKCRC,&p_pabBuffer[0],p_pStructReader,p_bATQBLength,&g_bDataBitsReceived,&g_bPicoReadStatus,&g_bRFReceiveEOFB,&g_bBitsToReceive);
return l_bStatus;
}
//-----------------------------------------------------------------------------
// Function name : b_fnSendReceiveRATS_PayPass(unsigned char* p_pabBuffer,StructReader* p_pStructReader)
//-----------------------------------------------------------------------------
// Description : Send the RATS Command and Receive the ATS
//
// IN : p_pStructReader : Pointer to the used StructReader structure.
//
// OUT : p_pabBuffer : data return by the ATS (RATS Response)
//
// RETURN : l_bStatus : Error code
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned char b_fnSendReceiveRATS_PayPass(unsigned char* p_pabBuffer,StructReader* p_pStructReader)
{
unsigned char l_abBuffer[2];
unsigned char l_bStatus;
l_abBuffer[0] = _ISOA_RATS; // 0xE0
// Format of RATS Parameter Byte
// FSDImin ='1000' (Requirements 5.9) and CDI ='0000' (Requirements 5.11)
l_abBuffer[1] = 0x80;
v_fnSendBuffer(_SENDCRC,2,0,&l_abBuffer[0],p_pStructReader);
l_bStatus = b_fnReceiveBuffer(_CHECKCRC,&p_pabBuffer[0],p_pStructReader,&g_lDataBytesReceived,&g_bDataBitsReceived,&g_bPicoReadStatus,&g_bRFReceiveEOFA,&g_bBitsToReceive);
return l_bStatus;
}
//-----------------------------------------------------------------------------
// Function name : v_fnSendPreparATTRIB_PayPass(unsigned char* p_pabBuffer,StructReader* p_pStructReader)
//-----------------------------------------------------------------------------
// Description : Prepare the data to send for an ATRRIB command
//
// IN : p_pStructReader : Pointer to the used StructReader structure.
//
//
// OUT : p_pabBuffer : buffer ready to be sent
//
// RETURN : - none -
//
// Notes : - none -
//-----------------------------------------------------------------------------
void v_fnSendPreparATTRIB_PayPass(unsigned char* p_pabBuffer,StructReader* p_pStructReader)
{
p_pabBuffer[0] = _ISOB_ATTRIB ; // 0x1D
// p_pabBuffer[1]..[4] --> PUPI from ATQA (Requirements 6.15)
// p_pabBuffer[11] = p_pabBuffer[7] ; // Higher layer朓NF (Requirements 6.22)
p_pabBuffer[7] = p_pabBuffer[10] & 0x01; // PARAM 3 (Requirements 6.20)
// p_pabBuffer[9] = p_pabBuffer[5] ; // Higher layer朓NF (Requirements 6.22)
// p_pabBuffer[10] = p_pabBuffer[6] ; // Higher layer朓NF (Requirements 6.22)
// p_pabBuffer[12] = p_pabBuffer[8] ; // Higher layer朓NF (Requirements 6.22)
p_pabBuffer[5] = 0 ; // PARAM 1 (Requirements 6.16)
p_pabBuffer[6] = 0x08 ; // PARAM 2 (Requirements 6.17)
p_pabBuffer[8] = 0 ; // PARAM 4 (Requirements 6.21)
if(p_pStructReader->s_bReaderSupportedSpeed & P0_USE_CHIP_BR) //PARAM 2
{
if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,2))
{
p_pabBuffer[6] |= 0x30; // Emission 847 kbps
}
else if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,1))
{
p_pabBuffer[6] |= 0x20; // Emission 423 kbps
}
else if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,0))
{
p_pabBuffer[6] |= 0x10; // Emission 212 kbps
}
if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,6))
{
p_pabBuffer[6] |= 0xC0; // Reception 847 kbps
}
else if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,5))
{
p_pabBuffer[6] |= 0x80; // Reception 423 kbps
}
else if (bit_testChar(&p_pStructReader->s_bCommunicationSupportedSpeed,4))
{
p_pabBuffer[6] |= 0x40; // Reception 212 kbps
}
}
}
//-----------------------------------------------------------------------------
// Function name : unsigned char b_fnPolling(unsigned char* p_abATQResponse, unsigned short* p_bATQLength, StructReader* p_pStructReader)
//-----------------------------------------------------------------------------
// Description : Pool cards to have just one card (type A or b)
//
// IN : p_pStructReader : Pointer to the used StructReader structure.
//
// OUT : p_abATQResponse : ATQA or ATQB response
// p_bATQBLength : ATQA or ATQB response length
//
// RETURN : END_POLLING_A one card A detected
// END_POLLING_B one card B detected
// RETRY_POLLING no card
// TRANSMISSION_ERROR Collision
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned char b_fnPolling(unsigned char* p_abATQResponse, unsigned short* p_bATQLength, StructReader* p_pStructReader)
{
unsigned char l_bStatus;
unsigned char l_bDelay;
#ifdef MODE_DEBUG
unsigned char i;
#endif
// LOAD ISO 14443-A PROTOCOL
v_fnProtocolChange(ISOA_PROTOCOL,&g_abP6Config14443A_PayPass[0],g_bRFReceiveEOFA,p_pStructReader);
// CLEAR BUFFER
memset(&p_abATQResponse[0],0,20);
/*----------POLLING A----------*/
// SEND WUPA CMD AND RECEIVE ATQA BUFFER
l_bStatus = b_fnSendReceiveREQAWUPA(_ISOA_WUPA,&p_abATQResponse[0],p_pStructReader,p_bATQLength);
// CHECK ERROR
l_bStatus = b_fnPayPassAnticollisionErrorHandling(_ISOA_WUPA, l_bStatus,&p_abATQResponse[0],*p_bATQLength);
// IF NO WUPA RESPONSE (NO CARD A)
if (l_bStatus == ERR_NOCARD)
{
#ifdef MODE_DEBUG
// printf("\nNo Card A\n");
#endif
/*----------POLLING B----------*/
// CHANGE PROTOCOL AND WAIT DURING THE SAME TIME tP = 4,72ms
// delay(500 etu = 4,72 ms = 10 * 419 祍 + t(ProtocolChange) )
for(l_bDelay=10;l_bDelay>0;l_bDelay--)
{
delay_us(419);
}
// LOAD ISO14443-B PROTOCOL
v_fnProtocolChange(ISOB_PROTOCOL,&g_abP6Config14443B_PayPass[0],g_bRFReceiveEOFB,p_pStructReader);
// CLEAR BUFFER
memset(&p_abATQResponse[0],0,20);
// SEND WUPB CMD AND RECEIVE ATQB BUFFER
l_bStatus = b_fnSendReceiveREQBWUPB_PayPass(_ISOB_WUPB_NO_SLOT,&p_abATQResponse[0],p_pStructReader,p_bATQLength);
// CHECK ERROR
l_bStatus = b_fnPayPassAnticollisionErrorHandling(_ISOB_WUPB_NO_SLOT, l_bStatus,&p_abATQResponse[0],*p_bATQLength);
// IF NO WUPB RESPONSE (NO CARD B)--> RETRY THE POLLING WITH THE FIRST WUPA
if (l_bStatus == ERR_NOCARD)
{
// WAIT AND CHANGE PROTOCOL(at the beginning of the "POLLING A") IN THE SAME TIME tP = 4,72ms
// delay(500 etu = 4,72 ms = 10 * 419 祍 + t(ProtocolChange) )
for(l_bDelay=10;l_bDelay>0;l_bDelay--)
{
delay_us(419);
}
#ifdef MODE_DEBUG
printf("No Card B\n");
#endif
return RETRY_POLLING;
}
// RETURN ERROR OF WUPB
if ( l_bStatus != ERR_NO_ERROR )
{
return l_bStatus;
}
#ifdef MODE_DEBUG
printf("Card B present in anticolB\n");
printf("ATQB Received : ");
for(i=0;i<(*p_bATQLength);i++)
{
printf("%02x",p_abATQResponse[i]);
}
printf("\nATQB Length : ");
printf("%02d\n",*p_bATQLength);
#endif
return END_POLLING_B;
}
// RETURN ERROR OF WUPA
if ( l_bStatus != ERR_NO_ERROR)
{
return l_bStatus;
}
#ifdef MODE_DEBUG
printf("\n1 Card A detected\n");
printf("ATQA Received : ");
for(i=0;i<(*p_bATQLength);i++)
{
printf("%02x",p_abATQResponse[i]);
}
printf(" ATQA Length : ");
printf("%02d\n",*p_bATQLength);
#endif
return END_POLLING_A;
}
//-----------------------------------------------------------------------------
// Function name : b_fnCollisionA(unsigned char* l_abBuffer,unsigned char* p_abUID, unsigned char* p_bUIDLength, StructReader* p_pStructReader)
//-----------------------------------------------------------------------------
// Description : Do the type A collision detection and memorize the UID
//
// IN : p_pStructReader : Pointer to the used StructReader structure.
// l_abBuffer : ATQA extract from the WUPA of POLLING
//
// OUT : p_abUID : UID received
// p_bUIDLength : UID size
//
// RETURN : END_COLLISION_A one card A
// PROTOCOL_ERROR
// TIME_OUT_ERROR
// TRANSMISSION_ERROR Collision
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned char b_fnCollisionA(unsigned char* l_abBuffer,unsigned char* p_abUID, unsigned char* p_bUIDLength, StructReader* p_pStructReader)
{
unsigned char l_bStatus;
unsigned char l_bSEL;
unsigned char l_bCurrentSerial;
unsigned char l_bDelay;
unsigned char i;
// RESET INDEX AND UID BUFFER
l_bCurrentSerial = 0;
memset(&p_abUID[0],0,12);
/*----------TYPE A COLLISON DETECTION----------*/
l_bSEL = _ISOA_SELECT ;
do
{
// ANTICOLLISION COMMAND
i = 0;
do // loop(x3) for time-out error
{
i += 1;
// SEND ANTICOLLISION CMD AND RECEIVE UID CLn
l_bStatus = b_fnSendReceiveANTICOLLISION_ISOA(l_bSEL,&l_abBuffer[0],p_pStructReader);
// TRANSMISSION ERROR? FRAME SIZE VERIFICATION
if ((l_bStatus == ERR_NO_ERROR) && (g_lDataBytesReceived != 5))
{
return TRANSMISSION_ERROR;
}
}
while ((i < 3) && (l_bStatus == ERR_NOCARD));
// RETURN ERROR OF ANTICOLLISION
if ((i == 3) && (l_bStatus == ERR_NOCARD))
{
return TIME_OUT_ERROR;
}
// FP COLLISION RETURN 23/08/07
if (l_bStatus == ERR_COLL)
{
return COLLISION_ERROR ;
}
if (l_bStatus != ERR_NO_ERROR)
{
return TRANSMISSION_ERROR;
}
// UID CLn NOT COMPLIANT(Requirements 5.4)
if ( ( ( (g_abATQAResponse[0]& 0xC0) == 0x00) & ((l_bSEL > 0x93)||(l_abBuffer[0]==0x88)))
|| ( ( (g_abATQAResponse[0]& 0xC0) == 0x40) & (((l_bSEL == 0x93)&(l_abBuffer[0]!=0x88)) || (l_bSEL > 0x95)))
|| ( ( (g_abATQAResponse[0]& 0xC0) == 0x80) & (((l_bSEL == 0x93)&(l_abBuffer[0]!=0x88))||((l_bSEL == 0x95)&(l_abBuffer[0]!=0x88))))
|| ( ( (g_abATQAResponse[0]& 0xC0) == 0xC0)))
{
return PROTOCOL_ERROR;
}
// VERIFY IF THE BCC INCLUDING IN THE UID CLn IS CORRECT (Requirements 5.4)
// CALCULATED VALUE
l_abBuffer[6] = l_abBuffer[0] ^ l_abBuffer[1] ^ l_abBuffer[2] ^ l_abBuffer[3];
if (l_abBuffer[4] != l_abBuffer[6])
{
return TRANSMISSION_ERROR;
}
// STORE THE UID
memcpy(&p_abUID[l_bCurrentSerial],&l_abBuffer[0],5);
// BUFFER SHOULD BE INITIALIZED WITH 0x00 FROM 5 UNTIL 14
memset(&l_abBuffer[5],0,10);
// COPY THE UID WITHOUT THE BCC IN THE BUFFER TO SEND
memcpy(&l_abBuffer[2],&p_abUID[l_bCurrentSerial],4);
// SELECT COMMAND
i = 0;
do //loop(x3) for time-out error
{
i += 1;
// SEND SELECT COMMAND AND RECEIVE SAK
l_bStatus = b_fnSendReceiveSELECT_ISOA(l_bSEL,&l_abBuffer[0],p_pStructReader);
// CHECK ERROR
l_bStatus = b_fnPayPassAnticollisionErrorHandling(_ISOA_SELECT, l_bStatus,&l_abBuffer[0],g_lDataBytesReceived);
}
while ((i < 3) && (l_bStatus == ERR_NOCARD));
// RETURN ERROR
if ((i = 3) && (l_bStatus == ERR_NOCARD))
{
return TIME_OUT_ERROR;
}
// FP COLLISION RETURN 23/08/07
if (l_bStatus == ERR_COLL)
{
return COLLISION_ERROR ;
}
if (l_bStatus != ERR_NO_ERROR)
{
return TRANSMISSION_ERROR;
}
// IF = CT --> DOUBLE OR TRIPLE UID
if (p_abUID[l_bCurrentSerial] == 0x88)
{
// NEXT STAGE SELECTION 93->95->97
l_bSEL += 2;
// SHIFT POSITION FOR THE NEXT 5 BYTES SERIAL NUMBER STAGE
l_bCurrentSerial += 5;
}
else
{
// FOR THE REAL SIZE OF UID
l_bCurrentSerial += 5;
break;
}
// VERIFY THE LAST SELECT RESPONSE:
// CASCADE BIT : IF BIT3=0 --> VALID SAK --> COMPLETE UID
//if ( bit_testChar(&l_abBuffer[0],2) == 0 )
if ((l_abBuffer[0] & 0x04) == 0)
{
return PROTOCOL_ERROR;
}
}
while (l_bSEL<0x98);
// VERIFY THE LAST SELECT RESPONSE:
// CASCADE BIT : IF BIT3=0 --> VALID SAK --> COMPLETE UID
if ((l_abBuffer[0] & 0x04) == 0x04 )
{
return PROTOCOL_ERROR;
}
// UID LENGTH
*p_bUIDLength=l_bCurrentSerial;
/*----------COLLISION DETECTION A----------*/
// SEND HALT A COMMAND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -