Add ATR support to android NFC
package org.openecard.scio;
import android.nfc.tech.IsoDep;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.openecard.common.ifd.scio.SCIOATR;
import org.openecard.common.ifd.scio.SCIOCard;
@@ -72,9 +73,39 @@ public class NFCCard implements SCIOCard {
@Override
public SCIOATR getATR() {
- LOG.warn("getATR not supported");
- // for now there is no way to get the ATR in android nfc api
+ // build ATR according to PCSCv2-3, Sec. 3.1.3.2.3.1
+ byte[] histBytes = isodep.getHistoricalBytes();
+ if (histBytes == null) {
+ histBytes = isodep.getHiLayerResponse();
+ }
+ if (histBytes == null) {
return new SCIOATR(new byte[0]);
+ } else {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ // Initial Header
+ out.write(0x3B);
+ // T0
+ out.write(0x80 | (histBytes.length & 0xF));
+ // TD1
+ out.write(0x80);
+ // TD2
+ out.write(0x01);
+ // ISO14443A: The historical bytes from ATS response.
+ // ISO14443B: 1-4=Application Data from ATQB, 5-7=Protocol Info Byte from ATQB, 8=Higher nibble = MBLI from ATTRIB command Lower nibble (RFU) = 0
+ // TODO: check that the HiLayerResponse matches the requirements for ISO14443B
+ out.write(histBytes, 0, histBytes.length);
+
+ // TCK: Exclusive-OR of bytes T0 to Tk
+ byte[] preATR = out.toByteArray();
+ byte chkSum = 0;
+ for (int i = 1; i < preATR.length; i++) {
+ chkSum ^= preATR[i];
+ }
+ out.write(chkSum);
+
+ byte[] atr = out.toByteArray();
+ return new SCIOATR(atr);
+ }
}
@Override
