智慧卡傳送和接收
對於連線,這裡有一個片段可以幫助你理解:
//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
變數