開発

NFC#08 RC-S660/S パケット仕様確認

RC-S660/S パケット仕様確認

今回は RC-S660/S との通信で使用されるパケット構造の理解を深めていきます。

・NFCを活用した新しいサービスや製品を企画・開発したい方
・スマートフォンやICカードとの連携機能を実装したいエンジニア
・IoT機器や非接触決済の技術に関心のある開発者

完成品画像NFC完成品紹介ページはこちら

パケット構造の概要

RC-S660/S との通信で使用されるパケットは、コマンドフレームとACKフレームの2種類が定義されています。

 コマンドフレーム

ホスト(今回は Mac)から RC-S660/S へのコマンド送信、及び、 RC-S660/S からのレスポンスとして利用されます。

コマンドフレームの概略図を以下に示します。

コマンドフレームは、 CCID コマンドを内包します。
CCID はICカードインターフェースデバイスを示し、USB関連仕様として定義されています。
CCID コマンドは、USBホストがICカードインターフェースデバイス(CCID)を介して、ICカードとやり取りするためのコマンドとなります。

RC-S660/S でサポートしている CCID コマンドでは、CCIDコマンド中に RC-S660/S を制御するためのAPDUコマンドを内包するものがあります。
APDU(Application Protocol Data Unit)はスマートカード向けの通信プロトコルで、 ISO/IEC 7816-4 で定義されています。

さらにそのAPDUコマンドの中には、ICカードを操作するためのカードコマンドを内包するものがあります。

 

 ACKフレーム

特定の目的でのみ利用されます。
例えば、ホスト(今回は Mac)からのコマンドを受信した際、データリンクレベルのエラーを検出しなかった場合に、 RC-S660/S からホストへ送信されます。

ACKフレームは特定のデータ列となります。

 

各データのパケット構成

それでは各データのパケット構成を詳しく見ていきましょう。

 コマンドフレーム/ACKフレーム構成

コマンドフレーム/ACKフレームは以下の要素で構成されます。

名称 バイト
サイズ
データ
1 プリアンブル 1 00h
2 スタートコード 2 00FFh
3 パケットデータ長 2 パケットデータのバイトサイズ(LEN)
※ビッグエンディアン
4 パケットデータ長チェックサム 1 コマンドフレーム:
 パケットデータ長データ列のチェックサム
ACKフレーム: FFh
5 パケットデータ LEN (コマンドフレームのみ)CCIDコマンドデータ列
6 パケットデータチェックサム 1 (コマンドフレームのみ)パケットデータ列のチェックサム
7 ポストアンブル 1 00h

プリアンブル・スタートコードは、パケットデータの開始を識別するための固定のデータ列です。
また、ポストアンブルは、パケットデータの終了を示す固定のデータです。

コマンドフレームにおけるパケットデータはCCIDコマンドデータ列です。
CCIDコマンドデータ列のバイトサイズがパケットデータ長に格納されます。
なお、ACKフレームではパケットデータは存在せず、パケットデータ長には 0000h が格納されます。

チェックサムは誤り検出のためのデータで、 データ列の各バイトの総和 + チェックサムバイト の下位1バイトが 00h となるようなチェックサムを設定します。
ただし、ACKフレームにおいては、パケットデータ長チェックサムには FFh を設定します。

 

 CCID コマンド/レスポンス構成

CCIDコマンドは以下の要素で構成されます。

名称 バイト
サイズ
データ
1 メッセージタイプ 1 CCIDコマンドの種類を示す特定の値
2 データ長 4 固有データのバイトサイズ(dwLength)
※リトルエンディアン
3 スロット番号 1 RC-S660/S では 00h 固定
4 シーケンス番号 1 送信ごとに単調増加するカウンタ
5 ステータスコード 1 (レスポンスのみ)RC-S660/S ではコマンドステータス
 02h :エラーなし
 42h :失敗(エラーで詳細を示す)
6 エラーコード 1 (レスポンスのみ)コマンドステータスが失敗の場合、エラー詳細を示す特定の値
7 固有ヘッダー 1 or 3 CCIDコマンドによる
8 固有データ dwLength CCIDコマンドによる

メッセージタイプはCCIDコマンドの種類を示し、各コマンドに対して特定の値が割り振られています。

スロット番号は、CCIDが複数のスロット(ICカード接続)をサポートしている場合に、どのスロットへのコマンドかを識別します。
RC-S660/S ではカード1枚での利用に限られているため、スロット番号は 00h 固定となります。

