Help us understand the problem. What is going on with this article?

【NFC】NDEFについて理解する

More than 1 year has passed since last update.

NDEF(NFC Data Exchange Format)についてまとめる機会があったのでその忘備録として

NDEFとはNFCを介してFeliCaやMIFARE、さらにiOS11にて提供が開始されるCore NFCなどへデータを読み書きするデータフォーマットを指す。

殆どの場合はライブラリなどを通じてデータの読み書きを行うがNDEFそのものに触れる機会があったのでNDEFとはどういう構造なのかをまとめていこうと思う。

公式のスペックはこちら。
http://nfc-forum.org/our-work/specifications-and-application-documents/specifications/nfc-forum-technical-specifications/

NDEFの構造を理解する

NDEF Message編

NDEFは1つのNDEF Messageと呼ばれるコンテナに、1~n個のNDEF Recordを含む。
このNDEF Record 1つに対してURLやテキストなどのデータを記録していく。

実装する際、このNDEF Messageを取り扱うか(NDEF Recordのみで良い場合等)は実装する環境に依存するので、この項目を無視することができるかもしれない…。

NEDFはデータ構造においてTLV方式を採用している。Tag Length Valueの3つ組で、Tagの部分にデータ型を指定し、Length部分にOctet長を、Valueのところに実際の値をいれるというデータ構造。

無題.png

NFC対応のICまたは機器(以下"タグ"と表記)に書き込みを行う場合、NDEF Messageの総容量がタグのPAYLOADの容量を超えてはならない。
例えば、こちらのタグであれば144Byte以内に収めなければならない。

よほど大容量の記録が行えるタグを除き、基本は1つのタグに1つのNDEF Recordで精一杯だと思う。

NDEF Messageのデータ構造は下図のとおりに表される。(NFC Forum Type 2 Tagの場合)
無題.png

1バイト目にNDEFであることを示す識別子0x03を指定し、2バイト目にNDEF Recordの容量(単位:バイト)を符号なし8bit整数で、そして3バイト目以降にNDEF Recordを記録する。

ちなみに、識別子はNFC Forum Type 2 Tagの場合だと以下が存在する。

識別子 名称 説明
0x00 NULL TLV NULLです。特になし。メモリ領域の調整用
0x01 Lock Control TLV ロック対象のビットを設定する。
0x02 Memory Control TLV 予約されたメモリ領域を識別する。
0x03 NDEF Message TLV NDEF Messageのコンテナ
0xfd Proprietary TLV 専有情報にタグを付ける。
0xfe Terminator TLV 終端コード。データの終りを示す。

NDEF Record編

NDEF Recordは複数の設定情報を含んだHEADER領域と本体データを含んだPAYLOAD領域が存在する。

NDEF Recordのデータ構造を下図に表記する。青がHEADERや終端指定コード、オレンジがPAYLOADを示す。

無題.png

各要素の説明がこちら

要素 説明
MB (Message Begin) NDEF Messageの始まりを意味するフラグ
ME (Message End) NDEF Messageの終わりを意味するフラグ
CF (Chunked Flag) 分割されたNDEF Messageの一部を示すフラグ
SR (Short Flag) 255Byte以下のRecordを意味するフラグ。有効にするとPAYLOAD LENGTHが4Byteから1Byteになる。
IL (ID Length) IDが設定されていることを示す。無効にするとID LENGTHとIDを省略することができる。
TNF (Type Name Format) TYPEフィールドの種類を示す。3bitで指定する。詳細は別図参照。
TYPE LENGTH TYPEフィールドの長さを符号なし8bit整数で指定する。この値でTYPEフィールドの容量が決定する。
PAYLOAD LENGTH SRの値に応じて長さが変化する。PAYLOADフィールドの長さを符号なしビックエンディアンで指定する。この値でPAYLOADフィールドの容量が決定する。
ID LENGTH ILの値に応じて省略されることがある。IDフィールドの長さを符号なし8bit整数で指定する。この値でIDフィールドの容量が決定する。
TYPE TYPE LENGTHに応じて長さが変化する。TNFの値によって設定値が変わる。
ID ILの値に応じて省略されることがある。ID LENGTHに応じて長さが変化する。
PAYLOAD PAYLOAD LENGTHに応じて長さが変化する。TNFとTYPEによって内容が変わる。

TNFの設定内容はこちら

説明
0x00 Empty
0x01 NFC Forun well-known-type
0x02 Media-type as define in RFC2046
0x03 Absolute URI as define in RFC3986
0x04 NFC Forum external type
0x05 Unknown
0x06 Unchanged
0x07 Recerved

TNFとPAYLOAD

TNFの値に応じて、TYPEで設定できる内容とPAYLOAD内のデータ構造が変化する。
今回はNFC Forun well-known-typeを例として取り上げる。

NFC Forun well-known-typeではTypeとPAYLOADにRTD(Record Type Difinition)が使用される。
RTDで使用できる種類で代表的なものはこちら。

分類 TYPE
Text T
URI U
SmartPoster Sp

ここで指定した内容に応じて、端末で読み取ったときの挙動を制御することができる。
例えばURIであればかざしたときにブラウザが立ち上がるようになる。

RTDの詳細や使用方法は冒頭で紹介した公式スペックを参照してほしい。

本ページではURIを例に挙げる。

NFC URI Record Type Definition

まず、PAYLOAD内はこのようなデータ構造となる。

無題.png

各要素の説明がこちら

要素 説明
Identifier code URIの識別子コードを指定する。識別子とコードの対応表は別表参照。
URI field URIをUTF-8で記述する。識別子で指定した分は省略する。

Identifier codeの代表例がこちら。その他のコードはNFC URI Record Type Definition Technical Specificationを参照のこと。

Identifier code プロトコル
0x00 N/A
0x01 http://www.
0x02 https://www.
0x03 http://
0x04 https://
0x05 tel:
0x06 mailto:

ここで注意すべきことは、このURIのPAYLOADはIdentifier codeで1バイト使用している。
つまり、PAYLOAD LENGTHにはURIフィールドのバイト数+1バイトを指定しなければならない。

NDEFを構築してみる

ここまでの内容を踏まえて、「 http://qiita.com/ 」にアクセスできるNDEFを構築してみる。

無題.png

※タグに書き込む際は終端コードが必須となっている。

この図よりタグに書き込むデータは、

03 0f d1 01
0b 55 03 71
69 69 74 61
2e 63 6f 6d
2f fe

となる。(もしNDEF Recordのみで良い場合は、先頭2バイトと最終1バイトを除けば良い)

参考

避けては通れないバイナリ地獄 - NDEFってなんだろう -

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした