Android
スマートカード
サーチ…
スマートカードの送受信
接続については、理解を深めるためのスニペットがあります:
//Allows you to enumerate and communicate with connected USB devices.
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
//Explicitly asking for permission
final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
UsbDevice device = deviceList.get("//the device you want to work with");
if (device != null) {
mUsbManager.requestPermission(device, mPermissionIntent);
}
Javaでは、Androidで利用できないパッケージjavax.smarcardを使用して通信が行われるので、ここでAPDU(スマートカードコマンド)の通信方法や送受信方法について考えてください。
今、上記の答えで言われたように
バルクアウトエンドポイント上にAPDU(スマートカードコマンド)を送信するだけでは、バルク入力エンドポイントに対して応答APDUを受信することはできません。エンドポイントを取得するには、次のコードスニペットを参照してください。
UsbEndpoint epOut = null, epIn = null;
UsbInterface usbInterface;
UsbDeviceConnection connection = mUsbManager.openDevice(device);
for (int i = 0; i < device.getInterfaceCount(); i++) {
usbInterface = device.getInterface(i);
connection.claimInterface(usbInterface, true);
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint ep = usbInterface.getEndpoint(j);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
// from host to device
epOut = ep;
} else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
// from device to host
epIn = ep;
}
}
}
}
これで、APDUコマンドとAPDU応答ブロックを送受信するバルクインとバルクアウトのエンドポイントが作成されました。
コマンドの送信については、下記のコードスニペットを参照してください。
public void write(UsbDeviceConnection connection, UsbEndpoint epOut, byte[] command) {
result = new StringBuilder();
connection.bulkTransfer(epOut, command, command.length, TIMEOUT);
//For Printing logs you can use result variable
for (byte bb : command) {
result.append(String.format(" %02X ", bb));
}
}
受信/応答の応答については、以下のコードスニペットを参照してください。
public int read(UsbDeviceConnection connection, UsbEndpoint epIn) {
result = new StringBuilder();
final byte[] buffer = new byte[epIn.getMaxPacketSize()];
int byteCount = 0;
byteCount = connection.bulkTransfer(epIn, buffer, buffer.length, TIMEOUT);
//For Printing logs you can use result variable
if (byteCount >= 0) {
for (byte bb : buffer) {
result.append(String.format(" %02X ", bb));
}
//Buffer received was : result.toString()
} else {
//Something went wrong as count was : " + byteCount
}
return byteCount;
}
ここでこの答えが見える場合、最初に送信されるコマンドは次のとおりです。
PC_to_RDR_IccPowerOnカードをアクティブにするコマンド。
ここではUSBデバイスクラス仕様書のセクション6.1.1を読んで作成することができます。
次に、このコマンドの例をここに示します62000000000000000000
これを送信する方法は次のとおりです。
write(connection, epOut, "62000000000000000000");
APDUコマンドを正常に送信した後、次のコマンドを使用して応答を読み取ることができます。
read(connection, epIn);
のようなものを受け取る
80 18000000 00 00 00 00 00 3BBF11008131FE45455041000000000000000000000000F1
ここでコードで受け取ったレスポンスは、コードからのread()
メソッドのresult
変数にread()
ます
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow