Skip to content

Commit

Permalink
Due to detection restrictions, require NXP
Browse files Browse the repository at this point in the history
  • Loading branch information
AbandonedCart committed Sep 11, 2023
1 parent e3d46a8 commit b3c7192
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 96 deletions.
49 changes: 13 additions & 36 deletions app/src/main/java/com/hiddenramblings/tagmo/nfctech/Infinity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import java.io.IOException
import java.math.BigInteger
import java.security.MessageDigest

class Infinity : TagTechnology {
class Infinity(mifare: MifareClassic?) : TagTechnology {

private val magicNumbers: Array<BigInteger> = arrayOf(
BigInteger("3"), BigInteger("5"),
Expand All @@ -28,51 +28,37 @@ class Infinity : TagTechnology {
)

private val tagMifare: MifareClassic?
private val tagNfcA: NfcA?
private var maxTransceiveLength: Int = 0

constructor(nfcA: NfcA?) {
tagNfcA = nfcA?.also {
maxTransceiveLength = it.maxTransceiveLength / 4 + 1
}
tagMifare = null
}

constructor(mifare: MifareClassic?) {
tagNfcA = null
init {
tagMifare = mifare?.also {
maxTransceiveLength = it.maxTransceiveLength / 4 + 1
}
}

@Suppress("unused")
var timeout: Int
get() = tagMifare?.timeout ?: tagNfcA?.timeout ?: 0
get() = tagMifare?.timeout ?: 0
set(timeout) {
tagMifare?.timeout = timeout
tagNfcA?.timeout = timeout
}

@Throws(IOException::class)
override fun connect() {
tagMifare?.connect() ?: tagNfcA?.connect()
tagMifare?.connect()
}

override fun isConnected(): Boolean {
return tagMifare?.isConnected ?: tagNfcA?.isConnected ?: false
}

fun isClassic1K() : Boolean {
return (tagMifare?.size == MifareClassic.SIZE_1K)
return tagMifare?.isConnected ?: false
}

@Throws(IOException::class)
override fun close() {
tagMifare?.close() ?: tagNfcA?.close()
tagMifare?.close()
}

override fun getTag(): Tag? {
return tagMifare?.tag ?: tagNfcA?.tag
return tagMifare?.tag
}

private fun keyInfinity(uid: String) : ByteArray {
Expand All @@ -93,8 +79,11 @@ class Infinity : TagTechnology {
)
}

@Throws(IOException::class)
fun authenticate() {
tagMifare?.let {
if (it.size != MifareClassic.SIZE_1K)
throw IOException(TagMo.appContext.getString(R.string.error_tag_format))
val keyA = keyInfinity(it.tag.id.toHex())
it.authenticateSectorWithKeyA(0, keyA)
Debug.warn(Companion::class.java, keyA.toHex())
Expand All @@ -104,7 +93,7 @@ class Infinity : TagTechnology {

fun transceive(data: ByteArray?): ByteArray? {
return try {
tagMifare?.transceive(data) ?: tagNfcA?.transceive(data)
tagMifare?.transceive(data)
} catch (e: IOException) {
Debug.warn(e)
null
Expand All @@ -115,25 +104,13 @@ class Infinity : TagTechnology {

private infix fun Short.equals(i: Int): Boolean = this == i.toShort()

private fun getMifareClasssic(tag: Tag?): Infinity? {
return MifareClassic.get(tag)?.let { Infinity(it) }
}

private fun getNfcA(tag: Tag?): Infinity? {
operator fun get(tag: Tag?): Infinity? {
return NfcA.get(tag)?.let {
if (it.sak equals 0x09 && it.atqa.equals(byteArrayOf(0x00, 0x44)))
Infinity(it)
MifareClassic.get(tag)?.let { mifare -> Infinity(mifare) }
else
null
}
}

operator fun get(tag: Tag?): Infinity? {
return try {
getMifareClasssic(tag)?.also { it.connect() }
} catch (e: IOException) {
getNfcA(tag)?.also { it.connect() }
} ?: getNfcA(tag)?.also { it.connect() }
}
}
}
53 changes: 28 additions & 25 deletions app/src/main/java/com/hiddenramblings/tagmo/nfctech/NfcActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ class NfcActivity : AppCompatActivity() {

private var isEliteIntent = false
private var isEliteDevice = false
private var infinity: Infinity? = null
private var ntag215: NTAG215? = null
private var skylanders: Skylanders? = null
private var infinity: Infinity? = null
private var writeCount = 0
private var tagTech: String? = null
private var hasTestedElite = false
Expand Down Expand Up @@ -256,29 +256,6 @@ class NfcActivity : AppCompatActivity() {
}
}

private suspend fun onMifareClassic(tag: Tag?) = withContext(Dispatchers.IO) {
val command = intent
val mode = command.action
try {
skylanders = Skylanders[tag]
skylanders?.let { mifare ->
// mifare.connect()
mifare.authenticate()
}
} catch (e: Exception) {
Debug.warn(e)
Debug.getExceptionCause(e)?.let { error ->

} ?: {
showError(getString(R.string.error_unknown))
try {
Debug.processLogcat(this@NfcActivity)
} catch (ignored: IOException) {
}
}
}
}

private suspend fun onMifareUltralight(tag: Tag?) = withContext(Dispatchers.IO) {
val command = intent
val mode = command.action
Expand All @@ -287,7 +264,6 @@ class NfcActivity : AppCompatActivity() {
ntag215 = if (NFCIntent.ACTION_BLIND_SCAN == mode || isEliteIntent)
NTAG215.getBlind(tag) else NTAG215[tag]
ntag215?.let { mifare ->
// mifare.connect()
if (!hasTestedElite) {
hasTestedElite = true
if (mifare.isPowerTag) {
Expand Down Expand Up @@ -647,6 +623,33 @@ class NfcActivity : AppCompatActivity() {
}
}

private suspend fun onMifareClassic(tag: Tag?) = withContext(Dispatchers.IO) {
val command = intent
val mode = command.action
try {
skylanders = Skylanders[tag]
infinity = Infinity[tag]
skylanders?.let { mifare ->
mifare.authenticate()
} ?: infinity?.let { mifare ->
mifare.authenticate()
} ?: {
showError(getString(R.string.error_nxp_required))
}
} catch (e: Exception) {
Debug.warn(e)
Debug.getExceptionCause(e)?.let { error ->

} ?: {
showError(getString(R.string.error_unknown))
try {
Debug.processLogcat(this@NfcActivity)
} catch (ignored: IOException) {
}
}
}
}

private suspend fun onTagDiscovered(intent: Intent) = withContext(Dispatchers.IO) {
setResult(RESULT_CANCELED)
val tag = intent.parcelable<Tag>(NfcAdapter.EXTRA_TAG)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import com.google.android.material.snackbar.Snackbar
import com.hiddenramblings.tagmo.BrowserActivity
import com.hiddenramblings.tagmo.BuildConfig
import com.hiddenramblings.tagmo.NFCIntent
import com.hiddenramblings.tagmo.Preferences
import com.hiddenramblings.tagmo.R
Expand Down Expand Up @@ -44,7 +43,6 @@ class ScanTag {
try {
mifare = NTAG215[tag]
mifare?.let { ntag ->
// ntag.connect()
if (!hasTestedElite) {
hasTestedElite = true
if (ntag.isPowerTag && prefs.eliteEnabled()) isEliteDevice = ntag.isElite
Expand Down
47 changes: 14 additions & 33 deletions app/src/main/java/com/hiddenramblings/tagmo/nfctech/Skylanders.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,52 +17,42 @@ import com.hiddenramblings.tagmo.nfctech.TagArray.toHexByteArray
import java.io.IOException
import java.math.BigInteger

class Skylanders : TagTechnology {
class Skylanders(mifare: MifareClassic?) : TagTechnology {

private val magicNumbers = listOf(2, 3, 73, 1103, 2017, 560381651, 12868356821)

private val tagMifare: MifareClassic?
private val tagNfcA: NfcA?
private var maxTransceiveLength: Int = 0

constructor(nfcA: NfcA?) {
tagNfcA = nfcA?.also {
maxTransceiveLength = it.maxTransceiveLength / 4 + 1
}
tagMifare = null
}

constructor(mifare: MifareClassic?) {
tagNfcA = null
init {
tagMifare = mifare?.also {
maxTransceiveLength = it.maxTransceiveLength / 4 + 1
}
}

@Suppress("unused")
var timeout: Int
get() = tagMifare?.timeout ?: tagNfcA?.timeout ?: 0
get() = tagMifare?.timeout ?: 0
set(timeout) {
tagMifare?.timeout = timeout
tagNfcA?.timeout = timeout
}

@Throws(IOException::class)
override fun connect() {
tagMifare?.connect() ?: tagNfcA?.connect()
tagMifare?.connect()
}

override fun isConnected(): Boolean {
return tagMifare?.isConnected ?: tagNfcA?.isConnected ?: false
return tagMifare?.isConnected ?: false
}

@Throws(IOException::class)
override fun close() {
tagMifare?.close() ?: tagNfcA?.close()
tagMifare?.close()
}

override fun getTag(): Tag? {
return tagMifare?.tag ?: tagNfcA?.tag
return tagMifare?.tag
}

private fun pseudoCrc48(crc: Long, data: List<Int>): Long {
Expand Down Expand Up @@ -102,8 +92,11 @@ class Skylanders : TagTechnology {
.joinToString("") { "%02x".format(it) }).toHexByteArray()
}

@Throws(IOException::class)
fun authenticate() {
tagMifare?.let {
if (it.size != MifareClassic.SIZE_1K)
throw IOException(TagMo.appContext.getString(R.string.error_tag_format))
for (sector in 0 until 16) {
val keyA = keySkylanders(it.tag.id.toHex(), sector)
it.authenticateSectorWithKeyA(sector, keyA)
Expand All @@ -114,7 +107,7 @@ class Skylanders : TagTechnology {

fun transceive(data: ByteArray?): ByteArray? {
return try {
tagMifare?.transceive(data) ?: tagNfcA?.transceive(data)
tagMifare?.transceive(data)
} catch (e: IOException) {
Debug.warn(e)
null
Expand All @@ -125,25 +118,13 @@ class Skylanders : TagTechnology {

private infix fun Short.equals(i: Int): Boolean = this == i.toShort()

private fun getMifareClasssic(tag: Tag?): Skylanders? {
return MifareClassic.get(tag)?.let { Skylanders(it) }
}

private fun getNfcA(tag: Tag?): Skylanders? {
operator fun get(tag: Tag?): Skylanders? {
return NfcA.get(tag)?.let {
if (it.sak equals 0x09 && it.atqa.equals(byteArrayOf(0x00, 0x44)))
Skylanders(it)
if (it.sak equals 0x01 && it.atqa.equals(byteArrayOf(0x0F, 0x01)))
MifareClassic.get(tag)?.let { mifare -> Skylanders(mifare) }
else
null
}
}

operator fun get(tag: Tag?): Skylanders? {
return try {
getMifareClasssic(tag)?.also { it.connect() }
} catch (e: IOException) {
getNfcA(tag)?.also { it.connect() }
} ?: getNfcA(tag)?.also { it.connect() }
}
}
}
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@
<string name="error_auth_null">Auth result was null</string>
<string name="error_archive_format">Zip encoding not supported</string>
<string name="error_unknown">An unknown error has occurred.</string>
<string name="error_tag_format">Mifare Classic 1K required!</string>
<string name="error_nxp_required">NXP chipset is required!</string>

<string name="fail_update_git">Unable to contact update server!</string>
<string name="fail_update_url">Update invalid! Please try again.</string>
Expand Down

0 comments on commit b3c7192

Please sign in to comment.