Updated on 2026-08-14

This commit is contained in:
Tangem 2018-06-27 23:04:50 +03:00
parent a952d32b15
commit 0fab3ec90e
13 changed files with 777 additions and 351 deletions

View file

@ -0,0 +1,100 @@
package com.tangem.data.nfc;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
public class CreateNewWalletTask extends Thread {
public static final String TAG = CreateNewWalletTask.class.getSimpleName();
private Context mContext;
private TangemCard mCard;
private NfcManager mNfcManager;
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public CreateNewWalletTask(Context context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
mCard = card;
mContext = context;
mNfcManager = nfcManager;
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
try {
// for Samsung's bugs -
// Workaround for the Samsung Galaxy S5 (since the
// first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
mNotifications.OnReadProgress(protocol, 5);
Log.i(TAG, "[-- Start create new wallet --]");
if (isCancelled) return;
protocol.run_VerifyCard();
Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
mNotifications.OnReadProgress(protocol, 30);
if (isCancelled) return;
// if (mCard.getPauseBeforePIN2() > 0) {
// mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
// }
// try {
protocol.run_CreateWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 60);
if (isCancelled) return;
protocol.run_Read();
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish create new wallet --]");
mNotifications.OnReadFinish(protocol);
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,101 @@
package com.tangem.data.nfc;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
public class PurgeTask extends Thread {
public static final String TAG = PurgeTask.class.getSimpleName();
private String txOutAddress;
private Context mContext;
private TangemCard mCard;
private NfcManager mNfcManager;
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public PurgeTask(Context context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
mCard = card;
mContext = context;
mNfcManager = nfcManager;
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
try {
// for Samsung's bugs - Workaround for the Samsung Galaxy S5 (since the first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
mNotifications.OnReadProgress(protocol, 5);
Log.i(TAG, "[-- Start purge --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_PurgeWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
if (isCancelled)
return;
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,167 @@
package com.tangem.data.nfc;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.util.Util;
import java.util.ArrayList;
public class ReadCardInfoTask extends Thread {
public static final String TAG = ReadCardInfoTask.class.getSimpleName();
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
private Context mContext;
private NfcManager mNfcManager;
private ArrayList<String> lastRead_UnsuccessfullPINs = new ArrayList<>();
private TangemCard.EncryptionMode lastRead_Encryption = null;
private String lastRead_UID;
public ReadCardInfoTask(Context context, NfcManager nfcManager, String lastRead_UID, IsoDep isoDep, CardProtocol.Notifications notifications) {
mContext = context;
mIsoDep = isoDep;
mNotifications = notifications;
mNfcManager = nfcManager;
this.lastRead_UID = lastRead_UID;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
try {
// for Samsung's bugs -
// Workaround for the Samsung Galaxy S5 (since the
// first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mNotifications);
mNotifications.OnReadStart(protocol);
try {
mNotifications.OnReadProgress(protocol, 5);
byte[] UID = mIsoDep.getTag().getId();
String sUID = Util.byteArrayToHexString(UID);
if (!lastRead_UID.equals(sUID)) {
lastRead_UID = sUID;
lastRead_UnsuccessfullPINs.clear();
lastRead_Encryption = null;
}
Log.i(TAG, "[-- Start read card info --]");
if (isCancelled) return;
protocol.setPIN(PINStorage.getDefaultPIN());
protocol.clearReadResult();
if (lastRead_Encryption == null) {
Log.i(TAG, "Try get supported encryption mode");
protocol.run_GetSupportedEncryption();
} else {
Log.i(TAG, "Use already defined encryption mode: " + lastRead_Encryption.name());
protocol.getCard().encryptionMode = lastRead_Encryption;
}
if (protocol.haveReadResult()) {
//already have read result (obtained while get supported encryption), only read issuer data and define offline balance
protocol.parseReadResult();
protocol.run_ReadOrWriteIssuerDataAndDefineOfflineBalance();
mNotifications.OnReadProgress(protocol, 60);
PINStorage.setLastUsedPIN(protocol.getCard().getPIN());
} else {
//don't have read result - may be don't get supported encryption on this try, need encryption or need another PIN
if (lastRead_Encryption == null) {
// we try get supported encryption on this time
lastRead_Encryption = protocol.getCard().encryptionMode;
if (protocol.getCard().encryptionMode == TangemCard.EncryptionMode.None) {
// default pin not accepted
lastRead_UnsuccessfullPINs.add(PINStorage.getDefaultPIN());
}
}
boolean pinFound = false;
for (String PIN : PINStorage.getPINs()) {
Log.e(TAG, "PIN: " + PIN);
boolean skipPin = false;
for (int i = 0; i < lastRead_UnsuccessfullPINs.size(); i++) {
if (lastRead_UnsuccessfullPINs.get(i).equals(PIN)) {
skipPin = true;
break;
}
}
if (skipPin) {
Log.e(TAG, "Skip PIN - already checked before");
continue;
}
try {
protocol.setPIN(PIN);
if (protocol.getCard().encryptionMode != TangemCard.EncryptionMode.None) {
protocol.CreateProtocolKey();
}
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 60);
PINStorage.setLastUsedPIN(PIN);
pinFound = true;
protocol.getCard().setPIN(PIN);
break;
} catch (CardProtocol.TangemException_InvalidPIN e) {
Log.e(TAG, e.getMessage());
lastRead_UnsuccessfullPINs.add(PIN);
}
}
if (!pinFound) {
throw new CardProtocol.TangemException_InvalidPIN("No valid PIN found!");
}
}
protocol.run_CheckPIN2isDefault();
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish read card info --]");
mNotifications.OnReadFinish(protocol);
}
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,150 @@
package com.tangem.data.nfc;
import android.app.Activity;
import android.content.Intent;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.Blockchain;
import com.tangem.domain.wallet.CoinEngine;
import com.tangem.domain.wallet.CoinEngineFactory;
import com.tangem.domain.wallet.LastSignStorage;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.presentation.activity.SendTransactionActivity;
import com.tangem.presentation.activity.SignPaymentActivity;
import com.tangem.util.BTCUtils;
public class SignPaymentTask extends Thread {
public static final String TAG = SignPaymentTask.class.getSimpleName();
private String txAmount = "";
private String txFee = "";
public void SetTransactionValue(String amount, String fee) {
txAmount = amount;
txFee = fee;
}
private String txOutAddress;
private Activity mContext;
private TangemCard mCard;
private NfcManager mNfcManager;
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public SignPaymentTask(Activity context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, String amount, String fee, String outAddress) {
mCard = card;
mContext = context;
mNfcManager = nfcManager;
mIsoDep = isoDep;
mNotifications = notifications;
txOutAddress = outAddress;
SetTransactionValue(amount, fee);
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
try {
// for Samsung's bugs -
// Workaround for the Samsung Galaxy S5 (since the
// first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
mNotifications.OnReadProgress(protocol, 5);
Log.i(TAG, "[-- Start sign payment --]");
if (isCancelled) return;
protocol.run_VerifyCard();
Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
mNotifications.OnReadProgress(protocol, 30);
if (isCancelled) return;
//
// if (mCard.getBlockchain() == Blockchain.Ethereum) {
// SignETH_TX(protocol);
// } else {
// SignBTC_TX(protocol);
// }
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (engine != null) {
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
byte[] tx;
// try {
tx = engine.Sign(txFee, txAmount, txOutAddress, mCard, protocol);
// }
// finally {
// mNotifications.OnReadWait(0);
// }
if (tx != null) {
String txStr = BTCUtils.toHex(tx);
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet || mCard.getBlockchain() == Blockchain.Token) {
txStr = String.format("0x%s", txStr);
}
LastSignStorage.setLastTX(mCard.getWallet(), txStr);
Intent intent = new Intent(mContext, SendTransactionActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
intent.putExtra("TX", txStr);
mContext.startActivityForResult(intent, SignPaymentActivity.REQUEST_CODE_SEND_PAYMENT);
}
}
mNotifications.OnReadProgress(protocol, 100);
if (isCancelled) return;
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (CardProtocol.TangemException_InvalidPIN e) {
e.printStackTrace();
protocol.setError(e);
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish sign payment --]");
mNotifications.OnReadFinish(protocol);
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,105 @@
package com.tangem.data.nfc;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
public class SwapPINTask extends Thread {
public static final String TAG = SwapPINTask.class.getSimpleName();
private Context mContext;
private TangemCard mCard;
private NfcManager mNfcManager;
private String newPIN, newPIN2;
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public SwapPINTask(Context context, TangemCard card, NfcManager nfcManager, String newPIN, String newPIN2, IsoDep isoDep, CardProtocol.Notifications notifications) {
this.newPIN = newPIN;
this.newPIN2 = newPIN2;
mCard = card;
mContext = context;
mNfcManager = nfcManager;
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
try {
// for Samsung's bugs -
// Workaround for the Samsung Galaxy S5 (since the
// first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
mNotifications.OnReadProgress(protocol, 5);
Log.i(TAG, "[-- Start swap pin --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_SwapPIN(PINStorage.getPIN2(), newPIN, newPIN2, false);
protocol.setPIN(newPIN);
mCard.setPIN(newPIN);
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,110 @@
package com.tangem.data.nfc;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
/**
* Created by dvol on 04.02.2018.
*/
public class VerifyCardTask extends Thread {
public static final String TAG = VerifyCardTask.class.getSimpleName();
private IsoDep mIsoDep;
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
private Context mContext;
private TangemCard mCard;
private NfcManager mNfcManager;
public VerifyCardTask(Context context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
mCard = card;
mContext = context;
mIsoDep = isoDep;
mNotifications = notifications;
mNfcManager = nfcManager;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
try {
// for Samsung's bugs -
// Workaround for the Samsung Galaxy S5 (since the
// first connection always hangs on transceive).
int timeout = mIsoDep.getTimeout();
mIsoDep.connect();
mIsoDep.close();
mIsoDep.connect();
mIsoDep.setTimeout(timeout);
try {
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
try {
mNotifications.OnReadProgress(protocol, 5);
Log.i(TAG, "[-- Start verify card --]");
if (isCancelled) return;
String PIN = mCard.getPIN();
protocol.setPIN(PIN);
protocol.run_Read();
PINStorage.setLastUsedPIN(PIN);
mNotifications.OnReadProgress(protocol, 30);
if (isCancelled) return;
protocol.run_VerifyCard();
mNotifications.OnReadProgress(protocol, 60);
Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
if (isCancelled) return;
if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) {
protocol.run_CheckWalletWithSignatureVerify();
mNotifications.OnReadProgress(protocol, 90);
}
// if (isCancelled) return;
// if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) {
// protocol.run_CheckWithSignatureVerify();
// }
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i(TAG, "[-- Finish verify card --]");
mNotifications.OnReadFinish(protocol);
}
} finally {
mNfcManager.ignoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void cancel(Boolean AllowInterrupt) {
try {
if (isAlive()) {
isCancelled = true;
join(500);
}
if (isAlive() && AllowInterrupt) {
interrupt();
mNotifications.OnReadCancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}