Search code examples
androidnfcrfidndefiso-15693

How to NDEF format NFC-Tags?


Good evening,

your page already helped a lot but I discovered problems when trying to format an NFC-tag and I couldn't find a topic related to NDEF-format a tag.

First I have to say that I'm new to the NFC technology.

I bought the following tag: http://www.ti.com/product/RI-I16-112A-03/description

This chip is factory tested and therefore every byte has been written to 0x00.

And now the problems start: I downloaded the application note to the tag: http://www.ti.com/lit/an/sloa166a/sloa166a.pdf and created an android app(source code below) to write the memory as shown in figure12. When I read out the content of the tag with the NXP-TagInfo app the memory looks as it should. The problem is still that it shows in the NXP-TagInfo that there is "No NFC data set storage" and furthermore it is discovered as NFC_TECH. Tell me if I'm wrong but this shows that the tag is definitely not NDEF-formatted.

For writing to the tag I did some research because it's not documented in the application note/datasheet and this is what confuses me most. Are there any documents that specify which byte flags can be used or which exist? I used 0x42 because I've seen it in this forum - if you want the source please ask for it.

My hardware: Sony Xperia S - Android 4.1.2 (Build-number: 6.2.B.1.96)
Compiled with Eclipse - target SDK= min SDK = API-level 16

And finally the code:

public class Nfc_activity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TextView textView = new TextView(this);
    String result = "";
    textView.setTextSize(40);

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

    byte[] block0 = new byte[] {0x42,0x21,(byte)0x00,(byte)0xe1,0x40,0x20,0x01};
    byte[] block1 = new byte[] {0x42,0x21,(byte)0x01,0x03,0x0b,(byte)0xd1,0x01};

    byte[] block2 = new byte[] {0x42,0x21,(byte)0x02,0x07,0x55,0x01,0x74};
    byte[] block3 = new byte[] {0x42,0x21,(byte)0x03,0x69,0x2e,0x63,0x6f};
    byte[] block4 = new byte[] {0x42,0x21,(byte)0x04,0x6d,(byte)0xfe,(byte)0x00,(byte)0x00};

    for(int i=0; i<receivedTag.getId().length; i++) {
        result+= Integer.toHexString(receivedTag.getId()[i]&0xff)+':';
    }


    textView.setText(result);
    setContentView(textView);

    NfcV nvcv = NfcV.get(receivedTag);

    try {
        nvcv.connect();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        nvcv.transceive(block0);
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }

    try {
        nvcv.transceive(block1);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    try {
        nvcv.transceive(block2);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        nvcv.transceive(block3);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        nvcv.transceive(block4);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    try {
        nvcv.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


EDIT: and here you can see the taginfo by NXP:

<?xml version="1.0" encoding="UTF-8"?>
<scan>
    <version>3.0</version>
    <date>2014-09-20 14:19:38</date>
    <title>Texas Instruments Tag-it HF-I Plus (inlay) tag</title>
    <uid nxp="false">3C:A7:4C:2B:00:00:07:E0</uid>
    <hasndef>false</hasndef>
    <section>
        <subsection title="IC manufacturer">
            <block type="text">
    <content>Texas Instruments</content>
</block>
        </subsection>
        <subsection title="IC type">
            <block type="text">
    <content>Tag-it HF-I Plus (inlay)</content>
</block>
        </subsection>
    </section>
    <section>
        <subsection title="No NFC data set storage">
            <block type="text">
    <content></content>
</block>
        </subsection>
    </section>
    <section>
        <subsection title="Memory size">
            <block type="text">
    <content>256 bytes
► 64 blocks, with 4 bytes per block</content>
</block>
        </subsection>
        <subsection title="IC detailed information">
            <block type="text">
    <content>Supported read commands:
► Single Block Read
► Multiple Block Read
► Get System Information
AFI supported
DSFID supported
IC reference value: 0x8B</content>
</block>
        </subsection>
    </section>
    <section>
        <subsection title="Technologies supported">
            <block type="text">
    <content>ISO/IEC 15693-3 compatible
ISO/IEC 15693-2 compatible</content>
</block>
        </subsection>
        <subsection title="Android technology information">
            <block type="text">
    <content>Tag description:
► TAG: Tech [android.nfc.tech.NfcV]
android.nfc.tech.NfcV
► Maximum transceive length: 253 bytes
<hexoutput>MIFARE Classic support present in Android</hexoutput></content>
</block>
        </subsection>
        <subsection title="Detailed protocol information">
            <block type="text">
    <content>ID: E0:07:00:00:2B:4C:A7:3C
AFI: 0x00
DSFID: 0x00</content>
</block>
        </subsection>
        <subsection title="Memory content">
            <block>
    <address>0</address>
    <data access=".">E1 40 20 01</data>
</block>
<block>
    <address>1</address>
    <data access=".">03 0B D1 01</data>
</block>
<block>
    <address>2</address>
    <data access=".">07 55 01 74</data>
</block>
<block>
    <address>3</address>
    <data access=".">69 2E 63 6F</data>
</block>
<block>
    <address>4</address>
    <data access=".">6D FE 00 00</data>
</block>
<block>
    <address>5</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>6</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>7</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>8</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>9</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>10</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>11</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>12</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>13</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>14</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>15</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>16</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>17</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>18</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>19</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>20</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>21</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>22</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>23</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>24</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>25</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>26</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>27</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>28</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>29</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>30</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>31</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>32</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>33</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>34</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>35</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>36</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>37</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>38</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>39</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>40</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>41</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>42</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>43</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>44</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>45</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>46</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>47</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>48</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>49</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>50</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>51</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>52</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>53</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>54</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>55</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>56</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>57</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>58</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>59</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>60</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>61</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>62</address>
    <data access=".">00 00 00 00</data>
</block>
<block>
    <address>63</address>
    <data access=".">00 00 00 00</data>
</block>
<block type="text">
    <content>
  x:user locked, *:factory locked, .:unlocked</content>
</block>
        </subsection>
    </section>
</scan>

Thank you for your responses.
Michael


Solution

  • The use of NfcV (ISO/IEC 15693) tags as NDEF tags is still not standardized. Hence, device manufacturers have to integrate support for the proprietary definitions of tag manufacturers (meanwhile they are similar/identical in most parts) into their Android versions.

    The device you are using (in combination with that Android version) does not1 have support for NDEF on NfcV tags. Therefore, you can't format the tag in a way that the NDEF message will be detected by your Android device.


    1) Actually that's not entirely true. This device is likely to support NDEF on NXP's ICODE tags (using the exact same format that you used on the TI tag). Unfortunately, that support was limited to NXP tags by testing if the manufacturer indication in the tag serial number is equal to 0x04 (= NXP).