シーケンス番号は、CCIDコマンド送信ごとに単調増加で設定するカウンタです。
コマンドに設定したシーケンス番号がレスポンスにそのまま設定され、ホスト側でコマンド送信データとレスポンスデータの突合に利用します。
シーケンス番号の値そのものは RC-S660/S の挙動への影響はありません。

ステータスコード、エラーコードはレスポンスのみで使用され、スロットのステータス・エラーを示します。RC-S660/S においてはそれぞれ、コマンド処理のエラー有無と、エラー内容を示すデータが設定されます。

固有ヘッダー、固有データはCCIDコマンドによって設定データが異なります。
固有ヘッダーとして割り当てられている領域は3バイトですが、レスポンスではそのうちの2バイトがステータスコード、エラーコードとして利用されるため、残りの1バイトのみが固有ヘッダーとして利用できる領域となります。

 

◇RC-S660/S でサポートしている CCID コマンド

RC-S660/S では、以下の2つのCCIDコマンドのみがサポートされています。

  • PC_to_RDR_Escape コマンド(メッセージタイプ 6Bh
    • RC-S660/S を制御するためのAPDUコマンドを送信する
    • 固有ヘッダー:全て 00h
    • 固有データ:
      • コマンド時:APDUコマンドデータ
      • レスポンス時:APDUレスポンスデータ
  • PC_to_RDR_Abort コマンド(メッセージタイプ 72h
    • 実行中のCCIDコマンドを中断する
    • 固有ヘッダー:全て 00h
    • 固有データ:無し

今回の開発では単純なパターンのみとするため、 PC_to_RDR_Escape コマンドのみ取り扱います。

 

 APDU コマンド構成

筆者注:
APDU が定義されている ISO/IEC 7816-4 では “Command APDU”(コマンド APDU)と表記されます。
厳密には異なりますが、今回は RC-S660/S のリファレンスの表現に合わせて「APDU コマンド」という表記としております。

RC-S660/S における APDU コマンドは以下の要素で構成されます。

名称 RC-S660/S 略称 バイトサイズ データ
1 クラスバイト CLA 1 コマンドのクラスを示す特定の値
2 命令バイト INS 1 処理対象コマンドを示す特定の値
3 パラメータバイト P1, P2 2 コマンド処理に関する制御とオプションを示す特定の値
4 コマンドデータ長 Lc 1 (コマンドデータが存在する場合のみ)コマンドデータのバイトサイズ
5 コマンドデータ Data In Lc (コマンドデータが存在する場合のみ)コマンドデータそのもの
6 レスポンスデータ長 Le 1 期待するレスポンスデータのバイトサイズ

クラスバイト、命令バイト、パラメータバイトはコマンドヘッダーとも呼ばれ、 APDU コマンドに応じた値を設定します。
ISO/IEC 7816-4 で定められているものの他、ベンダー独自で定義しているものもあります。

APDU コマンドがデータを持つ場合、コマンドヘッダーに続いてコマンドデータ長とコマンドデータを設定します。
コマンドデータ長は、 ISO/IEC 7816-4 の定義上は1バイトで表現できるサイズ(255バイト)を超えて設定できますが、 RC-S660/S においては1バイトで表現できるサイズ(255バイト)までとなっています。

コマンドヘッダー・コマンドデータに続いて、期待するレスポンスデータ長を設定できます。
この値はデータチェックに利用され、実際のレスポンスデータ長と異なる場合に RC-S660/S からエラーや警告が返却されます。
今回の開発では単純化のためデータチェックしないものとし、期待するレスポンスデータ長は設定しないものとします。

 

 APDU レスポンス構成

筆者注:
APDU が定義されている ISO/IEC 7816-4 では “Response APDU”(レスポンス APDU)と表記されます。
コマンドと同様に厳密には異なりますが、「APDU コマンド」の表記に対応して「APDU レスポンス」という表記としております。

APDU レスポンスは以下の要素で構成されます。

名称 RC-S660/S 略称 バイトサイズ データ
1 レスポンスデータ Data Out 任意 (レスポンスデータが存在する場合のみ)レスポンスデータそのもの
2 ステータスバイト SW1, SW2 2 処理結果を示す特定の値

APDU コマンドを受信すると、デバイスはコマンドに応じた処理をし、ステータスバイトに処理結果を設定して返却します。
また、レスポンスにデータが含まれる場合、ステータスコードより先行してレスポンスデータが返却されます。

 

 TLV 形式データ

APDU コマンド/レスポンスのデータでは、 TLV 形式でデータが取り扱われることがよくあります。
TLV 形式は、データの 種類/タグ(Type / Tag)、長さ(Length)、値(Value) をセットで表現するフォーマットです。
ISO/IEC 7816-4 では、 TLV は以下の用途で利用されます。

  • タグ(Tag)
    • タグ番号やレコード識別子として使用される
  • 長さ(Length)
    • 値のデータサイズ
  • 値(Value)
    • 実データ

 

パケット解析

 解析に使用する通信パケット

前回、RC-S660/S と通信し、ファームウェアバージョンを取得しました。
その際の通信パケットを利用し、パケットの構成と照合していきましょう。

題材となる送受信パケット

 

 パケット全体

送受信パケット全体を見てみましょう。

パケット全体

送信パケットは1つのコマンドフレームとなっています。
また、受信パケットは、1つのACKフレームと1つのコマンドフレームとなっています。

受信のACKフレームとコマンドフレームは連続しているように見えますが、 RC-S660/S の挙動としては、

  • ホストからコマンドフレームを受信すると、フレームに問題がなければ、10ミリ秒以内にACKフレームをホストへ返送する
  • その後、コマンド処理が完了したら、レスポンスのコマンドフレームをホストへ返送する

というように段階的に送信されます。

【補足】
今回のドライバで連続しているように見えるのは、 FT232H のレイテンシタイマによるものとなります。
レイテンシタイマのタイムアウト値が経過するまではPC側へデータ転送されないため、その時間内にACKフレームと受信コマンドフレームの両方が RC-S660/S から FT232H へ送信されることで、 Mac 側の受信では連続したデータのように見えます。
レイテンシタイマについては前回の記事も参照してください。

 

 送信コマンドフレーム

まずは送信パケットのコマンドフレームから見ていきます。

送信コマンドフレーム解析

プリアンブル、スタートコード、ポストアンブルは仕様通りの固定のデータとなっています。

パケットデータ長はビッグエンディアンのため、 000Eh = 14 バイトとなります。
パケットデータの領域も 14 バイト分であり、実際のデータと一致します。

パケットデータは CCID コマンドそのものとなります。
データの内容については後ほど詳しく見ていきます。

チェックサムは、各バイトの総和との和の下位1バイトが 00h となるように設定します。
パケットデータ長の各バイトの総和は

00h + 0Eh = 0E

のため、下位1バイトが 00h となるには F2h であり、実際のデータと一致します。

また、パケットデータのチェックサムは、総和が

6Bh + 04h + FFh + 56h = 01C4h
※ 00h は総和に影響しないため省略

のため、下位1バイトが 00h となるには 3Ch であり、こちらも実際のデータと一致します。

このように正しいコマンドフレームを送信することで、 RC-S660/S からACKフレームとレスポンスのコマンドフレームが返送されます。

 

◇CCID コマンド

送信コマンドフレーム中のCCIDコマンドについて詳しく見てみましょう。

CCIDコマンド解析

RC-S660/S を制御するため、CCIDコマンドは PC_to_RDR_Escape コマンドを使用します。
PC_to_RDR_Escape コマンドのメッセージタイプ 6Bh であるため、仕様通りとなっています。

PC_to_RDR_Escape コマンドでは、固有ヘッダーは全て 00h であるため、こちらも仕様通りです。
固有データは APDU コマンドそのものとなり、データの内容については後ほど詳しく見ていきます。

データ長は、CCIDコマンドではリトルエンディアンで表現されるため、 00000004h = 4 バイトとなります。固有データの領域も 4 バイト分であり、実際のデータと一致します。

スロット番号は、RC-S660/S では 00h 固定であり、仕様通りとなっています。
また、今回は1度きりの送信のため、シーケンス番号は 00h としています。

 

◇APDU コマンド

CCIDコマンド中のAPDUコマンドについて詳しく見てみましょう。

APDUコマンド解析

RC-S660/S ファームウェアバージョン取得のAPDUコマンドは、 RC-S660/S 公式リファレンスより以下の通りです。

  • コマンドヘッダー:
    • CLA(クラスバイト): FFh 
    • INS(命令バイト): 56h
    • パラメータバイト:
      • SW1: 00h
      • SW2: 00h
  • Lc(コマンドデータ長):- ※コマンドデータを持たない
  • Data In(コマンドデータ):- ※コマンドデータを持たない
  • Le(レスポンスデータ長): XXh

コマンドヘッダーは全て仕様通りとなっています。
また、ファームウェアバージョン取得のAPDUコマンドではコマンドデータを持たないため、 Lc 及び Data In は存在しません。

ファームウェアバージョン取得ではレスポンスデータが存在するため、レスポンスデータ長を設定することができます。
しかし、今回の開発ではレスポンスデータ長によるデータチェックをしないものとしているため、パケットデータに含めておりません。

 

 ACKフレーム

次に受信パケットのACKフレームを見てみましょう。

ACKフレーム解析

プリアンブル、スタートコード、ポストアンブルは仕様通りの固定のデータとなっています。

パケットデータ長はACKフレームの仕様通り、 0000h となっています。
またパケットデータ長チェックサムも、ACKフレームにおいては FFh 固定であるため、仕様通りとなっています。

 

 受信コマンドフレーム

最後に受信パケットのコマンドフレームを見てみましょう。

受信コマンドフレーム解析

プリアンブル、スタートコード、ポストアンブルは仕様通りの固定のデータとなっています。

パケットデータ長はビッグエンディアンのため、 001Eh = 30 バイトとなります。
パケットデータの領域も 30 バイト分であり、実際のデータと一致します。

パケットデータは、送信コマンドフレームの CCID コマンドに対する CCID レスポンスデータとなります。
データの内容については後ほど詳しく見ていきます。

送信コマンドフレームと同様にチェックサムを算出してみましょう。
パケットデータ長の各バイトの総和は

00h + 1Eh = 1Eh

のため、下位1バイトが 00h となるには E2h であり、実際のデータと一致します。

また、パケットデータのチェックサムは、総和が

83h + 14h + 02h + 01h + 01h + 01h + 01h + FFh
+ FFh + 04h + 01h + FFh + FFh + 01h + FFh + FFh + 90h = 072Dh
※ 00h は総和に影響しないため省略

のため、下位1バイトが 00h となるには D3h であり、こちらも実際のデータと一致します。

 

◇CCID レスポンス

受信コマンドフレーム中のCCIDレスポンスについて詳しく見てみましょう。

CCIDレスポンス解析

送信時の PC_to_RDR_Escape コマンドに対するレスポンスは RDR_to_PC_Escape レスポンスとなります。 RDR_to_PC_Escape レスポンスのメッセージタイプ 83h であるため、仕様通りとなっています。

RDR_to_PC_Escape レスポンスでは、固有ヘッダーは 00h であるため、こちらも仕様通りです。
固有データは APDU レスポンスそのものとなり、データの内容については後ほど詳しく見ていきます。

データ長は、CCIDレスポンスでもリトルエンディアンで表現されるため、 00000014h = 20 バイトとなります。固有データの領域も 20 バイト分であり、実際のデータと一致します。

スロット番号、シーケンス番号は送信時のCCIDコマンドと同一の値が設定されます。
今回はどちらも 00h で送信しているため、 CCID レスポンスでも 00h が設定されています。

RC-S660/S において、ステータスコードはコマンド処理のエラー有無を示します。 02h はエラーがない時の値となります。
エラーコードはエラーの内容を示しますが、ステータスコードで「エラーなし」となっているため、今回のパケットでは意味を持ちません。

 

◇APDU レスポンス

CCIDレスポンス中のAPDUレスポンスについて詳しく見てみましょう。

APDUレスポンス解析

APDUレスポンスは、末尾2バイトがステータスバイト、それより前は全てレスポンスデータとなります。
ステータスバイト SW1 = 90 , SW2 = 00 は正常終了であり、ファームウェアバージョン取得が正しく実行できた事を表します。
このため、レスポンスデータは取得されたファームウェアバージョン情報となります。

なお、 RC-S660/S 公式リファレンスより、取得されるファームウェアバージョン情報は以下の通りです。

オフセット 名称 サイズ 今回のパケットにおけるデータ
0 全体ファームウェアバージョン 4 00 00 01 01
4 MCU ファームウェアバージョン 2 01 01
6 SAM ファームウェアバージョン 2 ff ff
8 RFFE ファームウェアバージョン 2 04 01
10 RFFE EEPROM バージョン 2 ff ff
12 ブートローダバージョン 2 01 00
14 ファームウェア更新状態 2 ff ff
16 起動状態 2 00 00

 

 パケット要点まとめ

ここまで、送受信パケットの各データの詳細を見てきました。
最小で 20 バイト程度と比較的短いパケットですが、複数形式のコマンドが内包されているため、慣れていないと少し読みづらいかもしれません。

 

おわりに

今回は RC-S660/S で規定されている通信パケット構造と照合しながら、実際の通信パケットを解析しました。最小で 20 バイト程度と比較的短いパケットですが、複数形式のコマンドが内包されており、慣れていないと少し読みづらいかもしれません。

本シリーズではNFC体験ということで、以降の記事では、核となるAPDUコマンド・レスポンスに重点を置いて解説していくものとします。
より詳細にデータを読み解きたい場合は、本記事を振り返って参照ください。

次回はNFCカード読み書きについて実装していきます。

 


 

TOP