ACR1251にAndroid端末を乗せるとFeliCaカードと認識される問題を解決する
はじめに
NFCに興味を持ったので、Androidに搭載されているHost-based Card Emulation機能でなにかしてみようかなと思った。
ハローワールド的なものを作り終わって、さあ動かしてみようとACR1251CL-NTTComに乗せてみたら、TypeA/TypeBカードじゃなくてFeliCaと認識されてしまって、なんかうまく動かない!
という問題の解決を目指します。
この現象は、ちょっと型番忘れちゃったんですがAQUOS Phoneの何かで発生しました。
手持ちのXperiaZ/Z3/XZでは起きていません。
※ただ、XperiaはFeliCaとして認識されてほしい場合は困るかもしれません。TypeBカードとして認識されるので。
※しかしXperiaZ/Z3/XZはNFC-Fに対応してないので、FeliCaとしてACR1251に乗せたい場面が少ないかもしれません。
結論
ACR1251に「E0h 00h 00h 20h 01h 13h」のバイト列を送ると、設定が変わってFeliCaに反応しなくなります。
「E0h 00h 00h 20h 01h 1Fh」を送ると元に戻ります。
何が起きているのか
PCSCのWindCard系APIを使ってNFCカードを触っていると、ATR(Answer To Reset)という値を取得できます。
こいつが、Android端末を乗せたときに「僕FeliCaカードだよー」と叫びます。
具体的には下みたいな値が返ってきます。
3B-8F-80-01-80-4F-0C-A0-00-00-03-06-11-00-3B-00-00-00-00-42
まんなかちょっと後ろのほうに00-3Bと書いてありますが、これがFeliCaカードの証です。
今回は、こうなって欲しくありません。
詳細は不明ですが、なんとなく日本仕様なのかなと思います。
設定変更で解決
http://www.acs-japan.jp/products/258/acr1251-nfc のダウンロードページ最下部にApplication Programming InterfaceというPDFがあります。
これがACR1251の仕様書でして、この中のセクション5.4.12. Set PICC Operating Parameterに書いてあるコマンドを送信することで、反応するカードを選択することができます。
仕様に沿って、FeliCaのみ反応しないように設定すると「E0h 00h 00h 20h 01h 13h」です。
元に戻すには、すべてに反応する「E0h 00h 00h 20h 01h 1Fh」です。
ソースコード全文
ということで、設定変更のソースコード全文は以下です。
前半部分はeternalwindowsさんからお借りしました。(元ネタは参照セクションで)
ありがとうございます。
Visual Studio 2017 15.8.9で動くことを確認しています。
#include <windows.h>
#include <winscard.h>
#include <iostream>
#pragma comment (lib, "winscard.lib")
#define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
int main()
{
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
LPTSTR lpszReaderName;
LONG lResult;
DWORD dwAutoAllocate = SCARD_AUTOALLOCATE;
DWORD dwActiveProtocol;
BYTE bGetFirmwareCommand[] = { 0xE0, 0x00, 0x00, 0x20, 0x01, 0x13 };
BYTE bOutBuffer[256] = { 0 };
DWORD dwOutBufferLen = 0;
lResult = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
if (lResult != SCARD_S_SUCCESS) {
if (lResult == SCARD_E_NO_SERVICE)
MessageBox(NULL, TEXT("Smart Cardサービスが起動されていません。"), NULL, MB_ICONWARNING);
return 0;
}
lResult = SCardListReaders(hContext, SCARD_ALL_READERS, (LPTSTR)&lpszReaderName, &dwAutoAllocate);
if (lResult != SCARD_S_SUCCESS) {
if (lResult == SCARD_E_NO_READERS_AVAILABLE)
MessageBox(NULL, TEXT("カードリーダが接続されていません。"), NULL, MB_ICONWARNING);
return 0;
}
lResult = SCardConnect(hContext, lpszReaderName, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_UNDEFINED,&hCard, &dwActiveProtocol);
if (lResult !=
SCARD_S_SUCCESS) {
MessageBox(NULL, TEXT("カードリーダへの接続に失敗しました。"), NULL, MB_ICONWARNING);
return 0;
}
lResult = SCardControl(hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, bGetFirmwareCommand,sizeof(bGetFirmwareCommand), bOutBuffer, sizeof(bOutBuffer), &dwOutBufferLen);
if (lResult != SCARD_S_SUCCESS) {
MessageBox(NULL, TEXT("カードリーダへの送信が失敗しました。"), NULL, MB_ICONWARNING);
return 0;
}
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
SCardFreeMemory(hContext, lpszReaderName);
SCardReleaseContext(hContext);
return 0;
}
最後に
TypeAだけ、TypeBだけ、FeliCaだけに、それぞれ反応するように設定を変えると、
今使っているXperia XZだと以下みたいなATRが返ってきます。
TypeA
3B-80-80-01-01
TypeB
3B-F5-91-00-FF-91-81-71-FE-40-00-42-00-01-00-71-76
FeliCa
3B-8F-80-01-80-4F-0C-A0-00-00-03-06-11-00-3B-00-00-00-00-42
みなさんも、設定を変えてLet's HCE Life!!
参照
http://eternalwindows.jp/security/scard/scard02.html
https://tipszone.jp/20140902_introduction-to-nfc/
http://www.acs-japan.jp/products/258/acr1251-nfc
Author And Source
この問題について(ACR1251にAndroid端末を乗せるとFeliCaカードと認識される問題を解決する), 我々は、より多くの情報をここで見つけました https://qiita.com/ta_dragon/items/75ca13b006f708980418著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .