Updated on 2026-08-14
This commit is contained in:
parent
895b659df7
commit
7f29eea629
19 changed files with 56 additions and 48 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class CheckWalletCommand(
|
|||
}
|
||||
}
|
||||
|
||||
override fun handlePreRunErrors(
|
||||
override fun performPreCheck(
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CheckWalletResponse>) -> Unit
|
||||
): Boolean {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 -> {
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
|
|
|
|||
|
|
@ -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 -> {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")}")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue