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

Java Development

NFC - Peer to Peer Communications with SNEP

by Retired ‎01-30-2012 12:29 PM - edited ‎06-15-2012 02:20 AM (11,230 Views)

Introduction

This article is the fifth in a series of articles about NFC which are intended to help applications developers exploit NFC from within their own applications for BlackBerry® smartphones such as the BlackBerry® Bold™ 9900 and BlackBerry® Curve™ 9360.

 

Readers of this article should have some pre-existing knowledge of the fundamental architecture of NFC systems and be familiar with Java®.

 

Unless you already have good knowledge of the subjects covered, it’s recommended that you read the earlier articles in this series. Links to these articles can be found at the end of this one.

As well as covering some of the relevant theory, this article will look at an example application that acts as a SNEP responder in a peer to peer communication scenario. If you don’t know what these terms mean, don’t worry; all will be explained.

 

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 specialize in NFC applications development (amongst other things).

 

About this article

In the previous articles we’ve shown how to work with NFC smart tags and in the last article we showed how to transfer some arbitrary data from one device to another using a technique known as “virtual target emulation”. In this article we’ll look at an alternative way of transferring data between devices using one of the NFC forum defined modes of operation “peer to peer” and something called the Simple NDEF Exchange Protocol or “SNEP” for short.

 

Peer to Peer Use Cases

There are essentially two classes of use case that might be supported by NFC peer to peer data transfer. Simply put, these are cases involving small amounts of data or cases involving larger amounts of data.

 

In the case where there is a small amount of data to be transferred, and a URL might be a good example of such a case, then typically the data would be transferred using the NFC SNEP protocol, which we’ll talk about some more later in this article. Significantly, NFC is used for the entire data transfer operation.

 

A concrete example from the “small amount of data class” might be the transfer of a web site URL to a friend’s BlackBerry. “Look at this great site! Here, let me give you the URL”. You proceed to tap your BlackBerry to your friend’s and the URL gets immediately transferred. Beats reading out the URL and then the friend keying it in!

 

Where larger amounts of data are concerned however (e.g. pictures, videos etc) it is more usual to use Bluetooth® for the actual data transfer, but to use NFC to establish the Bluetooth connection in the first place. This practice is known as “connection handover” and there’s a BlackBerry API for this too. We’ll talk more about connection handover later in this article.

A concrete example here might be a picture gallery application which lets you show collections of your photographs. Transferring a selected image or two via an NFC connection handover established Bluetooth connection would be easy and natural.

 

When considering which of the two techniques to use, as a guideline, you should think about the time it will take to transfer your data. If it would take more than 3 or 4 seconds over NFC and therefore require the two users to keep their devices touching (or very close) for that length of time, then it would probably be better to use connection handover. Bluetooth is good at transferring files and allows the users to have their devices significantly further apart than is the case with NFC. NFC’s role in establishing the Bluetooth connection between the two devices is good at making the overall process quick and painless for the user.

 

Now let’s move on to the technical aspects of NFC peer to peer.

 

Modes of Communication

If all you want to do is learn how to use the BlackBerry APIs to add NFC Peer to Peer capabilities to your application, you can skip this section. It’s useful technical background however... so we’d recommend you read it anyway.

 

