2018年04月04日

電波法適合の NFC モジュールで安価な NFC タグを利用する

はてなブックマークに登録

はじめに

当ブログの記事「NFC タグで秘密情報を安全に携行する試み」では MIFARE Ultralight 準拠の NXP 製「NTAG21x」シリーズに目を向けました。そこでは市場で現在主流のこの NFC タグ製品の機能面での奥の深さを Android デバイスを使って試してみましたが、値段も安くすっかり気に入った NTAG21x を自作の装置でも利用したいと考えました。携帯端末の可搬性、据え置き型装置の拡張性、どちらも日常生活での NFC の実用性を支えている土台的な要素ですね。

NFC リーダ/ライタモジュール製品を探す

そんなわけでまずは電子工作向きの NFC リーダ/ライタモジュールを探すことから始めました。ネットを見渡してみると様々なものが出回っており、以下の製品などが目にとまりました。いずれもなかなか良さそうです。

国外のメーカーによるこれらのモジュールは個人でも簡単に購入することができます。一方、国内メーカーの製品情報を探したところでは、いくつもの企業が NFC リーダ/ライタモジュールの製造・販売を行ってはいるもののそのほとんどが法人向けの組み込み用であることを知りました。 その中で、私自身が今回調べた範囲では、2018年3月時点で個人が一般のディストリビュータから入手可能な国内製品はソニー株式会社様による「RC-S620/S」のみでした。もし他にも入手しやすい国内製品があればぜひご教示下さい。

さて、ここで気になるのがこれらの製品と電波法との関係です。

電波法と NFC モジュールとの関係について

ご承知のように、日本国内で「技適マーク」のない無線機を使用すると電波法違反となる可能性があり、外国製の機器を使いたい場合などにはこのことが最初に確認すべきポイントとなります。では、やはり電磁波を発生させる NFC リーダ/ライタは電波法においてどのように扱われているのでしょう。技適証明が必要なのか、それとも周囲への影響が微弱であるため特に規定されていないのか。この点について調べてみました。

まとめ

結論として、電波法には NFC リーダ/ライタに関する明確な規定があり、それに適合しない製品の日本国内での使用は NG であることを知りました。要点を整理してみます。

  • いわゆる技適証明は特定無線設備を対象とするものだが、NFC リーダ/ライタは電波法において特定無線設備にはあたらず「高周波利用設備」に該当し、そこに含まれる「誘導式読み書き通信設備」に分類される
    • つまり NFC リーダ/ライタは技適マークとは関係がない
  • 誘導式読み書き通信設備は、その電界強度が所定の条件を満たしている場合、または、総務大臣による型式指定を受けている場合には個別の許可なしに設置することができる
    • 型式指定の申請者は日本人または日本国内の法人でありかつ製造業者または輸入業者でなければならない
  • 電界強度条件との整合性の確認にも型式指定を受けるにも適正な方法での性能試験が必須

詳細

型式指定表示の実例

手元にあるふたつの製品での型式指定表示と公式サイトからの引用を示します。前掲の RC-S620/S にもしっかり印刷されています。  ※クリックで大きく表示

RC-S620/S について

貴重な選択肢として

今回手元で調べた範囲では、日本の電波法に準じた型式指定表示のある国外メーカーの NFC モジュールは見当たりませんでした、また、「3mの距離において電界強度が500μV/m」などという性能情報を目にすることもありません。 そのため、いまの時点で手近な実験や電子工作を適法に行うためには入手が容易で電波法適合の RC-S620/S は貴重な選択肢ということになります。

