Monday, 9 September 2013

NFC

Introduction

NFC (near field communication) is a standards-based, short-range wireless connectivity technology that enables simple and intuitive two-way interactions between electronic devices. It is very convenient to touch and communicate between two NFC devices. For example, with smartphone-integrated NFC technology, you can easily touch your phone to purchase items, share business cards, download discount coupons and so on. You will see many NFC-based new usages will be developed in the future.
This paper introduces NFC-based technology and usage modes in the current market. Then it also describes how to use NFC in the android applications. Finally, it presents two case studies for how to develop the NFC-based reader/writer applications.

NFC Technology Architecture

NFC is based on RFID technology at 13.56 MHz, with a typical operating distance up to 10 cm. The data exchange rate is up to 424 kilobits/s. Compared to other communication technology, the biggest advantage of NFC is it is quick and easy to use. The following graph compares NFC to other communication technologies.
Figure 1: Comparison of short-range communication technologies

NFC technology has three modes: NFC card emulation mode, peer-to-peer mode, and reader/writer mode, shown in the following graph.
Figure 2: NFC Protocol Families

In card emulation mode, NFC simulates an RFID integrated circuit (IC) card, with a security module, which allows users to make purchases safely. In peer–to-peer mode, you can share information, such as business cards, between different NFC devices via an NFC connection. You can also set up a WiFi* or Bluetooth* connection quickly through the NFC connection and transfer big files through the WiFi or Bluetooth connection. In reader/writer mode, you can use NFC-enabled devices to read NFC tags and launch smart tasks.
Each mode is discussed in more detail below.

NFC Card Emulation Mode

An NFC module usually consists of two parts: an NFC controller and a secure element (SE). The NFC controller is responsible for communication. The SE is responsible for encrypting and decrypting sensitive data.
Figure 3: NFC Hardware Components

The SE connects to the NFC controller via SWP (Single Wire Protocol) or DCLB (Digital Contactless Bridge) bus. NFC standards define a logical interface between the host and the controller allowing them to communicate via the RF-field. A built-in app or a small OS implements the SE, which is responsible for the encrypting and decrypting the sensitive data.
The three solutions to implement the SE are:
  • Embedded in SIM card
  • Embedded in SD card
  • Embedded in NFC Chip
Figure 4: Three NFC SE Solutions
The telecom operators, such as CMCC (China Mobile Communication Corporation), Vodafone and AT&T, usually prefer the SIM card-based solution, who are encouraging their users to replace old SIM cards with new NFC-enabled ones for free.

NFC Peer-to peer Mode

Two devices with NFC can communicate directly and easily to share small files such as business cards. Two NFC-enabled devices can also share configured .xml files with each other and establish Bluetooth/WiFi connection to share big files. In this mode, no SE module is needed.

NFC Reader /Writer Mode

In this mode, the NFC host can read/write NFC tags. A good example is to read useful
information from smart posters. Users can access links to view the advertisements and download discount coupons.
Figure 5: NFC Reader/Writer Mode

Introduction to Android NFC development

Android supports NFC with two packages: android.nfc and android.nfc.tech.
The main classes in the android.nfc package are:

