Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

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 に実際の値をいれるというデータ構造となっています。

NDEF Messageのデータ構造概要.png

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

よほど大容量の記録が行えるタグを除き、現実的には1つのタグに1つの NDEF Record で精一杯だと思います。

NDEF Messageのデータ構造は下図のとおりに表される。(NFC Forum Type 2 Tagの場合)
NDEF Messageのデータ構造.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 を示します。

NDEF Record のデータ構造.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 が設定されていることを示します。無効(0指定)にすると ID LENGTH と ID を省略することができます。
TNF (Type Name Format) TYPE フィールドの種類を示します。3bit で指定します。(コードの内容は後述)
TYPE LENGTH TYPE フィールドの長さを符号なし 8bit 整数で指定します。この値で TYPE フィールドで格納できる容量が決まります。
PAYLOAD LENGTH 前述の SR の値に応じて使用できる桁数が変わります。PAYLOAD フィールドの長さを符号なしビックエンディアンで指定します。この値でPAYLOADフィールドの容量が決定する。
ID LENGTH IL の値が 1 の場合は省略されます。ID フィールドの長さを符号なし8bit整数で指定します。この値で ID フィールドの格納できる容量が決まります。
TYPE TYPE LENGTH に応じて使用できる桁数が変わります。TNF の値によって設定できる内容が変わります。
ID IL の値が 1 の場合は省略されます。ID を記録できます。ID LENGTH に応じて使用できる桁数が変わります。
PAYLOAD PAYLOAD LENGTH に応じて使用できる桁数が変わります。TNF と TYPE によって内容が変わります。(後述)

TNFの設定内容はこちら

説明
0x00 Empty
0x01 NFC Forum 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 Reserved

TNF と PAYLOAD

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

NFC Forum 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 内はこのようなデータ構造となります。

NDEF Record PAYLOAD のデータ構.png

各要素の説明がこちら

要素 説明
Identifier code URI のプロトコル識別子を指定します。識別子とプロトコルの対応表は後述します。
URI field URI 本文を UTF-8 で記録します。Identifier code で指定した分は省略するようにします。

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バイトを使用しています。
つまり、前述で紹介した NDEF Record の PAYLOAD LENGTH には URI field の容量に 1バイトを加えて指定する必要があります。

NDEF を構築してみる

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

NDEF例.png
(2020/09/30 追記) 図の 3Byte にて「INF」を表記がありますが正しくは「TNF」です。

※ もし、タグに NDEF Message ごと書き込む場合は末尾に終端コード(0xfe)が必須となります。

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

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

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

参考

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

shimosyan
ビジネスチャットツールに携わる会社でコーポレートエンジニアとして働いています。
https://micmnis.net/
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