Exemplo n.º 1
0
/**
 * @brief  this function emits a REQB command to a PICC device
 * @param  *pDataRead	: Pointer to the response
 * @retval ISO14443B_SUCCESSCODE  : the function is successful.
 * @retval ISO14443B_ERRORCODE_DEFAULT  : an error occured
 */
int8_t ISO14443B_ReqB ( uint8_t *pDataRead )
{
	int8_t	status;
	uc8 ReqB[]					= { 			/* APf */
															ISO14443B_ANTICOLLISION_PREFIX_BYTE   , 
															/* AFI */
															ISO14443B_AFI_ALL_FAMILIES            , 
															/* Parameters */
															ISO14443B_EXTENDED_ATQB_NOT_SUPPORTED |  
															ISO14443B_REQB_ATTEMPT                |
															ISO14443B_SLOT_MARKER_1 
														};

	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x03,ReqB,pDataRead));
	/* Filling of the data structure */
	ISO14443B_Card.IsDetected = true;
	/* complete the ISO 14443 type B strucure */
	ISO14443B_CompleteStruture (pDataRead);
		
	return ISO14443B_SUCCESSCODE;
Error:
	return ISO14443B_ERRORCODE_DEFAULT; 

}
Exemplo n.º 2
0
/**
 * @brief  this functions sends the HLTA command to the PCD device
 * @param  *pDataRead	: Pointer to the PCD response
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_HLTA( uint8_t *pDataRead )
{
	uc8 	 pdata[]= { 0x50, 0x00, 0x28};

	/* send the command to the PCD device*/
	PCD_SendRecv(0x03,pdata,pDataRead);
	
	return ISO14443A_SUCCESSCODE;

}
Exemplo n.º 3
0
/**
 * @brief  this function carries out the second level of the anticollision
 * @param  *pDataRead	: Pointer to the PCD response
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_ACLevel2( uint8_t *pDataRead )
{
	uint8_t *pDataToSend = &(u95HFBuffer[PCD_DATA_OFFSET]),
					Length = 0,
					BccByte ;
	int8_t status;

	/* Perform anti-collision */
	errchk(ISO14443A_AC(pDataRead, SEL_CASCADE_LVL_2));
	//errchk(PCD_SendRecv(0x03,AnnticolParameter,pDataRead));
	
	/* Copies the UID into the data structure */
	if(ISO14443A_Card.UIDsize == ISO14443A_UID_DOUBLE_SIZE)
	{
		memcpy(&ISO14443A_Card.UID[ISO14443A_UID_PART], &pDataRead[PCD_DATA_OFFSET], ISO14443A_UID_SINGLE_SIZE);
	}
	else
	{
		memcpy(&ISO14443A_Card.UID[ISO14443A_UID_PART], &pDataRead[PCD_DATA_OFFSET+1], ISO14443A_UID_PART);
	}
	
	/* copies the BCC byte of the card response*/
	BccByte = pDataRead[PCD_DATA_OFFSET + ISO14443A_UID_SINGLE_SIZE ];
	
	/* Preparing the buffer who contains the SELECT command */
	pDataToSend[Length ++]	= SEL_CASCADE_LVL_2;
	pDataToSend[Length ++] = ISO14443A_NVM_70;
	
	/* Copies the UID into the data structure */
	if(ISO14443A_Card.UIDsize == ISO14443A_UID_DOUBLE_SIZE)
	{
		memcpy(&(pDataToSend[Length]),&(ISO14443A_Card.UID[ISO14443A_UID_PART]) , ISO14443A_UID_SINGLE_SIZE);
		Length += ISO14443A_UID_SINGLE_SIZE ;
	}
	else
	{
		pDataToSend[Length ++] = 0x88;
		memcpy(&(pDataToSend[Length]),&(ISO14443A_Card.UID[ISO14443A_UID_PART]) , ISO14443A_UID_PART);
		Length += ISO14443A_UID_PART ;
	}
	pDataToSend[Length ++] = BccByte;
	/* Add the control byte : Append the CRC + 8 bits in first byte (standard frame)*/
	pDataToSend[Length ++] = PCD_ISO14443A_APPENDCRC | PCD_ISO14443A_A8BITSINFIRSTBYTE;
	
	/* emit the select command */
	errchk(PCD_SendRecv(Length,pDataToSend,pDataRead));
	
	/* Recovering SAK byte */
	ISO14443A_Card.SAK = pDataRead[PCD_DATA_OFFSET];

	return ISO14443A_SUCCESSCODE;
Error:
	return ISO14443A_ERRORCODE_DEFAULT; 
}
Exemplo n.º 4
0
/**
 * @brief  this function checks if a card is still in the field
 * @retval ISO14443B_SUCCESSCODE  : the function is successful.
 * @retval ISO14443B_ERRORCODE_DEFAULT  : an error occured
 */
int8_t ISO14443B_IsCardIntheField ( void )
{
	uint8_t *pDataRead = u95HFBuffer;
	uc8			 Parameter			= 0xB2;
	int8_t	status;
	
	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x01,&Parameter,pDataRead));

	return ISO14443B_SUCCESSCODE;
Error:
	return ISO14443B_ERRORCODE_DEFAULT; 
}
Exemplo n.º 5
0
/**
 * @brief Handles the WAKE_UP command
 * @param *pDataRead	: Pointer to the response
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_PPS( uint8_t *pDataRead )
{
	uc8 	 pdata[]= { 0xD0, 0x11, 0x00, 0x28};
	int8_t status;

	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x04,pdata,pDataRead));

	/* checks the CRC */
	errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443A,pDataRead) );
	
	return ISO14443A_SUCCESSCODE;
Error:
	return ISO14443A_ERRORCODE_DEFAULT; 
}
Exemplo n.º 6
0
/**
 * @brief  this functions sends the REQA command to the PCD device
 * @param  *pDataRead	: Pointer to the PCD response
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_REQA( uint8_t *pDataRead )
{
	uc8 		ReqA[]					= { 0x26, 0x07};
	int8_t	status;


	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x02,ReqA,pDataRead));

	/* retrieves the ATQA response */
	memcpy(ISO14443A_Card.ATQA, &pDataRead[PCD_DATA_OFFSET], ISO14443A_ATQA_SIZE);
	/* completes the strucure according to the ATQA response */
	ISO14443A_CompleteStructure ( ISO14443A_Card.ATQA );
		
	return ISO14443A_SUCCESSCODE;
Error:
	return ISO14443A_ERRORCODE_DEFAULT; 
}
Exemplo n.º 7
0
/**
 * @brief  this functions emits the RATS command to PICC device
 * @param  *pDataRead	: Pointer to the response
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_RATS( uint8_t *pDataRead )
{
	int8_t status;	
	uint8_t FSCI;
	uc8 	 pdata[]= { 0xE0, 0x80, 0x28};

	/* send the command to the PCD device*/
	errchk(PCD_SendRecv(0x03,pdata,pDataRead));
	/* check the status byte of the PCD device */
	errchk(PCD_IsReaderResultCodeOk (SEND_RECEIVE,pDataRead) );
	/* check the CRC */
	errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443A,pDataRead) );

	FSCI = pDataRead[3]&0x0F;
	FSC = FSCIToFSC(FSCI);

	return ISO14443A_SUCCESSCODE;
Error:
	return ISO14443A_ERRORCODE_DEFAULT; 
}
Exemplo n.º 8
0
/**
 * @brief  this function complete the ISO14443B structure according to the AttriB response
 * @param  *pDataRead	: Pointer to the PCD response
 * @retval ISO14443B_SUCCESSCODE  : the function is successful.
 * @retval ISO14443B_ERRORCODE_DEFAULT  : an error occured
 */
int8_t ISO14443B_AttriB( uint8_t *pDataRead )
{
	int8_t	status;
	uint8_t AttriB[ISO14443B_ATQB_SIZE] 			= { 
																				/* Start byte */ 
																				ATTRIB_FIRST_BYTE           ,
																				/* PUPI */ 
																				0x00                        ,  
																				/* PUPI */  
																				0x00                        ,
																				/* PUPI */   
																				0x00                        ,
																				/* PUPI */   
																				0x00                        ,
																				/* Parameter 1 */   
																				TR0_64_FS                   | 
																				TR1_64_FS                   |
																				EOF_REQUIRED                |
																				SOF_REQUIRED                ,
																				/* Parameter 2 */                          
																				MAX_FRAME_SIZE_256_BYTES    |		 
																				PCD_TO_PICC_106K            |
																				PICC_TO_PCD_106K            ,
																				/* Parameter 3 */              
																				TR2_32_FS                   |
																				PICC_COMPLIANT_ISO14443_4   ,
																				/* Parameter 4 */                          
																				CID_0	                     
														};
														
	/* copies the PUPI field */													
	memcpy(&AttriB[1], ISO14443B_Card.PUPI, ISO14443B_MAX_PUPI_SIZE);
	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x09,AttriB,pDataRead));
	/* checks the CRC */
	errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443B,pDataRead) );
		
	return ISO14443B_SUCCESSCODE;
Error:
	return ISO14443B_ERRORCODE_DEFAULT; 
}
Exemplo n.º 9
0
/**
 * @brief  This functions manage the anticollision
 * @param  *pDataRead	: Pointer to the PCD response
 * @param  CascadeLevel	: information on the current cascade level
 * @return ISO14443A_SUCCESSCODE the function is succesful
 * @return ISO14443A_ERRORCODE_DEFAULT : an error occured
 */
