Search code examples
formatnfcndef

Interpreting Mangled NDEF Header


I was modifying a piece of PC software I wrote to read multiple NDEF records from an NFC tag. However, one of the tags I have contains a record with what seems to be a mangled NDEF header. It's the last record of 6, the other 5 coming in as expected. I've listed it below. For simplicity, all values are listed in hexidecimal and the payload has been truncated.

Record #6

Header:     42
Type Length:    03
Random Bytes:   00 00 00
Payload Length: 2C (44)
Rec. Type:      6E 2F 70 (n/p)
Payload:        **

As you can see, 3 random zero bytes are shoved between what should be the Type Length and Payload Length. I have double checked the Length Field in the TLV and found that it accounts for these 3 bytes. I'm not getting any data truncated off of the end of the TLV due to these added bytes.

I decided to do a sanity check with NXP's TagInfo app to make sure I wasn't just reading the data incorrectly. Checking the data dump from a full scan, I saw that the data does in fact match. I've listed the memory scan below. Only the relevant data points are listed and the payload is, again, truncated.

Memory Dump

addr    data
...
[30]    -- -- 42 03 |--B.|
[31]    00 00 00 2C |...,|
[32]    6E 2F 70 ** |n/p*|
[33]    ** ** ** ** |****|
...                  
[3D]    ** ** ** FE |***.|
...

We thought that maybe this was an issue with padding given that, in this case, the Terminator TLV appears at the end of page 0x3D. However, due to the nature of previous records, this is not always the case. Sometimes, the Terminator TLV shows up in the middle of a page.

However, the strange thing is that, in the same TagInfo app on the NDEF page, it reports the NDEF message as follows.

NDEF Message

...
[A8] 52 03 2C 6E 2F 70 ** ** |R.,n/p**|
[B0] ** ** ** ** ** ** ** ** |********|
...
[D8] ** **                   |**      |
...

Somehow, the software has not only removed the 3 extra bytes, but has correctly set the SR bit in the NDEF header. I have double checked this with another NFC app on Android and have confirmed that the other app is able to read the NDEF Message this way as well.

My question is, is there a reason or logic behind how the app is able to correct not only the the added bytes, but also the NDEF Header? I'm not sure if this is Android doing the correction or something else deeper in the NDEF message structure. Either way, I'm looking at the right way to make the correction while not effecting how I read the other 5 records held within this tag.


Solution

  • Those bytes are also part of the payload length

    If the record does not have the SR (short record) bit set, then the payload length is 4 bytes long rather than one byte.

    https://learn.adafruit.com/adafruit-pn532-rfid-nfc/ndef#payload-length-9-9

    The first byte is 0x42, which in binary is 0100 0010. If we separate that out, we can see that the record has the ME (or 'Message End') bit set, as well as a TNF ('Type Name Format') of 0x02 - 'MIME Media Record'. The SR bit is bit 4, which is zero in this case.

    That's also why they disappear in the version corrected by the TagInfo app - it has set the SR (which is why the header jumps to 0x52) and removed the unnecessary bytes.