Skip to content

Commit 04d543d

Browse files
committed
feat(Android): add withBlock method for read/write, example in App.tsx
1 parent 7b3b1e7 commit 04d543d

File tree

5 files changed

+284
-78
lines changed

5 files changed

+284
-78
lines changed

android/src/main/java/com/pos/CardManager.kt

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -70,47 +70,11 @@ abstract class CardManager {
7070
}
7171

7272
open suspend fun readRecordsFromCard(options: ReadableArray, promise: Promise) {
73-
val readableArray = Arguments.createArray()
74-
val readableMap = Arguments.createMap()
75-
readableMap.putString("cardId", cardId)
76-
readableMap.putString("samId", samId)
77-
7873
try {
7974
waitForCard()
8075
connectCard()
8176

82-
options.toArrayList().forEach {
83-
it as HashMap<*, *>
84-
val application = it["application"] as ArrayList<Int>
85-
val sfi = (it["sfi"] as Double).toInt()
86-
val offset = (it["offset"] as Double).toInt()
87-
val readMode = when ((it["readMode"] as Double).toInt()) {
88-
1 -> CardReadRecordsBuilder.ReadMode.MULTIPLE_RECORD
89-
else -> CardReadRecordsBuilder.ReadMode.ONE_RECORD
90-
}
91-
92-
selectApplication(application.map { it.toByte() }.toByteArray())
93-
selectFileBuilder()
94-
val readRecordsParser = readRecordsFromSfi(sfi, offset, readMode)
95-
96-
val records: Map<Int, ByteArray> = readRecordsParser.records
97-
98-
val resultMap = Arguments.createMap()
99-
val recordsMap = Arguments.createMap()
100-
101-
for ((key, record) in records) {
102-
val array = ByteConvertReactNativeUtil.byteArrayToReadableArray(record)
103-
recordsMap.putArray(key.toString(), array)
104-
}
105-
106-
resultMap.putInt("sfi", sfi)
107-
resultMap.putMap("records", recordsMap)
108-
109-
readableArray.pushMap(resultMap)
110-
}
111-
112-
readableMap.putArray("data", readableArray)
113-
promise.resolve(readableMap)
77+
read(options, promise)
11478
} catch (e: Throwable) {
11579
e.printStackTrace()
11680
promise.reject(
@@ -131,29 +95,7 @@ abstract class CardManager {
13195
waitForCard()
13296
connectCard()
13397

134-
options.toArrayList().forEach {
135-
it as HashMap<*, *>
136-
val apdu = it["apdu"] as ArrayList<Int>
137-
val application = it["application"] as ArrayList<Int>
138-
val sfi = (it["sfi"] as Double).toInt()
139-
val offset = (it["offset"] as Double).toInt()
140-
val samUnlockString = it["samUnlockString"] as String
141-
142-
val newRecord = apdu.map { it.toByte() }.toByteArray();
143-
144-
val selectApplicationParser = selectApplication(ByteConvertReactNativeUtil.arrayListToByteArray(application))
145-
unlockSam(samUnlockString)
146-
selectSamDiversifier(selectApplicationParser)
147-
val samChallengeParser = samChallenge()
148-
val openSession3Parser = openSession3(samChallengeParser, sfi, offset)
149-
samDigestInit(openSession3Parser)
150-
updateRecord(sfi, offset, newRecord)
151-
val samDigestCloseParser = samDigestClose()
152-
val closeSession3Parser = closeSession3(samDigestCloseParser)
153-
samDigestAuthenticate(closeSession3Parser)
154-
}
155-
156-
promise.resolve(true)
98+
write(options, promise)
15799
} catch (e: Exception) {
158100
when (e) {
159101
is PosException -> promise.reject(e.code, e.message)
@@ -165,6 +107,104 @@ abstract class CardManager {
165107
}
166108
}
167109

110+
// region Unsafe methods for custom workflows
111+
112+
protected fun read(options: ReadableArray, promise: Promise) {
113+
val readableArray = Arguments.createArray()
114+
val readableMap = Arguments.createMap()
115+
readableMap.putString("cardId", cardId)
116+
readableMap.putString("samId", samId)
117+
118+
options.toArrayList().forEach {
119+
it as HashMap<*, *>
120+
val application = it["application"] as ArrayList<Int>
121+
val sfi = (it["sfi"] as Double).toInt()
122+
val offset = (it["offset"] as Double).toInt()
123+
val readMode = when ((it["readMode"] as Double).toInt()) {
124+
1 -> CardReadRecordsBuilder.ReadMode.MULTIPLE_RECORD
125+
else -> CardReadRecordsBuilder.ReadMode.ONE_RECORD
126+
}
127+
128+
selectApplication(application.map { it.toByte() }.toByteArray())
129+
selectFileBuilder()
130+
val readRecordsParser = readRecordsFromSfi(sfi, offset, readMode)
131+
132+
val records: Map<Int, ByteArray> = readRecordsParser.records
133+
134+
val resultMap = Arguments.createMap()
135+
val recordsMap = Arguments.createMap()
136+
137+
for ((key, record) in records) {
138+
val array = ByteConvertReactNativeUtil.byteArrayToReadableArray(record)
139+
recordsMap.putArray(key.toString(), array)
140+
}
141+
142+
resultMap.putInt("sfi", sfi)
143+
resultMap.putMap("records", recordsMap)
144+
145+
readableArray.pushMap(resultMap)
146+
}
147+
148+
readableMap.putArray("data", readableArray)
149+
promise.resolve(readableMap)
150+
}
151+
152+
protected fun write(options: ReadableArray, promise: Promise) {
153+
options.toArrayList().forEach {
154+
it as HashMap<*, *>
155+
val apdu = it["apdu"] as ArrayList<Int>
156+
val application = it["application"] as ArrayList<Int>
157+
val sfi = (it["sfi"] as Double).toInt()
158+
val offset = (it["offset"] as Double).toInt()
159+
val samUnlockString = it["samUnlockString"] as String
160+
161+
val newRecord = apdu.map { it.toByte() }.toByteArray();
162+
163+
val selectApplicationParser = selectApplication(ByteConvertReactNativeUtil.arrayListToByteArray(application))
164+
unlockSam(samUnlockString)
165+
selectSamDiversifier(selectApplicationParser)
166+
val samChallengeParser = samChallenge()
167+
val openSession3Parser = openSession3(samChallengeParser, sfi, offset)
168+
samDigestInit(openSession3Parser)
169+
updateRecord(sfi, offset, newRecord)
170+
val samDigestCloseParser = samDigestClose()
171+
val closeSession3Parser = closeSession3(samDigestCloseParser)
172+
samDigestAuthenticate(closeSession3Parser)
173+
}
174+
175+
promise.resolve(true)
176+
}
177+
178+
fun unsafeConnectSam() {
179+
connectSam()
180+
}
181+
182+
open suspend fun unsafeWaitForCard(promise: Promise) {
183+
waitForCard()
184+
}
185+
186+
fun unsafeConnectCard() {
187+
connectCard()
188+
}
189+
190+
fun unsafeRead(options: ReadableArray, promise: Promise) {
191+
read(options, promise)
192+
}
193+
194+
fun unsafeWrite(options: ReadableArray, promise: Promise) {
195+
write(options, promise)
196+
}
197+
198+
fun unsafeDisconnectSam() {
199+
disconnectSam()
200+
}
201+
202+
fun unsafeDisconnectCard() {
203+
disconnectCard()
204+
}
205+
206+
// endregion
207+
168208
private fun selectApplication(application: ByteArray): SelectApplicationParser {
169209
val selectApplicationBuilder = SelectApplicationBuilder(
170210
SelectApplicationBuilder.SELECT_FIRST_OCCURRENCE_RETURN_FCI, application)

android/src/main/java/com/pos/GenericPos.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,13 @@ open class GenericPos(private val reactContext: ReactApplicationContext): CardMa
197197
super.readCardId(promise)
198198
}
199199
}
200+
201+
202+
203+
override suspend fun unsafeWaitForCard(promise: Promise) {
204+
job = GlobalScope.launch(start = CoroutineStart.LAZY) {
205+
waitForCard()
206+
promise.resolve(true)
207+
}
208+
}
200209
}

android/src/main/java/com/pos/PosModule.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,44 @@ class PosModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
7474
}
7575
}
7676

77+
@ReactMethod
78+
fun unsafeConnectSam() {
79+
device?.unsafeConnectSam()
80+
}
81+
82+
@ReactMethod
83+
@OptIn(DelicateCoroutinesApi::class)
84+
fun unsafeWaitForCard(promise: Promise) {
85+
GlobalScope.launch {
86+
device?.unsafeWaitForCard(promise)
87+
}
88+
}
89+
90+
@ReactMethod
91+
fun unsafeConnectCard() {
92+
device?.unsafeConnectCard()
93+
}
94+
95+
@ReactMethod
96+
fun unsafeRead(options: ReadableArray, promise: Promise) {
97+
device?.unsafeRead(options, promise)
98+
}
99+
100+
@ReactMethod
101+
fun unsafeWrite(options: ReadableArray, promise: Promise) {
102+
device?.unsafeWrite(options, promise)
103+
}
104+
105+
@ReactMethod
106+
fun unsafeDisconnectSam() {
107+
device?.unsafeDisconnectSam()
108+
}
109+
110+
@ReactMethod
111+
fun unsafeDisconnectCard() {
112+
device?.unsafeDisconnectCard()
113+
}
114+
77115
companion object {
78116
const val NAME = "Pos"
79117
}

0 commit comments

Comments
 (0)