static int8_t ISO14443A_AC( uint8_t *pDataRead, u8 CascadeLevel )
{
	u8 AnticolParameter [7] = {0x00, ISO14443A_NVM_20, 0x08,0x00,0x00,0x00,0x00};
	u8 NbResponseByte = 0;
	u8 NbResponseByteOrigin = 0;
	u8 Collision = 0;
	u8 ByteCollisionIndex = 0;
	u8 BitCollisionIndex = 0;

	u8 RemainingBit = 0;
	u8 NewByteCollisionIndex = 0;
	u8 NewBitCollisionIndex = 0;
	u8 UID[4] = {0x00,0x00,0x00,0x00};
	int8_t status;

	/* prepare command regarding cascade level on-going */
	AnticolParameter[0] = CascadeLevel;

	/* sends the command to the PCD device*/
	errchk(PCD_SendRecv(0x03,AnticolParameter,pDataRead));
	
	NbResponseByte = pDataRead[1]; 
	NbResponseByteOrigin = NbResponseByte;
	Collision = (pDataRead[NbResponseByte-1] & 0x80);

	ByteCollisionIndex = pDataRead[NbResponseByte];
	BitCollisionIndex = pDataRead[NbResponseByte+1];
	
	/* case that should not happend, as occurs because we have miss another collision */
	if( BitCollisionIndex == 8)
	{
		return ISO14443A_ERRORCODE_DEFAULT;
	}
			
	/* check for collision (Tag of different UID length at the same time not managed so far) */
	while( Collision == 0x80)
	{		
		/* clear collision detection */
		Collision = 0x00;
		
		/* send the command to the PCD device*/
		AnticolParameter[1] = ISO14443A_NVM_20 + ((ByteCollisionIndex) <<4) + (BitCollisionIndex+1);
		if( ByteCollisionIndex == 0)
		{	
			AnticolParameter[2] = pDataRead[2] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */
			AnticolParameter[3] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */
			UID [0] = AnticolParameter[2];
		}
		else if( ByteCollisionIndex == 1)
		{
			AnticolParameter[2] = pDataRead[2];
			AnticolParameter[3] = pDataRead[3] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */			
			AnticolParameter[4] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */
			UID [0] = AnticolParameter[2];
			UID [1] = AnticolParameter[3];
		}
		else if( ByteCollisionIndex == 2)
		{
			AnticolParameter[2] = pDataRead[2];
			AnticolParameter[3] = pDataRead[3];
			AnticolParameter[4] = pDataRead[4] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */			
			AnticolParameter[5] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */;
			UID [0] = AnticolParameter[2];
			UID [1] = AnticolParameter[3];
			UID [2] = AnticolParameter[4];
		}
		else if( ByteCollisionIndex == 3)
		{
			AnticolParameter[2] = pDataRead[2];
			AnticolParameter[3] = pDataRead[3];
			AnticolParameter[4] = pDataRead[4];
			AnticolParameter[5] = pDataRead[5] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */			
			AnticolParameter[6] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */;
			UID [0] = AnticolParameter[2];
			UID [1] = AnticolParameter[3];
			UID [2] = AnticolParameter[4];
			UID [3] = AnticolParameter[5];
		}
		else
			return ISO14443A_ERRORCODE_DEFAULT;
				
		/* send part of the UID */
		PCD_SendRecv((0x03+ByteCollisionIndex+1),AnticolParameter,pDataRead);
		
		if(pDataRead[0] != 0x80)
				return ISO14443A_ERRORCODE_DEFAULT;
		
		/* check if there is another collision to take into account*/
		NbResponseByte = pDataRead[1]; 
		Collision = (pDataRead[NbResponseByte-1]) & 0x80;
		
		if ( Collision == 0x80)
		{
			NewByteCollisionIndex = pDataRead[NbResponseByte];
			NewBitCollisionIndex = pDataRead[NbResponseByte+1];
		}
					
		/* we can check that non-alignement is the one expected */
		RemainingBit = 8 - (0x0F & (pDataRead[2+(NbResponseByte-2)-1]));
		if( RemainingBit == BitCollisionIndex+1)
		{		
			/* recreate the good UID */
			if( ByteCollisionIndex == 0)
			{
				UID [0] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[2]) | pDataRead[2] ;
				UID [1] = pDataRead[3];
				UID [2] = pDataRead[4];
				UID [3] = pDataRead[5];
			}
			else if( ByteCollisionIndex == 1)
			{
				UID [1] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[3]) | pDataRead[2] ;
				UID [2] = pDataRead[3];
				UID [3] = pDataRead[4];
			}
			else if( ByteCollisionIndex == 2)
			{
				UID [2] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[4]) | pDataRead[2] ;
				UID [3] = pDataRead[3];
			}
			else if( ByteCollisionIndex == 3)
			{
				UID [3] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[5]) | pDataRead[2] ;
			}
			else
				return ISO14443A_ERRORCODE_DEFAULT;
		}				
		else
			return ISO14443A_ERRORCODE_DEFAULT;		
		
			/* prepare the buffer expected by the caller */
			pDataRead[0] = 0x80;
			pDataRead[1] = NbResponseByteOrigin;
			pDataRead[2] = UID [0];
			pDataRead[3] = UID [1];
			pDataRead[4] = UID [2];
			pDataRead[5] = UID [3];	
			pDataRead[6] = UID[0]^UID[1]^UID[2]^UID[3];	
		
		/* if collision was detected restart anticol */
		if ( Collision == 0x80)
		{
			if( ByteCollisionIndex != NewByteCollisionIndex )
			{
				ByteCollisionIndex += NewByteCollisionIndex;
				BitCollisionIndex = NewBitCollisionIndex;	
			}
			else
			{
				ByteCollisionIndex += NewByteCollisionIndex;
				BitCollisionIndex += (NewBitCollisionIndex+1);				
			}
		}
	}
	
	return ISO14443A_SUCCESSCODE;
Error:
	return ISO14443A_ERRORCODE_DEFAULT; 
	
}