This commit is contained in:
septs 2025-02-26 13:02:50 +08:00
parent eca2acba8f
commit 5e7db370b0
Signed by: septs
SSH key fingerprint: SHA256:ElK0p6DNkbsqYUdJ3I9QHDVf21SQD0c2r+hd7s/r5Co
2 changed files with 27 additions and 27 deletions

View file

@ -18,49 +18,38 @@ class TelephonyManagerApduInterface(
const val TAG = "TelephonyManagerApduInterface"
}
override var valid: Boolean = false
override val valid: Boolean
get() = channels.isNotEmpty()
override fun connect() {
// Do nothing
}
private var channels = mutableSetOf<Int>()
override fun disconnect() {
// Do nothing
}
// Do nothing
override fun connect() {}
override fun disconnect() {}
override fun logicalChannelOpen(aid: ByteArray): Int {
val hex = aid.encodeHex()
val channel = tm.iccOpenLogicalChannelByPortCompat(port.card.physicalSlotIndex, port.portIndex, hex, 0)
if (channel.status != IccOpenLogicalChannelResponse.STATUS_NO_ERROR || channel.channel == IccOpenLogicalChannelResponse.INVALID_CHANNEL) {
throw IllegalArgumentException("Cannot open logical channel $hex via TelephonManager on slot ${port.card.physicalSlotIndex} port ${port.portIndex}")
throw IllegalArgumentException("Cannot open logical channel $hex via TelephonyManager on slot ${port.card.physicalSlotIndex} port ${port.portIndex}")
}
valid = true
channels.add(channel.channel)
return channel.channel
}
override fun logicalChannelClose(handle: Int) {
tm.iccCloseLogicalChannelByPortCompat(port.card.physicalSlotIndex, port.portIndex, handle)
valid = false
channels.remove(handle)
}
override fun transmit(handle: Int, tx: ByteArray): ByteArray {
if (runBlocking { verboseLoggingFlow.first() }) {
Log.d(TAG, "TelephonyManager APDU: ${tx.encodeHex()}")
}
val cla = tx[0].toUByte().toInt()
val ins = tx[1].toUByte().toInt()
val p1 = tx[2].toUByte().toInt()
val p2 = tx[3].toUByte().toInt()
val p3 = tx[4].toUByte().toInt()
val p4 = tx.drop(5).toByteArray().encodeHex()
// @formatter:off
val result = tm.iccTransmitApduLogicalChannelByPortCompat(
port.card.physicalSlotIndex, port.portIndex, handle,
cla, ins, p1, p2, p3, p4
tx,
)
// @formatter:on
if (runBlocking { verboseLoggingFlow.first() })
Log.d(TAG, "TelephonyManager APDU response: $result")
return result?.decodeHex() ?: byteArrayOf()

View file

@ -111,15 +111,26 @@ fun TelephonyManager.iccCloseLogicalChannelByPortCompat(
}
fun TelephonyManager.iccTransmitApduLogicalChannelByPortCompat(
slotIndex: Int, portIndex: Int, channel: Int,
cla: Int, inst: Int, p1: Int, p2: Int, p3: Int, data: String?
): String? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
slotIndex: Int,
portIndex: Int,
channel: Int,
tx: ByteArray
): String? {
val cla = tx[0].toUByte().toInt()
val ins = tx[1].toUByte().toInt()
val p1 = tx[2].toUByte().toInt()
val p2 = tx[3].toUByte().toInt()
val p3 = tx[4].toUByte().toInt()
val p4 = tx.drop(5).toByteArray().encodeHex()
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
iccTransmitApduLogicalChannelByPort(
slotIndex, portIndex, channel, cla, inst, p1, p2, p3, data
slotIndex, portIndex, channel,
cla, ins, p1, p2, p3, p4
)
} else {
iccTransmitApduLogicalChannelBySlot(
slotIndex, channel, cla, inst, p1, p2, p3, data
slotIndex, channel,
cla, ins, p1, p2, p3, p4
)
}
}