In our first article in this series, the NFC Primer for Developers (http://supportforums.blackberry.com/t5/Java-Development/NFC-Primer-for-Developers/ta-p/1334857 ), we introduced the three NFC modes of operation, namely Reader/Writer, Card Emulation and Peer to Peer. Under-pinning these modes of operation are two “modes of communication” and these are named Active and Passive respectively.

 

In Active Mode, the NFC device generates an RF field and acts as the “initiator”. In Passive Mode the NFC device does not generate an RF field, though it may use the RF field generated by another device whose field it encounters to draw energy from. The device in Passive Mode is termed the “target”. The initiator is also responsible for detection of other NFC devices whilst the target is concerned with advertising its presence to enable this.

 

Here’s how the two modes of communication get used in the three modes of operation:

Reader / Writer Mode – The NFC device which acts as the reader/writer is in Active Mode whilst the NFC tag or card is in Passive Mode.

 

NFC Device (acting as the reader)

Card or Tag

Active

Passive

 

 

Card Emulation Mode – Here, the reverse is true with the emulated card, running in the NFC device or a secure element within that device, acting in Passive Mode and the external reader, which is also known as the PCD (Proximity Coupling Device) operating in Active Mode.

 

NFC Device (emulating the card)

Reader

Passive

Active

 

Peer to Peer Mode – this is the subject of this article and so especially relevant. In Peer to Peer Mode of operation, usually both devices operate in Active Mode though technically it is possible for one device to be Active and the other Passive.  

 

NFC Device 1

NFC Device 2

Active

Active

 

Simple NDEF Exchange Protocol

SNEP is defined by the NFC Forum. Per the name, it’s a protocol designed to allow the easy exchange of data in an NDEF format. NDEF is the NFC Data Exchange Format. We covered aspects of NDEF in a previous article: http://supportforums.blackberry.com/t5/Java-Development/Reading-and-Writing-NFC-Smart-Tags/ta-p/1379...

 

Like many other protocols, it’s of the request/response type. A SNEP client kicks things off by sending a request to a SNEP server. The server processes the request and responds. Figure 1 illustrates this basic communication model.

 

 

communication_model_640.png

Figure 1 - SNEP communication model

 

SNEP messages can be quite large, up to 232-1 bytes to be precise. That’s 4096MB by my calculations. The underlying transport layer will generally have a much smaller maximum size for a single data unit and consequently it may become necessary to split a SNEP message into fragments for transmission and which will need to be reconstituted into the original SNEP message by the receiver.

 

Sound complicated? Luckily the BlackBerry APIs take care of this behind the scenes so for the application developer, life is relatively simple and this is not an issue.

We’ve covered the basic protocol stacks involved in NFC in other articles, namely the ISO 7816 and ISO 14443 stacks and the basic roles they play. SNEP itself runs on top of an intermediate layer in the stack containing a protocol called the Logical Link Layer Protocol or LLCP for short. Beneath that there are some optimisations for Peer to Peer Mode in the lower layers and these are defined in a specification known as ISO 18092.  See Figure 2.

 

LLCP provides a transport layer which can be either connection-oriented with guaranteed delivery of data units in a given sequence or connectionless whereby the transmission is unacknowledged. These concepts should be familiar from other communications systems.
 

Regarding ISO 18092, this includes ISO 14443-A which is used for the initial handshake, and another variant, ”Type-F”, which is used once an LLCP connection has been established. So ultimately NFC peer to peer utilises the 14443 stack which we’re already aware of. Yes, the world of NFC is complicated. But luckily we have BlackBerry APIs that hide the greater majority of this complexity from us.

 

snep_stack_640.png 

 

Figure 2 – SNEP, LLCP and ISO 18092

 

The BlackBerry APIs include an API for working directly with LLCP. We won’t be covering this here, focusing rather on SNEP for data transfer.

 

Why use SNEP anyway?

In our previous article, we showed you how to transfer data from one device to another using Virtual Target Emulation. So why bother with SNEP if we already have a way of accomplishing essentially the same thing?

 

SNEP has a number of advantages over using Virtual Target Emulation for transferring data objects. Chief amongst these are:

 

1.       No need to get involved directly with ISO 7816-4 APDUs! There’s no question that working directly with these APDUs is pretty low level stuff and you’d have to do everything yourself, including implementing some mechanism for handling larger amounts of data such as the fragmentation mechanism that SNEP has built-in. In short, SNEP is much easier for this kind of task than Virtual Target Emulation.

 

2.       The use of NDEF for message formats immediately makes the client side easy, and quite possibly you’ll need to do no work on that side of the architecture at all. Many of the applications on a standard BlackBerry smart phone are already NFC-enabled and the appropriate application will be used for the type of message that is served by the SNEP responder automatically without you needing to do any coding. With Virtual Target Emulation, you’d need to figure out whether to launch another application yourself.

 

3.       SNEP uses Type-F RF modulation which is capable of significantly higher communication speeds than 14443-A so performance should be better too.

 

So let’s take a look at the SNEP APIs and how they’re intended to be used.

 

The BlackBerry SNEP APIs

These APIs are really only concerned with the role of the SNEP server. A client application which receives and uses a message pushed to it by a SNEP server is basically just a standard NDEF message reader which implements the NDEFMessageListener interface which we covered in the previous article on this subject. Therefore we’ll focus on the SNEP server here.

 

Central to working with SNEP on BlackBerry are two interfaces and a class:

 

                Interface:NDEFMessageBuilder

                Interface:NDEFPushStatusCallback

                Class:NDEFPushManager

 

You’ll find each of these in the net.rim.device.api.io.nfc.push package in the 7.1 APIs. This package was introduced at version 7.1 so you will not find it in the 7.0 documentation.

 

Implementing a typical SNEP server / responder will require the following 3 steps to be carried out:

 

1.       Implement the NDEFMessageBuilder interface

2.       Implement the NDEFPushStatusCallback interface

3.       Register instances of these implementing classes using the NDEFPushManager

NDEFMessageBuilder’s responsibility is to respond to a request from a SNEP client by building an array of NDEFMessage objects and passing it back to the system which will then push the message(s) over NFC to the client. Figure 3 shows an example implementation which in this case, builds a message from a hard coded vCard object shown in Figure 4.

 

public class NfcSnepResponderMsgBuilder implements NDEFMessageBuilder {

    public NDEFMessage[] buildNDEFMessages() {
        NDEFMessage[] listOfNdefMessages = null;
        NDEFMessage myNdefMessage;
        
        try {
            myNdefMessage = NDEFMessageUtils.createMediaTypeNDEFMessage(
                    Constants.VCARD_MIME_TYPE, 
                    Constants.VCARD_DATA.getBytes());

            listOfNdefMessages = new NDEFMessage[]{myNdefMessage};
            
        } catch(NFCException e) {
          // log the issue
        }
        return listOfNdefMessages;
    }
}

 

Figure 3 – Implementing the NDEFMessageBuilder interface

 

    public static final String VCARD_MIME_TYPE = "text/x-vCard";
    public static final String VCARD_DATA = 
        "BEGIN:VCARD\n" +
        "VERSION:3.0\n" +
        "N:Guy;NFC;;;\n" +
        "FN:NFC Guy\n" + 
        "ADR;TYPE=WORK:;;200, Bath Road;Slough;Berkshire;SL1 3XE;UK\n" + 
        "TEL;TYPE=PREF,WORK:+44 1234 123000\n" +
        "TEL;TYPE=CELL:+44 4321 321000\n" +
        "TEL;TYPE=FAX:+44 1212 123321\n" +
        "EMAIL;TYPE=INTERNET:nfc_guy@rim.com\n" +
        "TITLE:Senior Application Development Consultant\n" +
        "ORG:Developer Relations\n" +
        "CATEGORIES:Business\n" +
        "URL:http://www.rim.com\n" +
        "X-ORG-URL:http://www.rim.com\n" +
        "END:VCARD";
}

 