NfcManager: Android devices can be used to manage all indicated NFC adapters, but because most Android devices support only one NFC adapter, NfcManager is generally called directly with getDefaultAdapter to get the specific phone adapter.
NfcAdapter: It works as an NFC agent, which is similar to the network adapter installed in the computer,by which cellphones access the NFC hardware to initiate NFC communication.
NDEF: NFC standards define a common data format called NFC Data Exchange Format (NDEF), which can store and transport various kinds of items, ranging from any MIME-typed object to ultra-short RTD-documents, such as URLs. NdefMessage and NdefRecord are two kinds of NDEF for the NFC forum defined data formats, which will be used in the sample code.
Tag: Android defined it represents a passive object like labels, cards, and so on. When the device detects a tag, Android will create a tag object, then put it in the Intent object, lastly send it to the appropriate Activity.
The android.nfc.tech package also contains many important sub-classes. These sub-classes provide access to a tag technology's features, which contain read and write operations. Depending on the type of technology used, these classes are divided into different categories, such as: NfcA, NfcB, NfcF, MifareClassic, and so on.
When a phone has NFC turned on, and after detection of a TAG, the TAG distribution system will automatically create a package of NFC TAG information of intent. If the phone has more than one application that can deal with this intent, a pop-up box will ask the user to choose which TAG activity to do. The TAG distribution system defines three types of intent. It is arranged in descending order of priority:
NDEF_DISCOVERED, TECH_DISCOVERED, TAG_DISCOVERED
Here we use the action intent-filter type to handle all types from TECH_DISCOVERED to ACTION_TECH_DISCOVERED. The file nfc_tech_filter.xml is used for the types defined in the file TAG. For details, see the Android documentation. The figure below shows the Activity of the matching process when the phone detects a TAG .
Figure 6: Process of NFC Tag Detected

Case study: Develop an NFC-based reader/writer application

The following demo shows the reader/writer function for the NFC tag. Before you can access a device's NFC hardware and properly handle NFC intents, declare these items in your AndroidManifest.xml file:
1<uses-permission android:name="android.permission.NFC" />
The minimum SDK version that your application must support is level 10, so declare these items in your AndroidManifest.xml file:
1<uses-sdk android:minSdkVersion="10"/>
2
3In the onCreate function,you can apply the NfcAdapter:
4
5public void onCreate(Bundle savedInstanceState) {
6……
7adapter = NfcAdapter.getDefaultAdapter(this);
8……
9
The following Intent call back shows the reader function. If the system broadcast Intent equals NfcAdapter.ACTION_TAG_DISCOVERED , then you can read the information in the tag and show it.
01@Override
02    protected void onNewIntent(Intent intent){
03        if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
04        mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  // get the detected tag
05        Parcelable[] msgs =
06intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
07            NdefRecord firstRecord = ((NdefMessage)msgs[0]).getRecords()[0];
08            byte[] payload = firstRecord.getPayload();
09            int payloadLength = payload.length;
10            int langLength = payload[0];
11            int textLength = payloadLength - langLength - 1;
12            byte[] text = new byte[textLength];
13            System.arraycopy(payload, 1+langLength, text, 0, textLength);
14            Toast.makeText(this, this.getString(R.string.ok_detection)+new String(text), Toast.LENGTH_LONG).show();
15                    }
16    }
The following code shows the writer function. Before you can determine the value of mytag, you must know whether there is a tag detected or not, then write the information to mytag.
01If (mytag==Null){
02    ……
03}
04else{
05……
06write(message.getText().toString(),mytag);
07……
08}
09    private void write(String text, Tag tag) throws IOException, FormatException {
10        NdefRecord[] records = { createRecord(text) };
11        NdefMessage  message = new NdefMessage(records);
12// Get an instance of Ndef for the tag.
13        Ndef ndef = Ndef.get(tag); // Enable I/O
14        ndef.connect(); // Write the message
15        ndef.writeNdefMessage(message); // Close the connection
16        ndef.close();
17    }
Depending on the information read from the tag, you can do more operations, such as launch a smart task, access a web site, and so on.

Case study: Develop an NFC-based application that uses the MifareClassic Card

