Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
New Contributor
Posts: 2
Registered: ‎09-25-2013
My Device: Z10
My Carrier: Telus

NFC Card Emulation

Hi,

We are developing an NFC Emulation 14443A app for building access. However, we are having issues where sometimes we don't receive an NFC_ISO14443_4_COMMAND_EVENT in our loop.

 

Device: BB-Z10 (STL100-3)
OS: 10.1.0.4181

 

We put a Micropross inbetween the phone and the reader to intercept the 14443 packets and noticed that it always connects, however when we select the default application (00 a4 04 00 00 00 00) we receive from the BB10 a WTX (Wait Time Extension) for 1 unit. The Reader queries the card again after waiting 1 unit and again receives a WTX for 1 unit. This goes on forever.

 

However, sometimes this works without any issue whatsoever. The only difference is that we still receive the WTX/STX but eventually, the BB10 returns with a "90 00" - success.

 

In my app, we are not receiving the COMMAND_EVENT in the first case. Perhaps this is a timing issue on our end?

 

Any suggestions would be hugely appreciated.

 

Best Regards,
John

 

My EventHandler runs for the duration of the app (in event(), I'm not sessing the COMMAND_EVENT):

NFCEventHandler()
{
    bps_initialize();
    nfc_request_events();
}

void NFCEventHandler::event(bps_event_t *event)
{
	qDebug() << "NFCEventHandler::event";

	NFCWorker* _instance = NFCWorker::getInstance();

	if (event && bps_event_get_domain(event) == nfc_get_domain()) {
		uint16_t code = bps_event_get_code(event);
		nfc_event_t *nfcEvent;
		nfc_target_t* target;

		qDebug() << "XXXX NFCEventHandler::event - processing event code: " << code;

		if (NFC_ISO14443_4_EVENT_CODE_EVENT == code) {
			qDebug() << "XXXX Echo emulation: selected by reader";
		} else if (NFC_ISO14443_4_COMMAND_EVENT == code) {
			qDebug() << "XXXX Echo emulation: command received";
			nfc_get_nfc_event(event, &nfcEvent);
			nfc_get_target(nfcEvent, &target);

			_instance->cardApp->process( target );
		}
	}
}

On touch, my app calls NFCWorker::connect() and waits for APDUs (process):

void NFCWorker::connect()
{
	/* Unique identifier as defined by ISO 14443-3 Type A specification.
	 * @c identifier can be either:
	 *  - @c NULL so that an internal unique identifier is created by the NFC
	 *    driver upon calling @c nfc_start_iso14443_4_emulation().
	 *  - a 4-byte array in which the first byte is within the range 0xH0-0xH7
	 *    or 0xH9-0xHE, where 'H' can be any hex value.
	 */
	char validId[] = { 0x91, 0x01, 0x02, 0x03 };
	char* identifier = validId;

	/**
	 * Size of @c identifier (in bytes). This is currently not used and must be
	 * set to 0 by the application.
	 */
	size_t identifier_size = 4;

	/**
	 * Historical bytes as defined by ISO 14443-4 Type A specification.
	 */
	char dataStr[] = "Testing_data";
	char* applicationData = dataStr;

	/**
	 * Size of @c applicationData (in bytes)
	 */
	size_t applicationData_size = 13;

	nfc_iso14443_4_card_t card_type_A;
	card_type_A.type = ISO14443_4TYPE_A;
	card_type_A.info.A.identifier = identifier;
	card_type_A.info.A.identifier_size = identifier_size;
	card_type_A.info.A.applicationData = applicationData;
	card_type_A.info.A.applicationData_size = applicationData_size;
/*

	char attribData[] = "1";
	char* aData = attribData;

	nfc_iso14443_4_card_t card_type_A;
	card_type_A.type = ISO14443_4TYPE_B;
	card_type_A.info.B.afi = 0x00;
	card_type_A.info.B.higherLayerResponse = attribData;
	card_type_A.info.B.higherLayerResponse_size = 1;
	card_type_A.info.B.identifier = identifier;
	card_type_A.info.B.identifier_size = identifier_size;
	card_type_A.info.B.numOfApps = 1;
*
*
*
*/
	const nfc_iso14443_4_card_t* p_card_type_A = &card_type_A;
	int rc = nfc_start_iso14443_4_emulation(p_card_type_A);
	if (rc != NFC_RESULT_SUCCESS)
	{
		qDebug() << QString( "nfc_start_iso14443_4_emulation FAILED: %1" ).arg( rc );
		stop();
	}
}


void NFCWorker::process( nfc_target_t *target )
{
	unsigned char command[NFC_ISO14443_4_COMMAND_BUFFER_LENGTH];
	size_t command_length = 0;
	nfc_result_t result;
	int i;

	if (!target) {
		qDebug() << "processIso144434CommandEvent has null target!";
		return;
	}

	memset(command, 0, NFC_ISO14443_4_COMMAND_BUFFER_LENGTH);

	qDebug() << "Received Iso14443-4 Command message";
	result = nfc_get_iso14443_4_emulation_command(target, command, NFC_ISO14443_4_COMMAND_BUFFER_LENGTH, &command_length);

	if (result != NFC_RESULT_SUCCESS) {
		qDebug() << QString("nfc_get_iso14443_4_emulation_command failed: %d").arg(result);
		return;
	}

	qDebug() << "XXXX command_length=" << command_length;
	QByteArray commandData = QByteArray::fromRawData(reinterpret_cast<const char *>(command), command_length);
	QString commandAsHex = QString::fromAscii(commandData.toHex());
	qDebug() << "XXXX command=" << commandAsHex;

	if( command[1] == 0xa4 )
	{
		result = nfc_send_iso14443_4_emulation_command_response(RESPONSE_OK, 2);
		if (result != NFC_RESULT_SUCCESS) {
			qDebug() << QString("nfc_send_iso14443_4_emulation_command_response response: %d").arg(result);
		}
		return;
	}
	else if( command[1] == 0xCB && command[4] == 0x05 )
	{
		//00 cb 3f ff 05 5C 03 5F C1 02
		if( Utilities::isSameCharArray( &command[7], CHUID_ID, 3) )
		{
			size_t response_length = 255 + 2;
			unsigned char response[response_length];

			for( i=0; i < 255; i++)
				response[i] = CHUID_DATA[i];

			response[255] = 0x61;
			response[256] = 0xFF;

			QByteArray returnData = QByteArray::fromRawData(reinterpret_cast<const char *>(response), response_length);
			QString returnDataAsHex = QString::fromAscii(returnData.toHex());

			result = nfc_send_iso14443_4_emulation_command_response(response, response_length);
			if (result != NFC_RESULT_SUCCESS) {
				qDebug() << QString("nfc_send_iso14443_4_emulation_command_response response: %d").arg(result);
			}

			qDebug() << "XXXX response=" << returnDataAsHex;

			_currentOffset = 255;
			return;
		}
		else
		{
			result = nfc_send_iso14443_4_emulation_command_response(NO_INS, 2);

			if (result != NFC_RESULT_SUCCESS) {
				qDebug() << QString("nfc_send_iso14443_4_emulation_command_response response: %d").arg(result);
			}

		}
	}
	else if( command[1] == 0xC0 )
	{
		int dataLen = (command[4] & 0x00FF );

		size_t response_length = dataLen + 2;
		unsigned char response[response_length];

		for( i=0; i < dataLen; i++)
			response[i] = CHUID_DATA[ _currentOffset + i];

		if( CHUID_LEN - _currentOffset - dataLen >= 255 )
		{
			response[response_length -2] = 0x61;
			response[response_length -1] = 0xFF;
		}
		else if( CHUID_LEN - _currentOffset - dataLen  <= 0 )
		{
			response[response_length-2] = 0x90;
			response[response_length-1] = 0x00;
		}
		else
		{
			response[response_length -2] = 0x61;
			response[response_length -1] = ( (CHUID_LEN - _currentOffset - dataLen ) & 0xFF );
		}

		QByteArray returnData = QByteArray::fromRawData(reinterpret_cast<const char *>(response), response_length);
		QString returnDataAsHex = QString::fromAscii(returnData.toHex());

		result = nfc_send_iso14443_4_emulation_command_response(response, response_length);
		if (result != NFC_RESULT_SUCCESS) {
			qDebug() << QString("nfc_send_iso14443_4_emulation_command_response response: %d").arg(result);
		}

		qDebug() << "XXXX response=" << returnDataAsHex;

		_currentOffset += dataLen;
		return;
	}
	else
	{
		result = nfc_send_iso14443_4_emulation_command_response(NO_INS, 2);

		if (result != NFC_RESULT_SUCCESS) {
			qDebug() << QString("nfc_send_iso14443_4_emulation_command_response response: %d").arg(result);
		}

		_currentOffset = 0;

		return;
	}
}

 

New Contributor
Posts: 2
Registered: ‎09-25-2013
My Device: Z10
My Carrier: Telus

Re: NFC Card Emulation

Should have mentioned my SDK: 

Version: 10.2.1

Build id: v201308081807

Retired
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: NFC Card Emulation

Have asked the dev team to comment on this...

--
Rob is no longer associated with BlackBerry.
Highlighted
Retired
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: NFC Card Emulation

The dev team would like to see your air trace, and the device logs... I'll email you shortly.

--
Rob is no longer associated with BlackBerry.