Source:
private ResponseAPDU communicate(CommandAPDU apdu) throws IOException { ByteArrayOutputStream result = new ByteArrayOutputStream(); ResponseAPDU lastResponse = null; if (mCardCapabilities.hasExtended()) { lastResponse = mTransport.transceive(apdu); } else if (apdu.getData().length <= MAX_APDU_NC) { int ne = Math.min(apdu.getNe(), MAX_APDU_NE); lastResponse = mTransport.transceive(new CommandAPDU(apdu.getCLA(), apdu.getINS(), apdu.getP1(), apdu.getP2(), apdu.getData(), ne)); } else if (apdu.getData().length > MAX_APDU_NC && mCardCapabilities.hasChaining()) { int offset = 0; byte[] data = apdu.getData(); int ne = Math.min(apdu.getNe(), MAX_APDU_NE); while (offset < data.length) { int curLen = Math.min(MAX_APDU_NC, data.length - offset); boolean last = offset + curLen >= data.length; int cla = apdu.getCLA() + (last ? 0 : MASK_CLA_CHAINING); lastResponse = mTransport.transceive(new CommandAPDU(cla, apdu.getINS(), apdu.getP1(), apdu.getP2(), Arrays.copyOfRange(data, offset, offset + curLen), ne)); if (!last && lastResponse.getSW() != APDU_SW_SUCCESS) { throw new UsbTransportException("Failed to chain apdu"); } offset += curLen; } } if (lastResponse == null) { throw new UsbTransportException("Can't transmit command"); } result.write(lastResponse.getData()); while (lastResponse.getSW1() == 0x61) { CommandAPDU getResponse = new CommandAPDU(0x00, 0xC0, 0x00, 0x00, lastResponse.getSW2()); lastResponse = mTransport.transceive(getResponse); result.write(lastResponse.getData()); } result.write(lastResponse.getSW1()); result.write(lastResponse.getSW2()); return new ResponseAPDU(result.toByteArray()); }

Target:
private ResponseAPDU communicate(CommandAPDU apdu) throws IOException { ByteArrayOutputStream result = new ByteArrayOutputStream(); ResponseAPDU lastResponse = null; if (mCardCapabilities.hasExtended()) { lastResponse = mTransport.transceive(apdu); } else if (apdu.getData().length <= MAX_APDU_NC) { int ne = Math.min(apdu.getNe(), MAX_APDU_NE); lastResponse = mTransport.transceive(new CommandAPDU(apdu.getCLA(), apdu.getINS(), apdu.getP1(), apdu.getP2(), apdu.getData(), ne)); } else if (apdu.getData().length > MAX_APDU_NC && mCardCapabilities.hasChaining()) { int offset = 0; byte[] data = apdu.getData(); int ne = Math.min(apdu.getNe(), MAX_APDU_NE); while (offset < data.length) { int curLen = Math.min(MAX_APDU_NC, data.length - offset); boolean last = offset + curLen >= data.length; int cla = apdu.getCLA() + (last ? 0 : MASK_CLA_CHAINING); lastResponse = mTransport.transceive(new CommandAPDU(cla, apdu.getINS(), apdu.getP1(), apdu.getP2(), Arrays.copyOfRange(data, offset, offset + curLen), ne)); if (!last && lastResponse.getSW() != APDU_SW_SUCCESS) { throw new UsbTransportException("Failed to chain apdu"); } offset += curLen; } } if (lastResponse == null) { throw new UsbTransportException("Can't transmit command"); } result.write(lastResponse.getData()); while (lastResponse.getSW1() == APDU_SW1_RESPONSE_AVAILABLE) { CommandAPDU getResponse = new CommandAPDU(0x00, 0xC0, 0x00, 0x00, lastResponse.getSW2()); lastResponse = mTransport.transceive(getResponse); result.write(lastResponse.getData()); } result.write(lastResponse.getSW1()); result.write(lastResponse.getSW2()); return new ResponseAPDU(result.toByteArray()); }