In this demo, we use the Mifare card for the data read test and use the card’s TAG type, MifareClassic. The MifareClassic card is commonly used in many scenarios, such as ID card,bus card and so on. The traditional MifareClassic card’s storage space is divided into 16 zones (Sector), each zone has four blocks (Block), and each block can store 16 bytes of data.
The last block in each district is called the Trailer, which is mainly used to store the local block key for reading and writing data. It has two keys: A and B, and each key length is 6 bytes, the default value of which is generally full-key FF or 0 by the MifareClassic.KEY_DEFAULT definition.
So when writing the Mifare card, you first need to have the correct key value (play a protective role), and the successful authentication must be done before a user can read and write data in the area.
01<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
02    package="org.reno"  
03    android:versionCode="1"  
04    android:versionName="1.0" >  
05    <uses-permission android:name="android.permission.NFC" />  
06    <uses-sdk android:minSdkVersion="14" />  
07    <uses-feature android:name="android.hardware.nfc" android:required="true" />  
08    <application  
09        android:icon="@drawable/ic_launcher"  
10        android:label="@string/app_name" >  
11        <activity  
12            android:name="org.reno.Beam"  
13            android:label="@string/app_name"  
14            android:launchMode="singleTop" >  
15            <intent-filter>  
16                <action android:name="android.intent.action.MAIN" />  
17    
18                <category android:name="android.intent.category.LAUNCHER" />  
19            </intent-filter>  
20            <intent-filter>  
21                <action android:name="android.nfc.action.TECH_DISCOVERED" />  
22            </intent-filter>  
23            <meta-data  
24                android:name="android.nfc.action.TECH_DISCOVERED"  
25                android:resource="@xml/nfc_tech_filter" />  
26        </activity
27    </application>  
28</manifest>  
res/xml/nfc_tech_filter.xml:
1<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
2    <tech-list>
3       <tech>android.nfc.tech.MifareClassic</tech>
4    </tech-list>
5</resources>
An example of how to read a MifareClassic card is as follows:
01private void processIntent(Intent intent) {   
02    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
03    for (String tech : tagFromIntent.getTechList()) {  
04        System.out.println(tech);  
05    }  
06    boolean auth = false;  
07    MifareClassic mfc = MifareClassic.get(tagFromIntent);  
08    try {  
09        String metaInfo = "";  
10        //Enable I/O operations to the tag from this TagTechnology object.  
11        mfc.connect();  
12        int type = mfc.getType();
13        int sectorCount = mfc.getSectorCount();  
14        String typeS = "";  
15        switch (type) {  
16        case MifareClassic.TYPE_CLASSIC:  
17            typeS = "TYPE_CLASSIC";  
18            break;  
19        case MifareClassic.TYPE_PLUS:  
20            typeS = "TYPE_PLUS";  
21            break;  
22        case MifareClassic.TYPE_PRO:  
23            typeS = "TYPE_PRO";  
24            break;  
25        case MifareClassic.TYPE_UNKNOWN:  
26            typeS = "TYPE_UNKNOWN";  
27            break;  
28        }  
29        metaInfo += "Card type:" + typeS + "n with" + sectorCount + " Sectorsn, "  
30                + mfc.getBlockCount() + " BlocksnStorage Space: " + mfc.getSize() + "Bn";  
31        for (int j = 0; j < sectorCount; j++) {  
32            //Authenticate a sector with key A.  
33            auth = mfc.authenticateSectorWithKeyA(j,  
34                    MifareClassic.KEY_DEFAULT);  
35            int bCount;  
36            int bIndex;  
37            if (auth) {  
38                metaInfo += "Sector " + j + ": Verified successfullyn";  
39                bCount = mfc.getBlockCountInSector(j);  
40                bIndex = mfc.sectorToBlock(j);  
41                for (int i = 0; i < bCount; i++) {  
42                    byte[] data = mfc.readBlock(bIndex);  
43                    metaInfo += "Block " + bIndex + " : "  
44                            + bytesToHexString(data) + "n";  
45                    bIndex++;  
46                }  
47            } else {  
48                metaInfo += "Sector " + j + ": Verified failuren";  
49            }  
50        }  
51        promt.setText(metaInfo);  
52    } catch (Exception e) {  
53        e.printStackTrace();  
54    }  
55}  

Summary

The smartphone equipped with NFC allow individuals to have everything they need at the tip of their fingers without lugging around ticket stubs or parking passes. The technology can even connect with friends to share information, play games, and transfer data. NFC strives to embrace both work and play, a crucial factor in creating its success and facilitating our lives in the future.

About the Author

Songyue Wang and Liang Zhang are application engineers in Intel Software and Service Group, and focus on mobile application enabling, including Android applications development and optimization for x86 devices, Web HTML5 application development.

NFC

NFC - Near Field Communication