⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paypass_anticollision.c

📁 读RF卡的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
// 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 + -