Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read data from NFC tag (IsoDep)

I am newbie in Android NFC API.

Currently, I have a NFC tag, I am making an Android app to read data from it. My simple App is launched when my phone get closer enough to the NFC Tag. But I have no idea how to read the data inside the NFC Tag. The tag uses IsoDep technology.

My current code:

@Override
protected void onResume (){
    super.onResume();

    Intent intent = getIntent();
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    IsoDep isoDep = IsoDep.get(tag);

    // How to read data from IsoDep instance?

I googled on internet, I notice people are sending commands to IsoDep to get response from NFC Tag, I suppose from the response, we can parse the data in the tag, I saw people doing this:

 //What is the 'command' ? How to define the command?
 //e.g.:
 byte command = (byte) 0x6A
 isoDep.transceive(command)

But, the command is just a byte, as a newbie, it is too difficult to understand what is happening. I have no idea how to define the command to read data? Anyone can explain to me? or is there a document I can learn about the command?

Generally, I need some guidance on how to define commands & how to parse data from response, I would like to read the data stored in the Tag & show the data in String format in UI element (e.g. TextView).

*AND***

I have no problem with those configurations(e.g. AnroidManifest.xml), please don't guide me on how to configure :)

like image 960
Mellon Avatar asked May 29 '13 13:05

Mellon


People also ask

How do I read data on my NFC card?

To read the NFC tag, the app needs to register for handling ACTION_NDEF_DISCOVERED intent. Registering this intent will let your app handle any NFC tag that is tapped to the Android device. If you wish to handle only those tags that belong to your application then you can add a filter.

What is IsoDep NFC?

android.nfc.tech.IsoDep. Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a Tag . Acquire an IsoDep object using get(Tag) . The primary ISO-DEP I/O operation is transceive(byte[]) . Applications must implement their own protocol stack on top of transceive(byte[]) .

Can you emulate an NFC tag?

With few clicks you can emulate NFC NDEF formatted text tag, URL or Android Application without spending any money buying NFC hardware. Please be sure that your NFC option is on before using the application.


1 Answers

IsoDep allows you to communicate over a ISO-14443-4 connection with the transceive operation. Over this protocol application data units (APDUs) are exchanged. The format is specified, you find a description on Wikipedia.

For exaple, to select an application on a smart card with a particular application identifier (AID) you would execute the following APDU command. The result simply indicates ok (9000) or an error.

    byte[] SELECT = { 
        (byte) 0x00, // CLA Class           
        (byte) 0xA4, // INS Instruction     
        (byte) 0x04, // P1  Parameter 1
        (byte) 0x00, // P2  Parameter 2
        (byte) 0x0A, // Length
        0x63,0x64,0x63,0x00,0x00,0x00,0x00,0x32,0x32,0x31 // AID
    };

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    IsoDep tag = IsoDep.get(tagFromIntent);

    tag.connect();
    byte[] result = tag.transceive(SELECT);
    if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
        throw new IOException("could not select applet");

After the application has been selected, you can execute application specific commands. The programs are typically written in JavaCard which follows the GlobalPlatorm spec. The following example executes on the above selected application the method 4 (0x04) which returns a byte array of at most 11 bytes. This result is then converted to a string.

    byte[] GET_STRING = { 
        (byte) 0x80, // CLA Class        
        0x04, // INS Instruction
        0x00, // P1  Parameter 1
        0x00, // P2  Parameter 2
        0x10  // LE  maximal number of bytes expected in result
    };

    result = tag.transceive(GET_STRING);
    int len = result.length;
    if (!(result[len-2]==(byte)0x90&&result[len-1]==(byte) 0x00))
       throw new RuntimeException("could not retrieve msisdn");

    byte[] data = new byte[len-2];
    System.arraycopy(result, 0, data, 0, len-2);
    String str = new String(data).trim();

    tag.close();
like image 169
Dominik Avatar answered Oct 11 '22 19:10

Dominik