NFC on BlackBerry 10 - Virtual Tag Emulation

by Retired on ‎08-16-2012 12:33 PM (7,353 Views)



This article is part of a series intended to help developers wishing to exploit NFC in their BlackBerry® 10 applications. Readers of this article should have some pre-existing knowledge of the fundamental architecture of NFC systems and be familiar with C++. You are expected to have read at least the “NFC Primer for Developers” article from the BlackBerry 7® series of articles since this covers concepts which are as applicable to BlackBerry 10 as they are to BlackBerry 7. The BlackBerry 10 article on reading and writing tags may also provide useful background to this article.

This article will explain how to use the BlackBerry 10 C++ native API to develop software which can turn your BlackBerry 10 device into an emulated NFC tag which can be read by other devices.


The Authors


This article was co-authored by Martin Woolley and John Murray both of whom work in the RIM Developer Relations team. Both Martin and John specialise in NFC applications development (amongst other things).


About Virtual Tag Emulation


In our BlackBerry 10 article on “Reading and Writing Tags using native APIs”, we answered the question “what is a tag?” and presented a photograph of a few examples, repeated here in Figure 1.



Figure 1 - Physical Tags


In this article, we’re going to explore “virtual tag emulation”. What does this mean? In short, it’s possible to have our BlackBerry device emulate an NFC tag in software such that another device, encountering our device running our emulation software, will believe to it be a tag like any other and be able to read its contents in exactly the same way as it would read the content of a physical tag. The act of emulating an NFC tag this way is called “Virtual Tag Emulation” and the BlackBerry 10 APIs make it easy for us to do this.


NFC Tool V3 - The Sample Application



Figure 2 - NFC Tool's home screen


In our article on reading and writing tags from a BlackBerry 10 application, we introduced the sample application “NFC Tool”. We updated the application to V2.1, adding a SNEP function to accompany our article on SNEP. To accompany this article, we’ve created V3 of NFC Tool and added a new option to the menu, “Emulate Tag” which you can see in Figure 1 above.


In the sections that follow, we’ll examine code fragments from this new aspect of NFC Tool to illustrate exactly how to proceed in your own code. We won’t be revisiting the overall design of NFC Tool or how we’ve used Cascades and the Qt framework since we’ve covered these issues in the initial article on tag reading and writing. We’ll just focus on the new aspects of NFC Tool version 3 and the specifics relating to virtual tag emulation.

We’ve released version 3 of NFC Tool in full in our GitHub repository, details of which can be found at the end of this article.


NFC Tool V3 – UI Design


Figure 3 gives an overview of the basic flow between pages involved in the “Emulate Tag” function.



Figure 3 - NFC Tool V3 – Virtual Card Emulation: user interface overview



The basic UI design is simple. The home screen provides a list of menu items which you can select by touching. When the “Emulate Tag” option is selected, we display a selection screen which can be used to choose the values of the URI and Text fields that should be present in the virtual Smart Poster tag. On selecting “Emulate” a live event log viewer page is displayed where details of the emulation process are shown for informative purposes. The user should bring another NFC device which is running a tag reader application into proximity with their BlackBerry 10 device at this point and the emulated tag will be read. The Smart Tags application on a BlackBerry 7 device would be a suitable choice for example.


Implementation Details


In this section we’ll review the changes that were made to NFC Tool to incorporate the virtual tag emulation capability. We won’t dwell on user interface issues but will focus immediately on those changes made to incorporate the new NFC operation.


The NfcManager class provides a simple, facade-like interface which other classes can use to initiate the various NFC operations. We added a new function “startTagEmulation” to NfcManager and this is shown in Figure 4 below.


void NfcManager::startTagEmulation(QString *uri, QString *text) {
	qDebug() << "XXXX NfcManager::startTagEmulation";

	_ndefSpUri  = uri;
	_ndefSpText = text;

	_workerInstance = NfcWorker::getInstance();

	QObject::connect(this, SIGNAL(start_tag_emulation(QVariant,QVariant)),
              _workerInstance, SLOT(emulateTag(QVariant,QVariant)),

	emit start_tag_emulation(QVariant::fromValue(*uri),
	qDebug() << "XXXX NfcManager::startTagEmulation done";

void NfcManager::stopTagEmulation() {
	qDebug() << "XXXX NfcManager::stopTagEmulation";

	_workerInstance = NfcWorker::getInstance();

	QObject::connect(this, SIGNAL(stop_tag_emulation()),
              _workerInstance, SLOT(stopEmulatingTag()),

	emit stop_tag_emulation();
	qDebug() << "XXXX NfcManager::stopTagEmulation done";

 Figure 3 – NfcManager’s startTagEmulation() and stopTagEmulation() functions



It’s important to run NFC operations in a background thread since some of the function calls are blocking calls. As such, we use QtConcurrent to run code implemented in our NfcWorker class in a separate long running thread that’s started when the application itself is started.


Ultimately, the NfcManager::startTagEmulation() function just initiates the execution of the NfcWorker::emulateTag function in a background thread, whilst NfcManager::stopTagEmulation() function just initiates execution of the NfcWorker::stopEmulatingTag() function .


Let’s examine the code in NfcWorker next.


void NfcWorker::emulateTag(const QVariant &uri, const QVariant &text) {
	qDebug() << "XXXX NfcWorker::emulateTag() starts...";
	prepareToEmulateTag(uri, text);
	qDebug() << "XXXX NfcWorker::emulateTag() ends...";

void NfcWorker::stopEmulatingTag() {
	qDebug() << "XXXX NfcWorker::stopEmulatingTag() starts...";
	qDebug() << "XXXX NfcWorker::stopEmulatingTag() ends...";

 Figure 4 – NfcWorker::emulateTag() and NfcWorker::stopEmulatingTag()



The steps followed in NfcWorker::emulateTag() follow exactly the same pattern as our other NFC functions supported by NFC Tool. BlackBerry Platform services is already running and listening for events in a loop in the listen() function. So, in our call to prepareToEmulateTag(), which we’ll examine shortly, we start logging to the event log screen and set things up for emulation of the virtual tag. We continue doing this until we’re asked to stop emulating. The trigger to stop emulating will have come from the user navigating away from the event log displaying the virtual tag processing events and will be actioned in the prepareToStopEmulation() function.
Figure 5 shows the prepareToEmulateTag() function and Figure 6 shows the prepareToStopEmulation()  function.


void NfcWorker::prepareToEmulateTag(const QVariant &the_uri,
                                    const QVariant &the_text) {
	if (_failedToInitialize) {

	QString uri = the_uri.toString();
	QString text = the_text.toString();

	qDebug() << "XXXX NfcWorker::prepareToEmulateTag entered ...";

	qDebug() << "XXXX setting inTagEmulationState=true";
	StateManager* state_mgr = StateManager::getInstance();

	emit message(QString("Preparing to emulate NDEF tag"));

	_taskToPerform = EMULATE_TAG;

	nfc_ndef_record_t* spNdefRecord;

	_ndefSpUri = uri;
	_ndefSpText = text;

	spNdefRecord = makeSpRecord();

	if (_emulateNdefMessage) {
		CHECK(nfc_delete_ndef_message(_emulateNdefMessage, true));
		_emulateNdefMessage = 0;


	CHECK(nfc_set_sp_uri(spNdefRecord, _ndefSpUri.toUtf8().constData()));

	CHECK(nfc_add_ndef_record(_emulateNdefMessage, spNdefRecord));


	emit message(QString("Emulating Sp Tag:"));
	emit message(QString("%1").arg(_ndefSpUri));
	emit message(QString("%1").arg(_ndefSpText));

Figure 5 – Preparing to emulate a Virtual Tag



Here’s what’s happening in the prepareToEmulateTag() function. First we check that the initialization step completed successfully. We then write some messages to the event log screen by emitting the message signal which we connected to the event log elsewhere in our code.


We’re going to emulate an NFC Smart Poster NDEF tag. The URI and Text that will comprise the Smart Poster tag have been derived from the screen where the user has entered them.


Setting up tag emulation is fairly simple. All we need to do is create an NDEF Message that will be delivered when our virtual tag is read and tell NFC to start tag emulation using that NDEF Message.


We already know how to create a Smart Poster NDEF Message. We’ve done this before in the function that writes an NDEF tag. The process is exactly the same here and we won’t duplicate the description.


The single key difference is what we do with the Smart Poster NDEF Message once it’s been created. In the case where we were writing tags the message was written to a tag that was presented to the device. In this case we present the NDEF Message through the nfc_start_ndef_tag_emulation() NFC API function. That’s all we need to do.

When we’re no longer interested in performing tag emulation it should be stopped in a controlled manner. Figure 6 shows the prepareToStopEmulation() function which does this.


void NfcWorker::prepareToStopEmulation() {
	if (_failedToInitialize) {

	qDebug() << "XXXX NfcWorker::prepareToStopEmulation entered ...";
	qDebug() << "XXXX setting inTagEmulationState=false";

	StateManager* state_mgr = StateManager::getInstance();

	if (state_mgr->inReadState()) {
		_taskToPerform = READ_NDEF_TAG;

	emit message(QString("Preparing to stop Tag emulation"));

	if (_emulateNdefMessage) {
		CHECK(nfc_delete_ndef_message(_emulateNdefMessage, true));
		_emulateNdefMessage = 0;


	emit message(QString("Tag emulation stopped"));

	qDebug() << "XXXX NfcWorker::prepareToStopEmulation exited ...";

 Figure 6 – Stopping virtual emulation



Stopping tag emulation is very simple. It simply involves making a call to the NFC API function called nfc_stop_ndef_tag_emulation(). The bulk of prepareToStopEmulation() is mostly concerned with housekeeping around state, logging and debugging message to show what’s going on.


It’s important to make sure that the NDEF Message that we obtained previously from the call to nfc_create_ndef_message(&_emulateNdefMessage) is correctly freed up again through a call to nfc_delete_ndef_message(_emulateNdefMessage, true).  We go through some gymnastics to ensure that this happens correctly in all cases.


Setting up and stopping virtual emulation is all very well, but we would also like to have some visibility into what happens when our virtual tag is “read” by a reader. That’s why we remember that we’re currently in the virtual emulation state by setting “_taskToPerform = EMULATE_TAG” in prepareToEmulateTag() in Figure 5.


As NFC events are received in the event loop these can be processed in the correct context. Figure 7 shows the relevant parts of the handleNfcEvent() function that does this.


void NfcWorker::handleNfcEvent(bps_event_t *event) {


	switch (_taskToPerform) {


		qDebug() << "XXXX Handling an NFC event in EMULATE_TAG state";


 Figure 7 - handleNfcEvent


The handleEmulateNfcEvent() function drives the logic which simply reports on virtual tag emulation events. Figure 8 shows this.


void NfcWorker::handleEmulateNfcEvent(bps_event_t *event) {
	uint16_t code = bps_event_get_code(event);

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

		qDebug() << "XXXX Nfc Virtual Tag Selection Event detected";
		emit message("NFC Virtual Tag Selection Event detected");

	} else if (NFC_VIRTUAL_TAG_LEFT_EVENT == code) {
		qDebug() << "XXXX Nfc Virtual Tag Left Event detected";
		emit message("NFC Virtual Tag Left Event detected");

	} else if (NFC_VIRTUAL_TAG_READ_EVENT == code) {
		qDebug() << "XXXX Nfc Virtual Tag Read Event detected";
		emit message("NFC Virtual Tag Read Event detected");

	qDebug() << "XXXX Emulate done";

Figure 8 – Processing virtual tag emulation events  


The important aspects of Figure 8 are as follows. There are three types of NFC events that are of importance to the handleEmulateNfcEvent() function:


    This event occurs when an external reader has “selected” the virtual tag that is being emulated. This is a precursor to either a read being performed on the virtual tag or the handset leaving the NFC radio field of the reader.
    This event occurs when the external reader actually reads the NDEF Message data that’s been prepared previously.
    This event occurs when the handset leaves the NFC radio field of the reader.

In the case of this application these events are simply logged and displayed on the event log screen of the application. Figure 9 shows an example of the messages that you might expect to see when an external reader reads the virtual tag.



Figure 9 – Event log showing a reader selecting, reading, and leaving the device’s NFC field 



Next Steps


Emulating a virtual NDEF tag is only one form of NFC emulation type that is available on BlackBerry 10. In addition to this form of emulation it’s possible to perform ISO 14443-4 emulation.


We won’t go into this in detail here but the basic principle is similar to emulation of a virtual tag.


  • Use the nfc_start_iso14443_4_emulation() function to register ISO 14443-4 card information with the NFC service.
  • Await NFC_ISO14443_4_COMMAND_EVENT and NFC_ISO14443_4_EVENT_CODE_EVENT events from the external reader.
  • Use the function nfc_get_iso14443_4_emulation_command() to obtain the command sent from the reader and nfc_send_iso14443_4_emulation_command_response() to provide a response.
  • Stop emulation using nfc_stop_iso14443_4_emulation().




Performing NFC Virtual Tag Emulation from a BlackBerry 10 C++ application is simple and requires only a few function calls.


You can download NFC Tool V2.1, including its full source code from:


NFC Tool as written for the BlackBerry 10 “Dev Alpha” device and requires the following versions of the NDK and device software to build and run:


  • BlackBerry 10 Native SDK 10.0.6
  • BlackBerry Dev Alpha Device Software 10.0.6

You can find details of other NFC related articles and sample applications written by Martin and John at


You can contact Martin or John through either the BlackBerry support forums or through Twitter:


  Support Forum ID Twitter 
 Martin  mwoolley @mdrim 
 John jomurray  @jcmrim