There is always a clue – digging into NFC issues (Part 2)

Case Studies & Success Stories

In my previous post, I began telling the story of a strange NFC issue I encountered during – of all things –a presentation by John Murray and myself at BlackBerry® DevCon Europe about developing NFC-enabled apps. As it turned out, an NFC tag on a flyer in the presentation room wasn’t scanning properly. What could be the issue?

Our first task was to establish whether or not we could read the content of the tags any way at all and if so, to determine just what that content was.

Now, an NFC tag is a smart card and it responds to ISO 7816-4 APDUs, so it’s possible to work with it at a lower level than would be the case when using the BlackBerry NDEFMessageListener Java® interface – which is how we’d normally seek to read an NFC tag from a BlackBerry® smartphone application. As such, armed with the NFC Forum specifications for NDEF tags types 1-4 in one hand, the ISO 7816-4 specs in the other, and a contactless card reader in errrrr…the other, we set to work.

Our investigation proceeded on two fronts: John had been looking at a Python API for smart card developers called “pyscard” for a while and thought we could do something with that. We also contacted our own NFC product development team for advice, and they provided a BlackBerry smartphone app that they use to dump the content of tags to the device screen.

While sitting in the hotel bar drinking coffee and huddled around my laptop, it wasn’t long before John and I had a Python script running which was able to dump and decode the content of the tag. Through trial and error, we determined that we were dealing with a Type 2, tag and the decoded data produced by our script agreed with the data produced by the app our development team had provided. On examining the details carefully, we could see the problem with the tags as plain as day. Here’s part of what our script produced. Can you see the issue?

NDEF data:

TNF : 3 RFC 3986 ABSOLUTE URI
Type Length : 1
MB (Message Begin) : 1
ME (Message End) : 1
CF (Chunk Flag) : 0
SR (Short Record) : 1
IL (ID Length) : 0
Payload Length (SR): 34
Type : U
Payload (hex) : 68 74 74 70 3A 2F 2F 6F 6E 2D 74 61 70 2E 6E 65 74 3F 74 3D 30 69 38
34 76 69 65 71 38 7A 65 73 31 6E

The problem is that there’s a mismatch between the value provided for TNF (Type Name Format) and the data in the Type field.

TNF=0x03 means the tag contains an “absolute URI” as defined in RFC 3986. When this value is specified, then the Type field should contain a valid URI and the payload should be empty. As we can see, however, the Type field contains “U” in this case.

Of the other values which TNF could take, a value of 0x01 means the tag contains an “NFC Well Known Type”. Well known types are pre-defined record types and formats which the NFC Forum devised to support common use cases. When TNF=0x01, the Type field contains a short code which indicates which of those well known types the payload represents. Values include “Sp” for smart poster, “T” for Text and “U” for URI. So as you can see, there are two ways of encoding a URI; either with TNF=0x03 and an empty Type field or with TNF=0x01 and Type=”U”. Clearly whatever tool was used to write the tags on the flyers has a bug, since these two distinct cases seem to have been mixed up so that we have the invalid combination of TNF=0x03 and Type=’U’.

So, the mystery of the unreadable tag was solved! Hopefully this account provides some insight into a real-world issue and the activities involved in investigating such a problem.

Have fun with NFC!

About mdwrim

My name’s Martin Woolley and I work in BlackBerry's Developer Relations team as a Senior Application Development Consultant. I’ve been with BlackBerry since 2009 but have worked in software development in various capacities for 30 years in a whole range of industry sectors and on numerous computing platforms small and large. These days I specialise in areas such as Bluetooth Low Energy, NFC, Internet of Things (Iot) and wearable technologies amongst other things.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus