/****************************************************************************
 * Copyright (C) 2012-2017 HS Coburg.
 * All rights reserved.
 * Contact: ecsec GmbH (info@ecsec.de)
 *
 * This file is part of the Open eCard App.
 *
 * GNU General Public License Usage
 * This file may be used under the terms of the GNU General Public
 * License version 3.0 as published by the Free Software Foundation
 * and appearing in the file LICENSE.GPL included in the packaging of
 * this file. Please review the following information to ensure the
 * GNU General Public License version 3.0 requirements will be met:
 * http://www.gnu.org/copyleft/gpl.html.
 *
 * Other Usage
 * Alternatively, this file may be used in accordance with the terms
 * and conditions contained in a signed written agreement between
 * you and ecsec GmbH.
 *
 ***************************************************************************/

package org.openecard.scio;

import android.nfc.tech.IsoDep;
import java.io.IOException;
import org.openecard.common.ifd.scio.SCIOATR;
import org.openecard.common.ifd.scio.SCIOCard;
import org.openecard.common.ifd.scio.SCIOChannel;
import org.openecard.common.ifd.scio.SCIOErrorCode;
import org.openecard.common.ifd.scio.SCIOException;
import org.openecard.common.ifd.scio.SCIOProtocol;
import org.openecard.common.ifd.scio.SCIOTerminal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * NFC implementation of SCIO API card interface.
 *
 * @author Dirk Petrautzki
 */
public class NFCCard implements SCIOCard {

    private static final Logger LOG = LoggerFactory.getLogger(NFCCard.class);
    private final NFCCardChannel nfcCardChannel = new NFCCardChannel(this);
    protected IsoDep isodep;
    
    NFCCard(IsoDep tag) {
	isodep = tag;
    }

    @Override
    public void beginExclusive() throws SCIOException {
	LOG.warn("beginExclusive not supported");
    }

    @Override
    public void endExclusive() throws SCIOException {
	LOG.warn("endExclusive not supported");
    }

    @Override
    public void disconnect(boolean arg0) throws SCIOException {
	try {
	    isodep.close();
	} catch (IOException e) {
	    // TODO: check if the error code can be chosen more specifically
	    throw new SCIOException("Disconnect failed", SCIOErrorCode.SCARD_F_UNKNOWN_ERROR, e);
	}
    }

    @Override
    public SCIOATR getATR() {
	LOG.warn("getATR not supported");
	// for now there is no way to get the ATR in android nfc api
	return new SCIOATR(new byte[0]);
    }

    @Override
    public SCIOChannel getBasicChannel() {
	return this.nfcCardChannel;
    }

    @Override
    public SCIOProtocol getProtocol() {
	// NFC is contactless
        return SCIOProtocol.TCL;
    }

    @Override
    public SCIOChannel openLogicalChannel() throws SCIOException {
	return nfcCardChannel;
    }

    @Override
    public byte[] transmitControlCommand(int arg0, byte[] arg1) throws SCIOException {
	LOG.warn("transmitControlCommand not supported");
	return new byte[0];
    }

    @Override
    public SCIOTerminal getTerminal() {
        return null;
    }

}

@@ -959,16 +959,54 @@
 IsoDep;%0A
+import java.io.ByteArrayOutputStream;%0A
 import j
@@ -2390,105 +2390,1087 @@
  %7B%0A%09
-LOG.warn(%22getATR not supported%22);%0A%09// for now there is no way to get the ATR in android nfc api%0A%09
+// build ATR according to PCSCv2-3, Sec. 3.1.3.2.3.1%0A%09byte%5B%5D histBytes = isodep.getHistoricalBytes();%0A%09if (histBytes == null) %7B%0A%09    histBytes = isodep.getHiLayerResponse();%0A%09%7D%0A%09if (histBytes == null) %7B%0A%09    return new SCIOATR(new byte%5B0%5D);%0A%09%7D else %7B%0A%09    ByteArrayOutputStream out = new ByteArrayOutputStream();%0A%09    // Initial Header%0A%09    out.write(0x3B);%0A%09    // T0%0A%09    out.write(0x80 %7C (histBytes.length & 0xF));%0A%09    // TD1%0A%09    out.write(0x80);%0A%09    // TD2%0A%09    out.write(0x01);%0A%09    // ISO14443A: The historical bytes from ATS response.%0A%09    // 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%0A%09    // TODO: check that the HiLayerResponse matches the requirements for ISO14443B%0A%09    out.write(histBytes, 0, histBytes.length);%0A%0A%09    // TCK: Exclusive-OR of bytes T0 to Tk%0A%09    byte%5B%5D preATR = out.toByteArray();%0A%09    byte chkSum = 0;%0A%09    for (int i = 1; i %3C preATR.length; i++) %7B%0A%09%09chkSum %5E= preATR%5Bi%5D;%0A%09    %7D%0A%09    out.write(chkSum);%0A%0A%09    byte%5B%5D atr = out.toByteArray();%0A%09    
 retu
@@ -3484,29 +3484,24 @@
 SCIOATR(
-new byte%5B0%5D);
+atr);%0A%09%7D
 %0A    %7D%0A%0A

Add ATR support to android NFC