@Override public void onTagDiscovered(final Tag tag) { Log.d(TAG, "Tag found: " + tag.toString()); Log.d(TAG, "Id: " + HexStrings.toHexString(tag.getId())); for (String tech: tag.getTechList()) { Log.d(TAG, "Tech: " + tech); } if (Arrays.asList(tag.getTechList()).contains("android.nfc.tech.IsoDep")) { IsoDepApduInterface apduInterface; try { apduInterface = new IsoDepApduInterface(IsoDep.get(tag)); } catch (IOException e) { fail(e.getMessage()); e.printStackTrace(); return; } dispatchLoadTask(apduInterface); } }
/** * Callback when a new tag is discovered by the system. * * <p>Communication with the card should take place here. * * @param tag Discovered tag */ public void onTagDiscovered(Tag tag){ LogUtil.i(TAG, "======= Discovered Tag:" + tag + "=========="); // Android's Host-based Card Emulation (HCE) feature implements the ISO-DEP (ISO 14443-4) // protocol. // // In order to communicate with a device using HCE, the discovered tag should be processed // using the IsoDep class. mIsoDep = IsoDep.get(tag); // Connect to the remote NFC device try { mIsoDep.connect(); } catch (IOException e) { e.printStackTrace(); } mIsoDep.setTimeout(TIMEOUT); }
private DERObject transceiveDER(IsoDep isoDep, DERObject input, boolean needsSelectAidApdu) throws IOException { final long startTimeTransceive = System.currentTimeMillis(); final byte[] derPayload = input.serializeToDER(); byte[] derResponse; Log.d(TAG, "transceiveDER - start - send derPayload length=" + derPayload.length + " byte"); derResponse = assembleFragment(isoDep, derPayload, needsSelectAidApdu); derResponse = keepAliveLoop(isoDep, derResponse); derResponse = concatNextResponseBytes(isoDep, derResponse); DERObject result = DERParser.parseDER(derResponse); long duration = System.currentTimeMillis() - startTimeTransceive; Log.d(TAG, "transceiveDER - end - " + "took " + duration + " ms - " + "received length=" + result.getPayload().length + " byte"); return result; }
private byte[] assembleFragment(IsoDep isoDep, byte[] derPayload, boolean needsSelectAidApdu) throws IOException { int fragmentByte = 0; byte[] derResponse = new byte[0]; while (fragmentByte < derPayload.length) { byte[] fragment = new byte[0]; if (needsSelectAidApdu) { Log.d(TAG, "transceiveDER - select Aid Apdu"); byte[] retval = isoDep.transceive(NFCUtils.createSelectAidApdu(NFCUtils.AID_ANDROID)); Log.d(TAG, "transceiveDER - select Aid Apdu OK! "+retval.length); if(NFCUtils.isKeepAlive(retval)) { needsSelectAidApdu = false; } } int endLength = Math.min(derPayload.length, fragmentByte + NFCUtils.DEFAULT_MAX_FRAGMENT_SIZE); byte[] fragmentPart = Arrays.copyOfRange(derPayload, fragmentByte, endLength); fragment = ClientUtils.concatBytes(fragment, fragmentPart); Log.d(TAG, "transceiveDER - about to send fragment size: " + fragment.length); derResponse = isoDep.transceive(fragment); Log.d(TAG, "transceiveDER - received payload: " + Arrays.toString(derResponse)); fragmentByte += fragment.length; } return derResponse; }
@Override public void onTagDiscovered(Tag tag) { Log.d(TAG, "onTagDiscovered: " + tag); final long startTime = System.currentTimeMillis(); long duration; try { IsoDep isoDep = IsoDep.get(tag); isoDep.connect(); onTagDiscovered(tag, isoDep, true); } catch (Throwable e) { Log.e(TAG, "Exception in onTagDiscovered", e); getPaymentRequestDelegate().onPaymentError(e.getMessage()); } }
/** * Activate NFC dispacher to read NFC Card Set the most important priority to the foreground application */ public static void enableDispatch(Activity activity) { if (isNfcEnabled(activity)) { NfcAdapter adapter = getNfcAdapter(activity); PendingIntent pendingIntent = PendingIntent.getActivity( activity, 0, new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter[] intentFilter = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) }; String[][] techList = new String[][] { { IsoDep.class.getName() } }; adapter.enableForegroundDispatch(activity, pendingIntent, intentFilter, techList); } }
/** * Creates a transceiver for the specified tag. * @return null is returned if a transceiver could not be created */ public static Transceiver create(Logger logger, Tag tag) { IsoDep isoDep = IsoDep.get(tag); if (null == isoDep) { logger.warn(TAG, "Unable to create IsoDep for NFC tag: " + StringUtil.join(tag.getTechList(), ", ")); return null; } logger.info(TAG, "Connnecting to ISO-DEP: " + isoDep.isConnected()); try { isoDep.connect(); isoDep.setTimeout(30000); return new Transceiver(logger, isoDep); } catch (Exception ex) { logger.error(TAG, "Unable to connect to ISO-DEP", ex); return null; } }
@TargetApi(10) private static CreditCardNfcResult readRecord(IsoDep paramIsoDep, byte paramByte1, byte paramByte2) throws IOException, TagReadTimeoutException { ResponseApdu localResponseApdu = new ResponseApdu(transceive(paramIsoDep, ApduUtil.buildReadCommand(paramByte1, paramByte2).command)); if (ApduUtil.matchesStatus(localResponseApdu, ResponseApdu.WRONG_LENGTH_LE)) { localResponseApdu = new ResponseApdu(transceive(paramIsoDep, ApduUtil.buildReadCommand(paramByte1, paramByte2, localResponseApdu.statusWord2).command)); } if (ApduUtil.matchesStatus(localResponseApdu, ResponseApdu.SUCCESS_SW)) { CreditCardNfcResult localCreditCardNfcResult = TlvUtil.parseCreditCardInfoFromTlv(TlvParser.parseTlv(localResponseApdu)); if (localCreditCardNfcResult != null) { return localCreditCardNfcResult; } } return null; }
private void onChallengeReceived() { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(getActivity()); if (adapter == null) { Toast.makeText(getActivity(), R.string.no_nfc, Toast.LENGTH_LONG).show(); } else if (adapter.isEnabled()) { Intent intent = getActivity().getIntent(); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent tagIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0); IntentFilter iso = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); ((MainActivity) getActivity()).setOnNFCListener(SignFragment.this); adapter.enableForegroundDispatch(getActivity(), tagIntent, new IntentFilter[]{iso}, new String[][]{new String[]{IsoDep.class.getName()}}); getView().findViewById(R.id.progressBar).setVisibility(View.INVISIBLE); ((TextView) getView().findViewById(R.id.status_text)).setText(R.string.swipe); } else { Toast.makeText(getActivity(), R.string.nfc_disabled, Toast.LENGTH_LONG).show(); } }
private void onChallengeReceived() { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(getActivity()); if (adapter == null) { Toast.makeText(getActivity(), R.string.no_nfc, Toast.LENGTH_LONG).show(); } else if (adapter.isEnabled()) { Intent intent = getActivity().getIntent(); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent tagIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0); IntentFilter iso = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); ((MainActivity) getActivity()).setOnNFCListener(EnrollFragment.this); adapter.enableForegroundDispatch(getActivity(), tagIntent, new IntentFilter[]{iso}, new String[][]{new String[]{IsoDep.class.getName()}}); getView().findViewById(R.id.progressBar).setVisibility(View.INVISIBLE); ((TextView) getView().findViewById(R.id.status_text)).setText(R.string.swipe); } else { Toast.makeText(getActivity(), R.string.nfc_disabled, Toast.LENGTH_LONG).show(); } }
private String doTransceiveUTF8(IsoDep iso, byte[] command) throws IOException { final byte[] ret = iso.transceive(command); Log.d(TAG, "Sent: " + ByteArrayToHexString(command) + "\nRecv: " + ByteArrayToHexString(ret)); final StringBuffer buffer = new StringBuffer(); for(int i = 1; i < ret.length; i++) { buffer.append((char)ret[i]); } final String retStr = buffer.toString(); Log.d(TAG, "UTF-8: " + retStr); return retStr; }
public static AndroidCard get(Tag tag) throws IOException { IsoDep card = IsoDep.get(tag); if(card != null) { /* Workaround for the Samsung Galaxy S5 (since the * first connection always hangs on transceive). * TODO: This could be improved if we could identify * Samsung Galaxy S5 devices */ card.connect(); card.close(); return new AndroidCard(card); } else { return null; } }
@Override protected String doInBackground(Tag... params) { Tag tag = params[0]; tagCommunicator = IsoDep.get(tag); try { tagCommunicator.connect(); tagCommunicator.setTimeout(5000); if (tagCommunicator.isConnected()) { readCard(); } } catch (IOException e) { e.printStackTrace(); } return null; }
public static AndroidCard get(Tag tag) throws IOException { IsoDep card = IsoDep.get(tag); /* Workaround for the Samsung Galaxy S5 (since the * first connection always hangs on transceive). * TODO: This could be improved if we could identify * Samsung Galaxy S5 devices */ card.connect(); card.close(); if(card != null) { return new AndroidCard(card); } else { return null; } }
@Override public void onTagDiscovered(Tag tag) { doTapFeedback(); clearImage(); // maybe clear console or show separator, depends on settings if (mAutoClear) { clearMessages(); } else { addMessageSeparator(); } // get IsoDep handle and run xcvr thread IsoDep isoDep = IsoDep.get(tag); if (isoDep == null) { onError(getString(R.string.wrong_tag_err)); } else { ReaderXcvr xcvr = new PaymentReaderXcvr(isoDep, "", this, TEST_MODE_EMV_READ); new Thread(xcvr).start(); } }
@Override public void onTagDiscovered(Tag tag) { doTapFeedback(); clearImage(); // maybe clear console or show separator, depends on settings if (mAutoClear) { clearMessages(); } else { // two separators between taps/discoveries addMessageSeparator(); addMessageSeparator(); } // get IsoDep handle and run xcvr thread IsoDep isoDep = IsoDep.get(tag); if (isoDep == null) { onError(getString(R.string.wrong_tag_err)); } else { List<SmartcardApp> memberApps = mGrpToMembersMap.get(mSelectedGrpPos); new Thread(new BatchReaderXcvr(isoDep, memberApps, this)).start(); } }
@Override public void onTagDiscovered(Tag tag) { if (Config.DEBUG) Log.d(TAG, "tag discovered: " + tag); if (!enabled) { if (Config.DEBUG) Log.d(TAG, "tag discovered, but InternalNfcTransceiver not enabled"); return; } isoDep = IsoDep.get(tag); try { isoDep.connect(); nfcInit.tagDiscovered(); } catch (IOException e) { if (Config.DEBUG) Log.e(TAG, "Could not connnect isodep: ", e); eventHandler.handleMessage(NfcEvent.INIT_FAILED, null); } }
/** * Send message via a Nfc connection. * * @param message The message in byte array form * @return The response from {@link NfcServerSocket}. null might be returned * if <li>the connection is lost. <li> {@link NfcServerSocket} does * not return response within timeout. <li> {@link NfcServerSocket} * returns a null response. */ public byte[] send(byte[] message) { if (currentTag == null) { return null; } if (isoDep == null) { isoDep = IsoDep.get(currentTag); } if (isoDep.isConnected()) { try { byte[] response = isoDep.transceive(message); return response; } catch (IOException e) { e.printStackTrace(); return null; } } else { log("isodep not connected"); return null; } }
/** * */ @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d(TAG, "onNewIntent Called"); if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { // validate that this tag can be written.... myStatusTextView.setText("tag detected"); pbCircular.setVisibility(View.VISIBLE); Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Log.d(TAG, detectedTag.toString()); Log.d(TAG, detectedTag.getTechList().toString()); this.isoDep = IsoDep.get(detectedTag); // Have the background task send the image fileSender.execute(imageBuffer); fileSender = new SendFileToWISP(this); }// end if }
@Override public void onNewIntent(Intent intent) { Log.i(TAG, "Discovered tag with intent: " + intent); if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) { tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); isotag = IsoDep.get(tag); if (isotag != null) { Log.i(TAG,"Found IsoDep tag!"); // Make sure we're not already communicating with a card if (activityState == STATE_IDLE) { askForPin(); } } } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // NFC stuff nfcA = NfcAdapter.getDefaultAdapter(getApplicationContext()); mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); // Setup an intent filter for all TECH based dispatches IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); mFilters = new IntentFilter[] { tech }; // Setup a tech list for all IsoDep cards mTechLists = new String[][] { new String[] { IsoDep.class.getName() } }; setState(STATE_IDLE); timer = new Timer(); timer.scheduleAtFixedRate(new CardPollerTask(), CARD_POLL_DELAY, CARD_POLL_DELAY); }
/** * Opens a connection with the ID by doing BAC * Uses hardcoded parameters for now * * @param tag - NFC tag that started this activity (ID NFC tag) * @return PassportService - passportservice that has an open connection with the ID */ public PassportService openConnection(Tag tag, final DocumentData docData) throws CardServiceException { try { IsoDep nfc = IsoDep.get(tag); CardService cs = CardService.getInstance(nfc); this.ps = new PassportService(cs); this.ps.open(); // Get the information needed for BAC from the data provided by OCR this.ps.sendSelectApplet(false); BACKeySpec bacKey = new BACKeySpec() { @Override public String getDocumentNumber() { return docData.getDocumentNumber(); } @Override public String getDateOfBirth() { return docData.getDateOfBirth(); } @Override public String getDateOfExpiry() { return docData.getExpiryDate(); } }; ps.doBAC(bacKey); return ps; } catch (CardServiceException ex) { try { ps.close(); } catch (Exception ex2) { ex2.printStackTrace(); } throw ex; } }
/** Contructor de la clase para la gestión de la conexión por NFC. * @param tag <code>Tag</code> para obtener el objeto <code>IsoDep</code> y establecer la * conexión. * @throws IOException Si falla el establecimiento de la conexión. */ public AndroidNfcConnection(final Tag tag) throws IOException { if (tag == null) { throw new IllegalArgumentException("El tag NFC no puede ser nulo"); //$NON-NLS-1$ } this.mIsoDep = IsoDep.get(tag); this.mIsoDep.connect(); this.mIsoDep.setTimeout(ISODEP_TIMEOUT); }
@Nullable private Tag getTag() { final IsoDep isoDep = mIsoDep.get(); if (isoDep != null) { return isoDep.getTag(); } return null; }
private byte[] concatNextResponseBytes(IsoDep isoDep, byte[] derResponse) throws IOException { int responseLength = DERParser.extractPayloadEndIndex(derResponse); Log.d(TAG, "transceiveDER - expected response length: " + responseLength + ", actual length: " + derResponse.length); while (derResponse.length < responseLength) { derResponse = ClientUtils.concatBytes(derResponse, transceiveKeepAlive(isoDep)); Log.d(TAG, "transceiveDER - had to ask for next bytes, length=" + derResponse.length); } return derResponse; }
private byte[] keepAliveLoop(IsoDep isoDep, byte[] derResponse) throws IOException { while (NFCUtils.isKeepAlive(derResponse) ) { Log.d(TAG, "transceiveDER - keep alive..."); derResponse = transceiveKeepAlive(isoDep); Log.d(TAG, "transceiveDER - keep alive done, got response, length=" + derResponse.length); } return derResponse; }
private void softResetNFC(final Tag tag) { try { Log.d(TAG, "try soft reset"); IsoDep isoDep = IsoDep.get(tag); isoDep.close(); isoDep.connect(); Log.d(TAG, "soft reset successful"); onTagDiscovered(tag, isoDep, false); } catch (Throwable e) { Log.d(TAG, "Soft reset failed", e); } }
@Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); if (intent != null && intent.getAction().equalsIgnoreCase(NfcAdapter.ACTION_TECH_DISCOVERED)) { Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); IsoDep isoDep = IsoDep.get(tag); if (isoDep != null) { new NFCAsyncTask().execute(isoDep); } } }
/** * Get ATS from isoDep * * @param pIso * isodep * @return ATS byte array */ private byte[] getAts(final IsoDep pIso) { byte[] ret = null; if (pIso.isConnected()) { // Extract ATS from NFC-A ret = pIso.getHistoricalBytes(); if (ret == null) { // Extract ATS from NFC-B ret = pIso.getHiLayerResponse(); } } return ret; }
private TravelCard readCardData(Intent intent) { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); IsoDep isoDep = IsoDep.get(tagFromIntent); try { isoDep.connect(); return CardOperations.readTravelCardData(isoDep); } catch (IOException ioErr) { Toast err = Toast.makeText(this, ioErr.getMessage(), Toast.LENGTH_LONG); err.show(); return new TravelCard(TravelCard.STATUS_NO_HSL_CARD); } }
public void onResume() { super.onResume(); Intent intent = getActivity().getIntent(); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent tagIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0); IntentFilter iso = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); adapter.enableForegroundDispatch(getActivity(), tagIntent, new IntentFilter[]{iso}, new String[][]{new String[]{IsoDep.class.getName()}}); }
public U2F_V2(IsoDep tag) throws IOException, APDUError { this.tag = tag; tag.setTimeout(5000); tag.connect(); try { send(SELECT_COMMAND); } catch (APDUError e) { if(e.getCode() == 0x6a82) { send(SELECT_COMMAND_YUBICO); } else { throw e; } } }
@Override protected void onNewIntent(Intent intent) { Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if(tag != null && nfc_listener != null) { nfc_listener.onNFC(IsoDep.get(tag)); } }
private void handleIntent(Intent intent) { final String action = intent.getAction(); if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) { Log.d(TAG, "TECH_DISCOVERED"); final Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); final IsoDep iso = IsoDep.get((Tag) tag); try { iso.connect(); doGetApps(iso); doSelectPICC(iso); doGetFileIDs(iso); final String expiry = doGetFile(iso, (byte)0x02, (byte)0x0A); final String idNumber = doGetFile(iso, (byte)0x03, (byte)0x09); fillFields(idNumber, expiry); iso.close(); } catch (IOException io) { Log.e(TAG, "Error communicating: " + io.toString()); } } }
static String getCardId(IsoDep isodep) { if (isodep != null) { byte[] id = isodep.getTag().getId(); if (id != null && id.length > 0) return Logger.toHexString(id, 0, id.length); } return "UNKNOWN"; }
static void disconnect(IsoDep tag) { try { if (tag != null) tag.close(); } catch (Exception e) { } }
static byte[] transceiveApdu(IsoDep tag, byte[] cmd) { if (tag != null) { try { if (!tag.isConnected()) { tag.connect(); tag.setTimeout(10000); } return tag.transceive(cmd); } catch (Exception e) { } } return null; }
private void enableForegroundDispatch(NfcAdapter adapter, Intent intent) { if(adapter.isEnabled()) { PendingIntent tagIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); IntentFilter tag = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); adapter.enableForegroundDispatch(activity, tagIntent, new IntentFilter[]{tag}, new String[][]{new String[]{IsoDep.class.getName()}}); } }
public static void readCard(IsoDep tech, Card card) throws InstantiationException, IllegalAccessException, IOException { final Iso7816.StdTag tag = new Iso7816.StdTag(tech); tag.connect(); for (final Class<?> g[] : readers) { HINT hint = HINT.RESETANDGONEXT; for (final Class<?> r : g) { final StandardPboc reader = (StandardPboc) r.newInstance(); switch (hint) { case RESETANDGONEXT: if (!reader.resetTag(tag)) continue; case GONEXT: hint = reader.readCard(tag, card); break; default: break; } if (hint == HINT.STOP) break; } } tag.close(); }