Updated on 2026-08-14

This commit is contained in:
Tangem 2020-05-08 10:37:04 +03:00
parent 895b659df7
commit 7f29eea629
19 changed files with 56 additions and 48 deletions

View file

@ -59,14 +59,6 @@ sealed class TangemSdkError(val code: Int) : Exception(code.toString()) {
*/
class NeedEncryption : TangemSdkError(30006)
class Pin1Changed : TangemSdkError(30007)
class Pin2Changed : TangemSdkError(30008)
class PinsChanged : TangemSdkError(30009)
//Personalization Errors
class AlreadyPersonalized : TangemSdkError(40101)
@ -77,12 +69,12 @@ sealed class TangemSdkError(val code: Int) : Exception(code.toString()) {
class Pin1Required : TangemSdkError(40401)
/**
* This error is returned when a [Task] expects a user to use a particular card,
* and a user tries to use a different card.
* but the user tries to use a different card.
*/
class WrongCard : TangemSdkError(40403)
/**
* This error is returned when a user scans a card of a [com.tangem.common.extensions.CardType]
* that is not specified in [Config.allowedCards].
* that is not specified in [Config.cardFilter].
*/
class WrongCardType : TangemSdkError(40404)

View file

@ -70,7 +70,7 @@ class CheckWalletCommand(
}
}
override fun handlePreRunErrors(
override fun performPreCheck(
session: CardSession,
callback: (result: CompletionResult<CheckWalletResponse>) -> Unit
): Boolean {

View file

@ -40,24 +40,24 @@ abstract class Command<T : CommandResponse> : CardSessionRunnable<T> {
override fun run(session: CardSession, callback: (result: CompletionResult<T>) -> Unit) {
Log.i("Command", "Sending ${this::class.java.simpleName}")
if (session.environment.handleErrors) {
if (handlePreRunErrors(session, callback)) return
if (performPreCheck(session, callback)) return
}
transceive(session) { result ->
if (session.environment.handleErrors) {
if (handleResponseErrors(session, result, callback)) return@transceive
if (performAfterCheck(session, result, callback)) return@transceive
}
callback(result)
}
}
open fun handlePreRunErrors(session: CardSession,
callback: (result: CompletionResult<T>) -> Unit): Boolean {
open fun performPreCheck(session: CardSession,
callback: (result: CompletionResult<T>) -> Unit): Boolean {
return false
}
open fun handleResponseErrors(session: CardSession,
result: CompletionResult<T>,
callback: (result: CompletionResult<T>) -> Unit): Boolean {
open fun performAfterCheck(session: CardSession,
result: CompletionResult<T>,
callback: (result: CompletionResult<T>) -> Unit): Boolean {
return false
}

View file

@ -39,7 +39,7 @@ class CreateWalletResponse(
*/
class CreateWalletCommand : Command<CreateWalletResponse>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true
@ -59,9 +59,9 @@ class CreateWalletCommand : Command<CreateWalletResponse>() {
return false
}
override fun handleResponseErrors(session: CardSession,
result: CompletionResult<CreateWalletResponse>,
callback: (result: CompletionResult<CreateWalletResponse>) -> Unit): Boolean {
override fun performAfterCheck(session: CardSession,
result: CompletionResult<CreateWalletResponse>,
callback: (result: CompletionResult<CreateWalletResponse>) -> Unit): Boolean {
when (result) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.InvalidParams) {

View file

@ -31,7 +31,7 @@ class PurgeWalletResponse(
*/
class PurgeWalletCommand : Command<PurgeWalletResponse>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<PurgeWalletResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<PurgeWalletResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true
@ -47,9 +47,9 @@ class PurgeWalletCommand : Command<PurgeWalletResponse>() {
return false
}
override fun handleResponseErrors(session: CardSession,
result: CompletionResult<PurgeWalletResponse>,
callback: (result: CompletionResult<PurgeWalletResponse>) -> Unit): Boolean {
override fun performAfterCheck(session: CardSession,
result: CompletionResult<PurgeWalletResponse>,
callback: (result: CompletionResult<PurgeWalletResponse>) -> Unit): Boolean {
when (result) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.InvalidParams) {

View file

@ -1,7 +1,9 @@
package com.tangem.commands
import com.tangem.CardSession
import com.tangem.SessionEnvironment
import com.tangem.TangemSdkError
import com.tangem.common.CompletionResult
import com.tangem.common.apdu.CommandApdu
import com.tangem.common.apdu.Instruction
import com.tangem.common.apdu.ResponseApdu
@ -366,6 +368,19 @@ class Card(
*/
class ReadCommand : Command<Card>() {
override fun performAfterCheck(session: CardSession, result: CompletionResult<Card>, callback: (result: CompletionResult<Card>) -> Unit): Boolean {
when (result) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.InvalidParams) {
callback(CompletionResult.Failure(TangemSdkError.Pin1Required()))
return true
}
return false
}
else -> return false
}
}
override fun serialize(environment: SessionEnvironment): CommandApdu {
val tlvBuilder = TlvBuilder()
/**

View file

@ -90,7 +90,7 @@ class ReadIssuerDataCommand(
}
}
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<ReadIssuerDataResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<ReadIssuerDataResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true

View file

@ -51,7 +51,7 @@ class ReadUserDataResponse(
*/
class ReadUserDataCommand : Command<ReadUserDataResponse>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<ReadUserDataResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<ReadUserDataResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true

View file

@ -37,7 +37,7 @@ class SignCommand(private val hashes: Array<ByteArray>)
private val hashSizes = if (hashes.isNotEmpty()) hashes.first().size else 0
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<SignResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<SignResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true
@ -73,9 +73,9 @@ class SignCommand(private val hashes: Array<ByteArray>)
return false
}
override fun handleResponseErrors(session: CardSession,
result: CompletionResult<SignResponse>,
callback: (result: CompletionResult<SignResponse>) -> Unit): Boolean {
override fun performAfterCheck(session: CardSession,
result: CompletionResult<SignResponse>,
callback: (result: CompletionResult<SignResponse>) -> Unit): Boolean {
when (result) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.InvalidParams) {

View file

@ -40,7 +40,7 @@ class WriteIssuerDataCommand(
verifier: IssuerDataVerifier = DefaultIssuerDataVerifier()
) : Command<WriteIssuerDataResponse>(), IssuerDataVerifier by verifier {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit): Boolean {
val card = session.environment.card
if (card == null) {
callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead()))
@ -74,9 +74,9 @@ class WriteIssuerDataCommand(
return false
}
override fun handleResponseErrors(session: CardSession,
result: CompletionResult<WriteIssuerDataResponse>,
callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit
override fun performAfterCheck(session: CardSession,
result: CompletionResult<WriteIssuerDataResponse>,
callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit
): Boolean {
when (result) {
is CompletionResult.Failure -> {

View file

@ -73,7 +73,7 @@ class WriteIssuerExtraDataCommand(
}
}
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<WriteIssuerDataResponse>) -> Unit): Boolean {
val card = session.environment.card
if (card == null) {
callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead()))

View file

@ -34,7 +34,7 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val
private val userCounter: Int? = null,
private val userProtectedCounter: Int? = null) : Command<WriteUserDataResponse>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<WriteUserDataResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<WriteUserDataResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true
@ -50,9 +50,9 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val
return false
}
override fun handleResponseErrors(session: CardSession,
result: CompletionResult<WriteUserDataResponse>,
callback: (result: CompletionResult<WriteUserDataResponse>) -> Unit
override fun performAfterCheck(session: CardSession,
result: CompletionResult<WriteUserDataResponse>,
callback: (result: CompletionResult<WriteUserDataResponse>) -> Unit
): Boolean {
when (result) {
is CompletionResult.Failure -> {

View file

@ -21,7 +21,7 @@ data class DepersonalizeResponse(val success: Boolean) : CommandResponse
*/
class DepersonalizeCommand : Command<DepersonalizeResponse>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<DepersonalizeResponse>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<DepersonalizeResponse>) -> Unit): Boolean {
if (session.environment.card?.status == CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
return true

View file

@ -39,7 +39,7 @@ class PersonalizeCommand(
private val acquirer: Acquirer? = null
) : Command<Card>() {
override fun handlePreRunErrors(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit): Boolean {
override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit): Boolean {
if (session.environment.card?.status != CardStatus.NotPersonalized) {
callback(CompletionResult.Failure(TangemSdkError.AlreadyPersonalized()))
return true

View file

@ -14,7 +14,7 @@ class TlvBuilder {
fun serialize(): ByteArray {
Log.v("TLV",
"List of TLV that are being sent to a card:\n${tlvs.joinToString("\n")}")
"List of encoded TLVs:\n${tlvs.joinToString("\n")}")
return tlvs.serialize()
}

View file

@ -20,7 +20,7 @@ class TlvDecoder(val tlvList: List<Tlv>) {
init {
Log.v("TLV",
"List of TLV received from card:\n${tlvList.joinToString("\n")}")
"List of decoded TLVs:\n${tlvList.joinToString("\n")}")
}
/**

View file

@ -9,8 +9,8 @@ android {
applicationId "com.tangem.devkit"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
versionCode 3
versionName "1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View file

@ -18,7 +18,7 @@ class TlvResources {
holder.register(TlvId.TransactionOutHash, Resources(R.string.tlv_transaction_out_hash, R.string.info_tlv_transaction_out_hash))
holder.register(TlvId.Counter, Resources(R.string.tlv_counter, R.string.info_tlv_counter))
holder.register(TlvId.IssuerData, Resources(R.string.tlv_issuer_data, R.string.info_tlv_issuer_data))
holder.register(TlvId.UserData, Resources(R.string.tlv_issuer_data, R.string.info_tlv_user_data))
holder.register(TlvId.UserData, Resources(R.string.tlv_user_data, R.string.info_tlv_user_data))
holder.register(TlvId.ProtectedUserData, Resources(R.string.tlv_user_protected_data, R.string.info_tlv_protected_user_data))
}
}

View file

@ -80,6 +80,7 @@ class NfcReader : CardReader {
isoDep = null
return
} catch (exception: Exception) {
Log.i(this::class.simpleName!!, exception.localizedMessage ?: "Error tranceiving data")
isoDep = null
return
}