個人的には、電波法の必然性と重要性を十分に理解・納得しながらも、一方で、とりわけ IoT 方面での国外メーカーによる国際的にメジャーな製品を公然と試すことのできないケースが発生することをもどかしく思うこともあります。手近な実験や試作のためにわざわざ電波暗室を借りたり渡航したりするわけにもいきませんしね。。 (^^;
さっそくスイッチサイエンス様のサイトから RC-S620/S を購入しました。 本来組み込み用途のこのモジュールの入出力端子は FFC コネクタで一般的な電子工作では何かと取り回しにくいのですが、同社オリジナルのブレークアウト基板と専用ケーブルのセットがあわせて販売されているためとても助かります。

利用者向けの公式リソース

利用者向けに以下のリソースが公式サイトで公開されています。各ダウンロードページに記載された規約・使用許諾契約の内容を十分に確認した上でこれらを利用します。

  • Sony Japan | FeliCa | 法人のお客様 | ダウンロード
    • RC-S620/S製品仕様書<簡易版>
    • RC-S620/Sコマンドリファレンスマニュアル<簡易版>
      規約
             :
      第3条(使用権)

      1. ソニーは、利用者に対して、利用者が対象文書を使用目的のために本ウェブサイトから複製することができる非独占的な権利を無償にて利用者に許諾します。
      2. 利用者は、対象文書の全部または一部を、さらに複製したり、これに対する修正、追加等の改変をすることはできません。また、対象文書およびその複製物を、第三者に頒布したり、ウェブサイトにアップロードするなどして第三者が取得可能な状態にしないものとします。
             :
  • Arduino向けRC-S620/S制御ライブラリの提供
    • 「Arduino向けRC-S620/S制御ライブラリ」ダウンロードページ
      RC-S620/S制御ライブラリ 使用許諾契約
             :
      第1条(総則)
       1.ソニーは、本規約に定める各条項に従い、本ソフトウェアおよび関連資料に関する非独占的かつ譲渡不能な次の権利(但し特許権は除く。以下「使用権」とします)を、お客様に許諾します。
        (1)お客様が、ソフトウェア使用者をして、本ソフトウェアおよび関連資料の全部もしくは一部を使用、複製、複写または改変してアプリケーションソフトウェアを開発する権利。 なお、本規約において、ソフトウェア使用者およびアプリケーションソフトウェアとは、それぞれ、次の意味を有します。
         .愁侫肇ΕД∋藩兌圈本ソフトウェアを入手頂いたお客様1名の方。
         ▲▲廛螢院璽轡腑鵐愁侫肇ΕД◆Д愁法疾夙鸚椰ICカードリーダ/ライター製品「RC-S620/S」を制御するためのソフトウェアプログラム。
        (2)お客様が、本項第1号に基づき開発されたアプリケーションソフトウェアを複製したうえ、ソースコード形式またはバイナリ形式にて、第三者に頒布する権利。
       2.お客様は、前項で定める場合を除き、本ソフトウェアおよび関連資料の全部もしくは一部を使用、複製、複写または改変してはならないものとします。
             :

公式リソースのカバーする範囲

このようにドキュメントに加えサンプルコードが公式に提供されていることは利用者にとってとても嬉しい配慮ですが、これらの参照・使用に際しては以下の事情をあらかじめ理解しておく必要があるでしょう。

  • RC-S620/S はあくまでも組み込み用製品であり本来の顧客は法人である
  • 各仕様書は冒頭のページの注釈のとおり「調査、試作および評価」を目的とする「簡易版」であり、「商用向け」の版は顧客が「正式に RC-S620/S を導入」する場合に提供される
  • 「製品仕様書<簡易版>」 1, 2 項に記載のあるように RC-S620/S は FeliCa に加え ISO/IEC 14443 (Type A, Type B) にも対応しているが、主眼はあくまでも前者である
  • 各仕様書およびサンプルコードは FeliCa まわりの一部の機能に特化した内容である

思いがけない援軍の存在

さて、冒頭で触れたように手元で実現したいのは MIFARE Ultralight NTAG21x へのアクセスです。RC-S620/S が ISO/IEC 14443 Type A(MIFARE)に対応していることは上記の通り仕様書に明記されているものの、公式のリソースではそのための具体的な方法や手順がわかりません。

まずそもそも MIFARE の近接を検知するにはどうすればいいのか。「Arduino向けRC-S620/S制御ライブラリ」の polling() 関数は FeliCa を検知するために「コマンドリファレンスマニュアル<簡易版>」に記載されている「InListPassiveTarget」というコマンドを呼び出しています。
ためしに「InListPassiveTarget ISO/IEC 14443 Type A」のキーワードで情報を検索したところ次の興味深い資料が目にとまりました。

PN532」は NXP による NFC モジュールです。この資料の中の InListPassiveTarget の記述箇所を探すと Page 115 (上図)にそのものずばりのコマンド説明がありました。

「RC-S620/Sコマンドリファレンスマニュアル<簡易版> Version 2.11」 Page 80 の InListPassiveTarget の説明と読み合わせてみると、ターゲットが FeliCa の場合のパラメータ説明は一致しており、さらに「簡易版」には記載されていない ISO/IEC 14443 Type A, B への対応方法を含め 7 ページに渡り詳しい説明が掲載されています。その他のコマンドについても同様で、CommunicateThruEx など RC-S620/S 側のみに存在するいくつかのコマンドはあるものの、全体としてはいわばスーパーセットのマニュアルのように見受けられました。実際にこのマニュアルに添って「Arduino向けRC-S620/S制御ライブラリ」の polling() 関数を以下の要領で書き換えてみると ISO/IEC 14443 Type A の近接を検知することができました。

FeliCa 対応のオリジナルコード

/* InListPassiveTarget */
memcpy(buf, "\xd4\x4a\x01\x01\x00\xff\xff\x00\x00", 9);
buf[5] = (uint8_t)((systemCode >> 8) & 0xff);
buf[6] = (uint8_t)((systemCode >> 0) & 0xff);

ret = rwCommand(buf, 9, response, &responseLen);

ISO/IEC 14443 Type A 用

ret = rwCommand((const uint8_t *)"\xd4\x4a\x01\x00", 4,
                 response, &responseLen);

このように、メーカーの異なる RC-S620/S と PN532 との間にコマンドレベルでの共通性がある理由は NFC フォーラム仕様のどこかにあるのかも知れませんが手元では今のところ該当する情報の特定に至っていません。 あるいは、両社がともに「デバイスやサービス間の新機能と互換性を実現するための規格策定」をミッションのひとつとする NFC フォーラムのコアメンバーであることに関係があるのかも知れません。いずれにせよ PN532 のマニュアルのおかげで先が見えてきました。

NTAG21x ネイティブコマンドの発行について

先般の記事では、NTAG21x のメモリアクセスに必要な次のよっつのネイティブコマンドを挙げました。

  • GET_VERSION
    NTAG 製品のバージョン,ストレージサイズ等を得る
  • READ
    所定のページアドレスから始まる 4 ページ分(16 バイト)のデータを得る
  • WRITE
    所定のページアドレスへ 1 ページ分(4 バイト)のデータを書き込む
  • PWD_AUTH
    パスワードで保護された領域へのアクセス要求に先行してパスワード認証を要求する

これらを RC-S620/S 経由でターゲットへ送出してやれば NTAG21x のメモリを自由に操作できるはずです。

RC-S620/S にはこのようにターゲットとする PICC 固有のコマンドを発行するための CommunicateThruEX コマンドが用意されています。ただし、「コマンドリファレンスマニュアル<簡易版> Version 2.11」 Page 71 の「本コマンドは 212/424 kbps の RF パケットの送受信を行います」の記述のとおりこのコマンドは FeliCa 専用で、通信速度 106 kbps の ISO/IEC 14443 向けには使えません。

一方、「PN532 User Manual Rev.02」にはそれと同様の機能で汎用性のある InDataExchange, InCommunicateThru のふたつのコマンドの情報が掲載されています。同マニュアルの InListPassiveTarget コマンドのページには MaxTg フィールドについて「The PN532 is capable of handling 2 targets maximum at once, so this field should not exceed 0x02.」と記述されており、InDataExchange においては target (Tg) を明示的に指定するのに対し、InCommunicateThruでは「it is assumed that a target has been first activated.」という違いがあります。

  • PN532 User Manual Rev.02 - 7.3.5 InListPassiveTarget
  • PN532 User Manual Rev.02 - 7.3.8 InDataExchange
  • PN532 User Manual Rev.02 - 7.3.9 InCommunicateThru

ふたたび RC-S620/S 側に目を向けると、「コマンドリファレンスマニュアル<簡易版> Version 2.11」 Page 50 の InListPassiveTarget コマンド説明で MaxTg フィールドについては「Target ID を取得する Target の最大数. 01h を指定してください」と記述されています。つまりこの部分の仕様は PN532 と異なる様子であり、この要素の影響を受ける InDataExchange, InCommunicateThru の挙動は、両コマンドの存在有無の確認を含め RC-S620/S 上で実際に試してみる必要がありそうです。

前掲のよっつの NTAG21x ネイティブコマンドの発行を RC-S620/S 経由で試みたところ、InListPassiveTarget によるターゲットの捕捉後に以下の組み合わせが有効であることを手元で確認しました。また、この結果から RC-S620/S においても InDataExchange, InCommunicateThru の両コマンドを利用可能であることが明らかになりました。

  • NTAG: GET_VERSION コマンド (0x60)
    • InCommunicateThru コマンド(0x42)経由での発行のみ有効
      • rwCommand((const uint8_t*)"\xd4\x42\x60", 3, response, &responseLen); の要領
  • NTAG: READ コマンド (0x30)
    • InDataExchange コマンド(0x40)、InCommunicateThru コマンド(0x42)いずれを経由しても有効
      • rwCommand((const uint8_t*)"\xd4\x40\x01\x30[開始ページ番号 1byte]", 5, response, &responseLen); の要領
      • rwCommand((const uint8_t*)"\xd4\x42\x30[開始ページ番号 1byte]", 4, response, &responseLen); の要領
  • NTAG: WRITE コマンド (0xA2)
    • InDataExchange コマンド(0x40)経由での発行のみ有効
      • rwCommand((const uint8_t*)"\xd4\x40\x01\xA2[対象ページ番号 1byte][書き込みデータ 4byte]", 9, response, &responseLen); の要領
  • NTAG: PWD_AUTH コマンド (0x1B)
    • InCommunicateThru コマンド(0x42)経由での発行のみ有効
      • rwCommand((const uint8_t*)"\xd4\x42\x1b[パスワード 4byte]", 7, response, &responseLen); の要領

ライブラリへの加筆とテストプログラムの作成

ここまでの経緯でおおむね材料が揃ったところで、「Arduino向けRC-S620/S制御ライブラリ」へ自分のほしかった機能を追加し、あわせて動作確認用にテストプログラムの作成を行います。

想定した内容

以下の内容を想定しました。NDEF メッセージの解釈や ISO/IEC 14443 Type B の ID 取得など若干の要素を追加しています。さしあたり手元で用途のなかった NTAG21x ネイティブの WRITE, PWD_AUTH コマンドは今回は利用していません。今後必要になったときに実装を追加しようと思います。

  • ライブラリへ追加する関数のイメージ
    • ISO/IEC 14443 Type A の近接検知と ID の取得
    • ISO/IEC 14443 Type B の近接検知と ID の取得
    • NTAG21x 専用: メモリの総ページ数を取得
    • MIFARE Ultralight 用: 所定のメモリページの内容を読み出す
  • テストプログラムのイメージ
    • ターゲットが ISO/IEC 14443 Type A (MIFARE) の場合
      • ID を取得しシリアルへ出力
        • MIFARE Ultralight の場合
          • メモリ内容のダンプをシリアルへ出力
            • NDEF メッセージが記録されている場合
              • NDEF レコード内容を順次取得しシリアルへ出力
    • ターゲットが ISO/IEC 14443 Type B の場合
      • 擬似 ID である PUPI (Pseudo-Unique PICC Identifier) を取得しシリアルへ出力
    • ターゲットが FeliCa (Standard / Lite / Lite-S) の場合
      • IDm を取得しシリアルへ出力

機器の接続

手元ではこれまで Arduino IDE を利用する機会はありましたが Arduino 実機を扱うのは今回が初めてでした。

RC-S620/S と Arduino UNO をシリアル接続して制御を行い、上記のように処理状況を UNO から USB 経由で PC 上のシリアルターミナルへ随時出力することを想定していたのですが、UNO のハードウェアシリアルが一系統のみであることを知り、別立ての USB シリアル変換モジュール(FT231X)と Arduino 標準の SoftwareSerial ライブラリを併用することにしました。

同じ理由で、Arduino IDE から UNO 本体の USB シリアル経由でプログラムを書き込む際には [RC-S620/S 側 TXD] <--> [RX ピン] の結線を外して排他する必要があります。このあたりの事情は Arduino ユーザには当然のことなのでしょうがビギナーにはちょっと新鮮でした。

  

ソースコード

動作の様子

動画:3分19秒

  


(tanabe)
klab_gijutsu2 at 08:38│Comments(0)NFC | IoT

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント