Using the NFC emulator

This API is available on Firefox OS for privileged or certified applications only.

For testing of the NFC API, there is an NFC emulator available. This article details how to set up and use the emulator, and perform some simple tests.

NFC emulator prerequisities

In order to use the NFC emulator, you need the following prerequisites in place:

  • A B2G emulator. You need to have a B2G emulator running a recent B2G build. See Preparing for your first B2G build for more details on how to build Firefox OS, and Using the B2G emulators for emulator reference.
  • A Telnet client. On Mac OS X Telnet is installed by default; on Ubuntu, you can easily find and install the "telnet" package. 
  • For debugging purposes, it is convienient to have the ADB toolchain installed as well.

Note: Currently NFC can be used on "emulator-jb" only. When, during build process you invoke ./config.sh, make sure to use one of that as a build target.

Launching the emulator

  1. First, start off by launching the emulator:
    Bash
    $ cd B2G
    $ ./run-emulator.sh
  2. Once it's booted, unlock the screen and enable NFC (Settings app > NFC).
  3. The NFC module is switched off whenever the screen is turned off; to work around that, change the screen timeout to never (Settings app > Display > Screen timeout > Never).
  4. Now it's time to connect to emulator's telnet console. By default, the emulator listens on port 5554 (the port number is shown on titlebar of emulator's window):
    Bash
    $ telnet localhost 5554
    Trying 127.0.0.1... 
    Connected to localhost.
    Escape character is '^]'. 
    Android Console: type 'help' for a list of commands 
    OK

The emulator is now ready to accept your commands — now let's look at what we can do with this.

Telnet command line interface

The general syntax for NFC Telnet command is:

JavaScript
nfc <protocol> <command> <arguments>

Too see which protocols are supported, use the nfc command on its own:

Bash
nfc
allows you to modify/retrieve NFC states and send notifications

available sub-commands:
    nci              send NCI notification
    snep             put and read NDEF messages
    llcp             internal LLCP handling
    tag              data handling

KO: missing sub-command

The sub-commands listed above are explained in more detail below, but in general you'll want to use them in the following order:

  1. nci (active an NFC endpoint)
  2. llcp (set up an emulated LLCP link)
  3. snep (message handling) or tag (data handling)

Note: For every command you issue on a telnet interface, you will get either an "OK" or "KO" status. The first one is self-explanatory, whereas the latter means a failure and will usually provide an error message.

Testing peer to peer content sharing

One of the major use cases for NFC is the sharing of web pages, contacts, etc., with the information being transmitted as NDEF (NFC Data Exchange Format) records, which are themselves encapsulated inside SNEP (Simple NDEF Exchange Protocol) messages.

Initial connection setup

In order for sharing to work, you first have to activate an NFC endpoint:

JavaScript
nfc nci rf_intf_activated_ntf 0
OK

Then set up an emulated LLCP link:

JavaScript
nfc llcp connect 4 4
OK

Note: The general syntax for the llcp command is: nfc llcp connect <DSAP> <SSAP>. Use a value of 4 for each of these (as in the command above), for SNEP transfers.

Sending messages

Now you are able to send various NDEF messages; Firefox OS will inspect received NDEF messages and fire appropriate apps to handle them. Built-in applications such as Browser, Contacts or Dialer will handle most common URIs.

The most basic example is web page sharing. If you enter the following command, for example, the Browser app should open with http://www.mozilla.org loaded:

JavaScript
nfc snep put -1 -1 [208,1,VQ,AW1vemlsbGEub3Jn,]
OK

Note: Be careful not to include any extra spaces between the square brackets, otherwise the command will fail. This is a known limitation and it's being worked on as part of Bug 1015127. Also, in the command above the trailing comma is mandatory.

Note: In the command above, we have used a value of -1 for both DSAP and SSAP. This is a convienience feature: -1 indicates that the previously used value should be used (4 and 4 in this case, as set in the llcp command).

NDEF message syntax

In between the square brackets there is an NDEF message encoded, containing five fields. The general syntax is as follows:

JavaScript
nfc snep put -1 -1 [flags,tnf,type,payload,id]

Flags

NDEF message flags, such as MB (message beginning), ME (message end) or SR (short record). These are described in detail in section 3.2 of NFCForum-TS-NDEF_1.0 (PDF), published by the NFC Forum. There are five flags defined:

  • MB (128): Indicates that this record is first in message.
  • ME (64): Indicates that  this record is last in message.
  • CF (32): Used in chunked records.
  • SR (16): Short record, meaning that payload length is encoded on a single octet (instead of the default four.)
  • IL (8): Indicates that ID length is present.

In our example above, flags has a value of 208, which is the sum of 128 + 64 + 16: this therefore means that the MB, ME and SR flags are set. The Emulator attempts to set flags automatically, whenever possible, meaning that the following two commands are equivalent:

Bash
nfc snep put -1 -1 [208,1,VQ,BmthbWl0dWVsQGdtYWlsLmNvbQ,]
OK
nfc snep put -1 -1 [0,1,VQ,BmthbWl0dWVsQGdtYWlsLmNvbQ,]
OK

TNF (Type Name Format)

Indicates what structure the "type" field has. The most common types are "well known" (TNF = 1) and "media type" (TNF = 2). Well-known records are records whose structure is defined by NFC Forum, such as URI or text records. Media type records can carry any arbitrary information whose type is identified by it's MIME type.

Record type

Describes the type of the payload. For well known records (those with TNF = 1) it's a code defined by the NFC Forum (U for URIs, T for text records). For media type records, it's the MIME type of the payload (e.g. image/jpeg.)

Note: The emulator telnet interface accepts this field in Base64 encoded format. This means that for URI well-known records, you should use VQ instead of U; for text well-known records, use VA instead of T. Similarly, you should Base64 encode MIME types for media type records.

Payload

The contents of the message, as a Base64 encoded array of bytes. In the example shown above, we have used the value AW1vemlsbGEub3Jn, which is equal to a [1,109,111,122,105,108,108,97,46,111,114,103] array (Base64 encoded.)

Record ID

Allows you to include an ID value to identify the record in the whole message. This field is optional, but if you omit it you have to leave in the trailing comma (as in the example above.) This also has to be Base64 encoded.

Example SNEP commands

This section provides some common snep commands that should satisy most of your testing needs.

Note: If you use the snep command without the NDEF message argument:

Bash
ndef snep put -1 -1

it will print out the previous message received from the LLCP connection.

URLs

Bash
# Flags: MB,ME,SR
# TNF: 1 (well known)
# Type: 'U'
# Payload: 'http://www.google.com'
# ID: 'A'
nfc snep put -1 -1 [208,1,VQ,AWdvb2dsZS5jb20=,A]

# Flags: MB,ME,SR
# TNF: 1 (well known)
# Type: 'U'
# Payload: 'https://www.google.com'
nfc snep put -1 -1 [208,1,VQ,Amdvb2dsZS5jb20=,]

# Same as above, but with no URI abbrevation.
# Flags: MB,ME,SR
# TNF: 1 (well known)
# Type: 'U'
# Payload: 'https://www.google.com'
nfc snep put -1 -1 [208,1,VQ,AGh0dHA6Ly9tb3ppbGxhLmNvbQ,]

Note: The prefix of the URI is often abbreviated with an abbreviation code of 1, e.g. http://www.mozilla.com could be represented both as [104,116,116,112,58,47,47,119,119,119,46,109,111,122,105,108,108,97,47,99,111,109] and [1,109,111,122,105,108,108,97,47,99,111,109]. The latter form is much shorter, because the prefix http://www. has been replaced with 1. See nfc_utils.js for a full table of abbreviations, as defined in NFCForum-TS-RTD_URI_1.0.

Mailto: URI

Bash
# Mailto: URI
# Flags: MB,ME,SR
# TNF: 1 (well known)
# Payload: 'mailto:kamituel@gmail.com'
nfc snep put -1 -1 [208,1,VQ,BmthbWl0dWVsQGdtYWlsLmNvbQ,]

Tel: URI

Bash
# Flags: MB,ME,SR 
# TNF: 1 (well known) 
# Type='U' 
# Payload: 'tel:0048123456789' 
nfc snep put -1 -1 [208,1,VQ,BTAwNDgxMjM0NTY3ODk=,]

VCards

Bash
# Flags: MB,ME 
# TNF: 2 (media type) 
# Type='text/vcard' 
# Payload: 'BEGIN:VCARD\nVERSION:2.1\nFN:Fire Fox\nTEL:0048123456789\nEMAIL:fire.fox@mozilla.org\nEND:VCARD' 
nfc snep put -1 -1 [192,2,dGV4dC92Y2FyZA,QkVHSU46VkNBUkQNC1ZFUlNJT046Mi4xDQpGTjpGaXJlIEZveA0KVEVMOjAwNDgxMjM0NTY3ODkNCkVNQUlMOmZpcmUuZm94QG1vemlsbGEub3JnDQpFTkQ6VkNBUkQ,]

Smart posters

Bash
# Simple smart poster with singe record (URI) pointing to http://www.kamituel.com (with abbreviation). 
# Flags: MB,ME,SR 
# TNF: 1 (well known) 
# Type: 'Sp' 
nfc snep put -1 -1 [208,1,U3A,0AENVQFrYW1pdHVlbC5jb20,] 

# Smart poster from: 
# https://android.googlesource.com/platform/development/+/85122d2605a22c8e7bcde868c2b7a7d8d744e613/apps/Tag/src/com/android/apps/tag/MockNdefMessages.java 
nfc snep put -1 -1 [208,1,U3A,kQEXVAJlbk5GQyBGb3J1bSBUeXBlIDQgVGFnUQEMVQFueHAuY29tL25mYw,] 

# Ultimate smart poster, with: 
# - action record (0) 
# - URI ('youtube.com') 
# - text record for english ('Best page ever! q#@') 
# - text record for polish ('ąćńó') 
# - small PNG icon 
nfc snep put -1 -1 [208,1,U3A,kQEMVQF5b3V0dWJlLmNvbREBF1QCZW5CZXN0IHBhZ2UgZXZlciEgIHEjQBEBC1QCcGzEhcSHxYTDsxEDAWFjdABSCVRpbWFnZS9wbmeJUE5HDQoaCgAAAA1JSERSAAAABAAAAAQIAgAAACaTCSkAAAAbSURBVAjXY/j//z8DDDDCOYyMjEwQCiqFrAwAJgsJAcPRmnsAAAAASUVORK5CYII,]
 

License

© 2016 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-us/docs/web/api/nfc_api/using_the_nfc_emulator

API Emulator Firefox OS Guide NFC