Figure 4 - Code fragment showing the hard coded vCard object that will be served out over SNEP

 

The outcome of attempting to push an NDEF message over SNEP to a client will be communicated back to the application asynchronously, via the implementation of NDEFPushStatusCallback. This interface also has a single method, this one called onNDEFPushStatusUpdate. It receives two parameters; the first, a copy of the NDEFMessage whose status is being reported on and the second, the status itself encoded as an integer value.

The NDEFPushStatusUpdate interface defines the following constants for each of the possible status values which you might expect to receive:

 

DATA_TOO_LARGE

INVALID_DATA

PUSH_ERROR

REJECTED

SUCCESS

 

Hopefully these are largely self explanatory. PUSH_ERROR, which is a rather general term, will be encountered when there has been some kind of I/O error, possibly caused by the two devices moving apart before the transfer had completed.

 

Figure 5 shows an example implementation of NDEFPushStatusCallback.

 

public class NfcSnepResponderCallBack implements NDEFPushStatusCallback {

    public void onNDEFPushStatusUpdate(NDEFMessage ndefMessage, int status)       
    {

        String textStatus;
        byte [] ndefMessageAsBytes;
        
        switch (status) {
        
            case NDEFPushStatusCallback.SUCCESS:
                textStatus = "SUCCESS";
                break;
    
            case NDEFPushStatusCallback.REJECTED:
                textStatus = "REJECTED";
                break;
                
            case NDEFPushStatusCallback.PUSH_ERROR:
                textStatus = "PUSH_ERROR";
                break;
                
            case NDEFPushStatusCallback.INVALID_DATA:
                textStatus = "INVALID_DATA";
                break;
                
            case NDEFPushStatusCallback.DATA_TOO_LARGE:
                textStatus = "DATA_TOO_LARGE";
                break;
                
            default:
                textStatus = "UNDEFINED";
                break;
        }
// do something meaningful with the result       
    }
}

 

Figure 5 - Implementing the NDEFPushStatusCallback interface

 

You probably noticed something interesting here. You return an array of NDEFMessage objects from your NDEFMessageBuilder and yet the NDEFPushStatusCallback object receives only a single instance of NDEFMessage in calls to its onNDEFPushStatusUpdate() method. This is because if you do return an array of more than one NDEFMessage object, you will receive individual calls to your NDEFPushStatusCallback object for each NDEFMessage object individually. You can check which message you’re being given the status for by looking at the NDEFMessage parameter of course.

 

Armed with our implementations of NDEFMessageBuilder and NDEFPushStatusCallback, all that remains is to instantiate them and register them with the system. Figure 6 shows this.

 

   protected void registerForNdefPush() {
        
        NDEFPushManager ndefPushManager = NDEFPushManager.getInstance();

        _myMsgBuilder = new NfcSnepResponderMsgBuilder(_screen);
        _myStatusCallBack = new NfcSnepResponderCallBack(_screen);
        
        if ((_ndefPushManager != null) && !_registeredWithPush) {
            _ndefPushId = ndefPushManager.pushNDEF(_myMsgBuilder,     _myStatusCallBack);
            _registeredWithPush = true;
        }
    }

 

Figure 6 The method “registerForNdefPush()”

 

As shown, we call the pushNDEF() method of our NDEFPushManager object and provide our NDEFMessageBuilder and NDEFPushStatusCallback objects as parameters. In return, we’re given an int value. This is a registration ID and we can use this later on to cancel the registration of our interfaces as shown in Figure 7 below by calling the cancelNDEFPush() method of the NDEFPushManager object.

 

    protected void unregisterForNdefPush() {
        
        if ((_ndefPushManager != null) && _registeredWithPush) {
            _ndefPushManager.cancelNDEFPush(_ndefPushId);
            _registeredWithPush = false;
            _myMsgBuilder = null;
            _myStatusCallBack = null;
        }
    }

 

Figure 7 – Cancelling our SNEP registration

 

Foreground is where the action is

For an application which is acting as a SNEP responder to receive call-backs to its NDEFMessageBuilder interface, it must be running in the foreground. This makes sense if you think about it. There could be multiple applications on a device, each of which has implemented the NDEFMessageBuilder interface and all of which might be running at the same time.

The SNEP APIs are designed with use cases in mind whereby the person wishing to transfer some data (like a vCard for example) will bring up the application, select the data (e.g. the particular contact from their address book) and then bring their device together with the device they want to transfer the vCard to. It’s a very explicit action on behalf of the user. “Send this vCard to the other device please” might be a way of thinking about this scenario.

 

BlackBerry Tags

This is not really a developer issue, but whilst we’re talking about use cases, it might be worth pointing out that as of version 7.1 of the BlackBerry OS, many of the standard BlackBerry applications are “NFC-enabled” and can transfer their data to another device via SNEP. This capability is known as BlackBerry Tags.

 

As an example, if you have a 7.1 device, go into the Contacts app, select a contact and then pop up the menu. You’ll see you have the option to Send Contact Card. Click on this menu item and a sub-menu, offering you various ways of sending your contact card will appear. One of those options is “Tag”. This means “please use NFC”! Figure 8 has a screenshot from a Bold 9900 doing just that.

 

bbtags.png

Figure 8 - BlackBerry Tags in the Contacts app

 

About SNEP Clients

SNEP clients implement the NDEFMessageListener interface just like any standard tag reading application and as such will receive calls to their onNDEFMessageDetected() method when a SNEP server has pushed an NDEFMessage to the device on which the client application is running.

 

One thing a SNEP client may choose to do, which a standard tag reader might not, however, is to use connection handover to complete the remainder of the data transfer over Bluetooth. In this case the content of the NDEFMessage received over SNEP must include details necessary to establish a Bluetooth connection back to the other device and initiate the transfer.

We’ll cover connection handover as a topic in a future article.

 

The Sample Application

We’ve created a sample application to accompany this article and you can download the full source code from our blackberry/Samples-for-Java/NFC github repository. The application acts as a SNEP responder and, when another NFC enabled device which supports SNEP enters the NFC field, it will automatically push a vCard object over SNEP to the other device. Don’t forget that you need BlackBerry devices which are running OS 7.1 for SNEP support to be available.

You’ll find the sample code here:

 

https://github.com/blackberry/Samples-for-Java/tree/master/NFC/NfcSnepResponder

 

When you launch the application you will first see a screen with a single icon as shown below in figure 9.

 

snep1.png

Figure 9 - The SNEP sample application start screen

 

Click the icon with the track pad to proceed. The next screen is an event log that will provide information about the application’s progress as it proceeds to serve a vCard to another device.

 

 snep2.png

Figure 10 - The sample application event log

 

Bring another NFC enabled device which supports SNEP into the device’s NFC field and the event log will show activity per Figure 11.

 snep3.png

Figure 11 -  Event log showing activity

 

On the other device you should see the UI indicating receipt of the vCard over SNEP and be given the opportunity to save the vCard to the Contacts application. See Figure 12.

 

 

snep4.png

Figure 12 - Receiving the vCard over SNEP

 

After saving the vCard you’ll see a new entry in your Contacts database like the one in Figure 13 below.

 

snep5.png

Figure 13 - The vCard after saving


 

Summary

In this article we’ve reviewed the Simple NDEF Exchange Protocol from a variety of perspectives. We hope this has helped make it easy for you to take advantage of SNEP in your own BlackBerry applications.

 

The APIs are available today so download the latest BlackBerry® JDK® from

http://us.blackberry.com/developers/blackberry7/

 

BlackBerry Java APIs are documented here if you'd like to browse further:

http://www.blackberry.com/developers/docs/7.1.0api/

 

The NFC Forum Home Page can be found here: http://www.nfc-forum.org

 

Other BlackBerry Developer NFC Articles

 

See the NFC Article Index for the list of other articles in this series

 

 

Glossary of NFC Terms

  • APDU - Application Protocol Data Unit. A message type which forms part of a protocol and which may be exchanged between peers as either a request or a response message. Applications on a BlackBerry smartphone may communicate with applets in an SE using the ISO 7816-4 APDUs for example.
  • CLF - Contactless Front-end. Part of the NFC Controller. Communicates via RF with an NFC reader.
  • HCI - Hardware Controller Interface. Amongst other things, this component of the NFC system architecture redirects radio communication to appropriate SE.
  • ISO 7816-4 - the specification which defines the protocol which allows applications to communicate with applets installed in an SE or smart card.
  • NDEF - NFC Data Exchange Format
  • NFC - Near Field Communications
  • PCD – Proximity Coupling Device (also known as “card reader”)
  • PICC – Proximity Integrated Circuit Card
  • SE - Secure Element. A hardware component which can host and act as an execution environment for small software applications known, in this context, as "applets".
  • SIM - Subscriber Identity Module. In 2G modules this used to be synonymous with the SIM *card* i.e. the small smart card inserted in the handset. In 3G networks, the SIM is a software module installed on the UICC.
  • SNEP  - Simple NDEF Exchange Protocol
  • SWP - Single Wire Protocol.
  • UICC - Universal Integrated Circuit Card - the smart card used in mobile terminals in GSM® and UMTS® networks.
Contributors
Users Online
Currently online: 10 members 1,029 guests
Please welcome our newest community members: