DEVELOPERS BLOG

Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 5: Virtual Tag and Card Emulation

OPEN SOURCE / 10.14.13 / alexkinsella1

Abstract background. Yellow - green palette.

Guest post by Martin Woolley and John Murray

This is the fifth part of a six-part series by Martin Woolley and I on porting BlackBerry Java applications that use NFC to BlackBerry 10. So far we’ve looked at Tag Reading, Tag Writing, Peer to Peer mode and the Reading of contactless cards. In this post, we’ll review the porting of code that implements virtual target emulation.

Here’s where we are in the series as a whole:

  1. Reading NFC Tags
  2. Writing NFC Tags
  3. Peer to Peer Mode
  4. Reading NFC Contactless Cards
  5. NFC Virtual Tag and Card Emulation
  6. NFC Card Emulation

So, let’s dive straight in and take a look at the aspects that you have to deal with:

Key Issues for the Java Developer

Let’s review the key issues and steps that a BlackBerry Java developer would have to go through to implement NFC virtual target emulation, and for the sake of being specific, let’s assume that we want to emulate an ISO-14443-4 type “A” target. Type “B” is identical.

  1. Create an instance of a class that implements VirtualISO14443Part4TargetCallback: Firstly, implement the two methods: onVirtualTargetEvent() and processCommand() of the VirtualISO14443Part4TargetCallback interface in order to be notified when the virtual target has been activated, de-activated or selected by an external reader; or, when a command, in the form of an APDU, is presented by an external reader.
  2. Create an instance of the VirtualISO14443Part4TypeATarget: Secondly, create an instance of the VirtualISO14443Part4TypeATarget class and provide it with a listener in the form of an instance of the class that was created in the previous step implementing the VirtualISO14443Part4TargetCallback interface.
  3. Start processing events delivered via the VirtualISO14443Part4TargetCallback interface: Finally, use the startEmulation() method of the VirtualISO14443Part4TypeATarget instance to start virtual target emulation; and conversely use the stopEmulation() method to stop virtual target emulation. The method onVirtualTargetEvent() will be called to notify of state changes of the virtual target. The method processCommand() will be called to deliver APDUs sent from the external reader to the virtual target for processing.

The BlackBerry 10 Native Approach:

There are two basic approaches depending on whether you want to emulate a NFC tag with a NDEF message as a payload; or, perform lower level (such as ISO-14443-4) emulation where APDUs are received and require a response.

Emulating an NDEF Tag

Starting virtual tag emulation in BlackBerry 10 is quite simple. It involves preparing a NDEF message that will represent the content of the virtual tag and then calling nfc_start_ndef_tag_emulation(). Stopping virtual tag emulation is equally easy: just call nfc_stop_ndef_tag_emulation(). Both of these are shown in the code fragment below.

...
void NfcListener::startTagEmulation(const QString &tagData) {

    int rc;
     nfc_ndef_record_t *ndefRecord =
        makeCustomRecord(
             QString("my.rim.com"), QString("myrecordtype"), tagData);
    if (_emulateNdefMessage) {
        rc = nfc_delete_ndef_message(_emulateNdefMessage, true);
        _emulateNdefMessage = 0;
    }

     rc = nfc_create_ndef_message(&_emulateNdefMessage);
    rc = nfc_add_ndef_record(_emulateNdefMessage, ndefRecord);
    rc = nfc_start_ndef_tag_emulation(_emulateNdefMessage);

 ...

 void NfcListener::stopTagEmulation() {

      int rc;
      rc = nfc_stop_ndef_tag_emulation();

      if (_emulateNdefMessage) {
            rc = nfc_delete_ndef_message(_emulateNdefMessage, true);
            _emulateNdefMessage = 0;
      }
}
...

In addition, you can use BPS (BlackBerry Platform Services) to track the current state of the virtual target in relation to the external reader. This is shown in the code fragment below, where the events of interest are:

  • NFC_VIRTUAL_TAG_SELECTION_EVENT: 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.
  • NFC_VIRTUAL_TAG_READ_EVENT: This event occurs when the external reader actually performs a read on the NDEF Message data that’s been prepared previously.
  • NFC_VIRTUAL_TAG_LEFT_EVENT: This event occurs when the handset leaves the NFC radio field of the reader.
...
void NfcListener::handleNfcEvent(bps_event_t *event) {

     uint16_t code = bps_event_get_code(event);

     if (NFC_VIRTUAL_TAG_SELECTION_EVENT == code) {
        // do something
    } else if (NFC_VIRTUAL_TAG_LEFT_EVENT == code) {
        // do something
    } else if (NFC_VIRTUAL_TAG_READ_EVENT == code) {
        // do something
    }
}
...

ISO-14443-4 type emulation

The basic principle is similar to emulation of a virtual tag; as in the Java case, we’ll assume that we’re doing ISO-14443-4 emulation and need to receive APDUs and respond to them.

Use the function:

  • nfc_start_iso14443_4_emulation() to register ISO 14443-4 card information with the NFC service.

Then use the BPS (BlackBerry Platform Services) to

  • Await NFC_ISO14443_4_COMMAND_EVENT and NFC_ISO14443_4_EVENT_CODE_EVENT events as a result of actions by the external reader.

Use the function:

  • nfc_get_iso14443_4_emulation_command() to obtain the command sent from the reader

Then use the function:

  • nfc_send_iso14443_4_emulation_command_response() to provide a response to the command just received.

Finally, stop emulation using the function:

  • nfc_stop_iso14443_4_emulation().

And that’s all there is to it!

Resources

Knowledge Base Articles:

Blog Posts

Sample Code: Here are two code samples showing the use of virtual NDEF Tag emulation.

Contacts

About alexkinsella1