「RC-S380 を用いたFeliCa Lite-Sへの書き込み」でFeliCa Lite-S形式のICカードへの書き込みをおこない、「PC/SC APIを用いてSuicaカードの利用履歴情報の読み取り」でWindowsで標準でサポートされるPC/SC のインタフェースでSuicaカードのをアクセスしました。今回は、PC/SC のインタフェースでFeliCa Lite-S形式のICカード「フェリカ 革製キーホルダ型 ICタグ」にデータを書き込みます。
動作環境
- Windows 10 Professional
- Visual Studio 2019
- PaSoRi RC-S380
フェリカ 革製キーホルダ型 ICタグ
フェリカ 革製キーホルダ型 ICタグ (FeliCa Lite-S, フェリカライトエス) 業務用, TS-K1-NFCをamazonから購入したので、Raspberry Pi 3にRC-S380 非接触ICカードリーダー/ライター PaSoRi(パソリ)を接続してデータを書き込みました。RC-S380に置いた購入した革製キーホルダ型 ICタグを次に示します。
APDUコマンド仕様
PC/SCで使用するAPDUコマンドの仕様を次に示します。
Select File
byte no | 項目名 | 指定値 | 説明 |
---|---|---|---|
0 | CLA | FF | 命令クラス FF固定 |
1 | INS | A4 | Select File |
2 | P1 | 00 | エリア数 00固定 |
3 | P2 | 01 | サービス数 01固定 |
4 | Le | 02 | データサイズ 02固定 |
5 | Data | 09 | Selectするサービス 指定はリトルエンディアン |
6 | Data | 00 | Selectするサービス |
Read Binary
byte no | 項目名 | 指定値 | 説明 |
---|---|---|---|
0 | CLA | FF | 命令クラス FF固定 |
1 | INS | B0 | Read Binary |
2 | P1 | 00 | Block開始位置指定 00固定 |
3 | P2 | 00 | Blockリスト指定 00~指定でブロックx番目を取得する |
4 | Le | 00 | 00固定 |
Update Binary
byte no | 項目名 | 指定値 | 説明 |
---|---|---|---|
0 | CLA | FF | 命令クラス FF固定 |
1 | INS | D6 | Update Binary |
2 | P1 | 00 | Block開始位置指定 00固定 |
3 | P2 | 00 | Blockリスト指定 00~指定でブロックx番目に書く |
4 | Lc | 以降に続くデータのサイズ | |
5 | データ | 書き込みたいデータ | |
6 | Le | 00 | 00固定 |
Write Binary APDUコマンドはエラーのため使用できませんでした。
ステータスワード
「SW1:0x90、SW2:0x00」のときのみ成功を示し、それ以外の場合はつぎの実行できなかった理由を示します。
FeliCa Lite-Sのリード/ライト関数
「PC/SC APIを用いてSuicaカードの利用履歴情報の読み取り」の「ICカード読み取り関数」に示すSendCommandメソッドを次のように変更します。
- 7行目で、Select File APDUコマンド を定義します。
- 8行目で、Read Binary APDUコマンド を定義します。
- 9行目で、Update Binary APDUコマンド を定義します。
void SendCommand(IntPtr hContext, string readerName) { int dwResponseSize; byte[] response = new byte[2048]; long lResult; byte[] commnadSelectFile = { 0xff, 0xA4, 0x00, 0x01, 0x02, 0x09, 0x00 }; //Select File APDUコマンド サービスコード:9 byte[] commnadReadBinary = { 0xff, 0xb0, 0x00, 0x01, 0x00 }; // READ BINARY 2ブロック目のデータの読み込み byte[] commnadUpdateBinary = { 0xff, 0xd6, 0x00, 0x01, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12, 13, 14, 15,0x00 }; // UPDATE BINARY IntPtr SCARD_PCI_T1 = GetPciT1(); NfcApi.SCARD_IO_REQUEST ioRecv = new NfcApi.SCARD_IO_REQUEST { cbPciLength = 2048 }; IntPtr hCard = Connect(hContext, readerName); dwResponseSize = response.Length; lResult = NfcApi.SCardTransmit(hCard, SCARD_PCI_T1, commnadSelectFile, commnadSelectFile.Length, ioRecv, response, ref dwResponseSize); if (lResult != NfcConstant.SCARD_S_SUCCESS) { Debug.WriteLine("SelectFile error\n"); return; } dwResponseSize = response.Length; lResult = NfcApi.SCardTransmit(hCard, SCARD_PCI_T1, commnadUpdateBinary, commnadUpdateBinary.Length, ioRecv, response, ref dwResponseSize); if (lResult != NfcConstant.SCARD_S_SUCCESS) { Debug.WriteLine("WriteBinary error\n"); return; } Parse_tag(response); dwResponseSize = response.Length; lResult = NfcApi.SCardTransmit(hCard, SCARD_PCI_T1, commnadReadBinary, commnadReadBinary.Length, ioRecv, response, ref dwResponseSize); if (lResult != NfcConstant.SCARD_S_SUCCESS) { Debug.WriteLine("ReadBinary error\n"); return; } Parse_tag(response); }
作成したプログラムの実行
デバックメニューから「デバック開始」をクリックすると、作成したプログラムが実行され、出力ウインドウに次のメッセージが表示されます。
Smart Cardサービスに接続しました。 リーダー名を\0で接続した文字列: Sony FeliCa Port/PaSoRi 3.0 0 Sony FeliCa Port/PaSoRi 3.0 0 (S/N 0206962) から、カードを読み取りました。012E4128728C7E8B Suica履歴データ:90-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 Suica履歴データ:00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-90-00