Initial commit
This commit is contained in:
463
Emoney Info/Classes/api/UnifiedNfcApi.swift
Executable file
463
Emoney Info/Classes/api/UnifiedNfcApi.swift
Executable file
@ -0,0 +1,463 @@
|
||||
import Foundation
|
||||
import CoreNFC
|
||||
|
||||
|
||||
extension CFArray {
|
||||
func toSwiftArray<T>() -> [T] {
|
||||
let array = Array<AnyObject>(_immutableCocoaArray: self)
|
||||
return array.compactMap { $0 as? T }
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary where Key == String, Value == Any {
|
||||
var account: String? {
|
||||
guard let account = self[kSecAttrAccount as String] as? String else {
|
||||
return nil
|
||||
}
|
||||
return account
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
public class UnifiedNfcApi {
|
||||
var stationMap: [Int: Station] = [:]
|
||||
|
||||
func parseData() {
|
||||
stationMap = [
|
||||
0: Station(id: 0, name: "PARKIR RESKA", subName: "PARKIR RESKA", latitude: "0", longitude: "0"),
|
||||
1: Station(id: 1, name: "Tanah Abang", subName: "Tanah Abang", latitude: "-6.18574476", longitude: "106.8108382"),
|
||||
67: Station(id: 67, name: "C-Access", subName: "C-Access", latitude: "0", longitude: "0"),
|
||||
257: Station(id: 257, name: "Bogor", subName: "Bogor", latitude: "-6.59561005", longitude: "106.7904379"),
|
||||
258: Station(id: 258, name: "Cilebut", subName: "Cilebut", latitude: "-6.53050343", longitude: "106.8005885"),
|
||||
259: Station(id: 259, name: "Bojonggede", subName: "Bojonggede", latitude: "-6.49326562", longitude: "106.7949173"),
|
||||
260: Station(id: 260, name: "Citayam", subName: "Citayam", latitude: "-6.44879141", longitude: "106.8024588"),
|
||||
261: Station(id: 261, name: "Depok", subName: "Depok", latitude: "-6.40493394", longitude: "106.8172447"),
|
||||
262: Station(id: 262, name: "Depok Baru", subName: "Depok Baru", latitude: "-6.39113047", longitude: "106.821707"),
|
||||
263: Station(id: 263, name: "Pondok Cina", subName: "Pondok Cina", latitude: "-6.36905168", longitude: "106.8322114"),
|
||||
264: Station(id: 264, name: "Univ. Indonesia", subName: "Univ. Indonesia", latitude: "-6.36075528", longitude: "106.8317544"),
|
||||
265: Station(id: 265, name: "Univ. Pancasila", subName: "Univ. Pancasila", latitude: "-6.33894476", longitude: "106.8344241"),
|
||||
272: Station(id: 272, name: "Lenteng Agung", subName: "Lenteng Agung", latitude: "-6.33065157", longitude: "106.8349938"),
|
||||
273: Station(id: 273, name: "Tanjung Barat", subName: "Tanjung Barat", latitude: "-6.30780817", longitude: "106.8388513"),
|
||||
274: Station(id: 274, name: "Pasar Minggu", subName: "Pasar Minggu", latitude: "-6.28440597", longitude: "106.8445384"),
|
||||
275: Station(id: 275, name: "Pasar Minggu Baru", subName: "Pasar Minggu Baru", latitude: "-6.26278132", longitude: "106.8518598"),
|
||||
276: Station(id: 276, name: "Duren Kalibata", subName: "Duren Kalibata", latitude: "-6.25534623", longitude: "106.8550195"),
|
||||
277: Station(id: 277, name: "Cawang", subName: "Cawang", latitude: "-6.24266069", longitude: "106.8588196"),
|
||||
278: Station(id: 278, name: "Tebet", subName: "Tebet", latitude: "-6.22606896", longitude: "106.8583004"),
|
||||
279: Station(id: 279, name: "Manggarai", subName: "Manggarai", latitude: "-6.20992352", longitude: "106.8502129"),
|
||||
280: Station(id: 280, name: "Cikini", subName: "Cikini", latitude: "-6.19856352", longitude: "106.8412599"),
|
||||
281: Station(id: 281, name: "Gondangdia", subName: "Gondangdia", latitude: "-6.18594019", longitude: "106.8325942"),
|
||||
288: Station(id: 288, name: "Juanda", subName: "Juanda", latitude: "-6.16672229", longitude: "106.8304674"),
|
||||
289: Station(id: 289, name: "Sawah Besar", subName: "Sawah Besar", latitude: "-6.16063965", longitude: "106.8276397"),
|
||||
290: Station(id: 290, name: "Mangga Besar", subName: "Mangga Besar", latitude: "-6.14979667", longitude: "106.8269796"),
|
||||
291: Station(id: 291, name: "Jayakarta", subName: "Jayakarta", latitude: "-6.14134112", longitude: "106.8230834"),
|
||||
292: Station(id: 292, name: "Jakarta Kota", subName: "Jakarta Kota", latitude: "-6.13761335", longitude: "106.8146308"),
|
||||
293: Station(id: 293, name: "Bekasi", subName: "Bekasi", latitude: "-6.23614485", longitude: "106.9994173"),
|
||||
294: Station(id: 294, name: "Kranji", subName: "Kranji", latitude: "-6.22433352", longitude: "106.9793992"),
|
||||
295: Station(id: 295, name: "Cakung", subName: "Cakung", latitude: "-6.21929974", longitude: "106.9521357"),
|
||||
296: Station(id: 296, name: "Klender Baru", subName: "Klender Baru", latitude: "-6.21743543", longitude: "106.9396893"),
|
||||
297: Station(id: 297, name: "Buaran", subName: "Buaran", latitude: "-6.21615092", longitude: "106.9283069"),
|
||||
304: Station(id: 304, name: "Klender", subName: "Klender", latitude: "-6.21335877", longitude: "106.8998889"),
|
||||
305: Station(id: 305, name: "Jatinegara", subName: "Jatinegara", latitude: "-6.21513342", longitude: "106.8703259"),
|
||||
313: Station(id: 313, name: "Tangerang", subName: "Tangerang", latitude: "-6.17679787", longitude: "106.63272688"),
|
||||
327: Station(id: 327, name: "Karet", subName: "Karet", latitude: "-6.2008165", longitude: "106.8159002"),
|
||||
328: Station(id: 328, name: "Sudirman", subName: "Sudirman", latitude: "-6.202438", longitude: "106.8234505"),
|
||||
329: Station(id: 329, name: "Tanah Abang", subName: "Tanah Abang", latitude: "-6.18574476", longitude: "106.8108382"),
|
||||
336: Station(id: 336, name: "Palmerah", subName: "Palmerah", latitude: "-6.20740425", longitude: "106.7974463"),
|
||||
337: Station(id: 337, name: "Kebayoran", subName: "Kebayoran", latitude: "-6.23718958", longitude: "106.782542"),
|
||||
338: Station(id: 338, name: "Pondok Ranji", subName: "Pondok Ranji", latitude: "-6.27633762", longitude: "106.7449376"),
|
||||
339: Station(id: 339, name: "Jurang Mangu", subName: "Jurang Mangu", latitude: "-6.28876225", longitude: "106.7291141"),
|
||||
340: Station(id: 340, name: "Sudimara", subName: "Sudimara", latitude: "-6.29694285", longitude: "106.7127952"),
|
||||
341: Station(id: 341, name: "Rawabuntu", subName: "Rawabuntu", latitude: "-6.31500105", longitude: "106.6761968"),
|
||||
342: Station(id: 342, name: "Serpong", subName: "Serpong", latitude: "-6.32004857", longitude: "106.6655717"),
|
||||
343: Station(id: 343, name: "Cisauk", subName: "Cisauk", latitude: "-6.3249995", longitude: "106.6407467"),
|
||||
344: Station(id: 344, name: "Cicayur", subName: "Cicayur", latitude: "-6.32951436", longitude: "106.6189624"),
|
||||
345: Station(id: 345, name: "Parung Panjang", subName: "Parung Panjang", latitude: "-6.34420808", longitude: "106.5698061"),
|
||||
352: Station(id: 352, name: "Cilejit", subName: "Cilejit", latitude: "-6.35434367", longitude: "106.5097328"),
|
||||
353: Station(id: 353, name: "Daru", subName: "Daru", latitude: "-6.33800742", longitude: "106.4923913"),
|
||||
354: Station(id: 354, name: "Tenjo", subName: "Tenjo", latitude: "-6.32725713", longitude: "106.4613542"),
|
||||
355: Station(id: 355, name: "Tigaraksa", subName: "Tigaraksa", latitude: "-6.32846118", longitude: "106.4347451"),
|
||||
356: Station(id: 356, name: "Maja", subName: "Maja", latitude: "-6.33230387", longitude: "106.3965692"),
|
||||
357: Station(id: 357, name: "Citeras", subName: "Citeras", latitude: "-6.33492764", longitude: "106.3327125"),
|
||||
358: Station(id: 358, name: "Rangkasbitung", subName: "Rangkasbitung", latitude: "-6.3526711", longitude: "106.251502"),
|
||||
374: Station(id: 374, name: "Bekasi Timur", subName: "Bekasitimur", latitude: "-6.246845", longitude: "107.0181248"),
|
||||
376: Station(id: 376, name: "Cikarang", subName: "Cikarang", latitude: "-6.2553926", longitude: "107.1451293")
|
||||
]
|
||||
}
|
||||
var langCode : String?
|
||||
var apduRunner = ApduRunner()
|
||||
|
||||
public init() {
|
||||
langCode = Locale.current.languageCode
|
||||
parseData()
|
||||
}
|
||||
|
||||
func setCallback(apduCallback : ApduCallback){
|
||||
apduRunner.setApduCallback(callback: apduCallback)
|
||||
apduRunner.setUnifiedNfcApi(nfcApi: self)
|
||||
}
|
||||
|
||||
func setApduRunner(apRunner : ApduRunner){
|
||||
self.apduRunner = apRunner
|
||||
}
|
||||
|
||||
public func checkIfNfcSupported() -> Bool {
|
||||
return NFCTagReaderSession.readingAvailable
|
||||
}
|
||||
|
||||
public func searchCard(){
|
||||
apduRunner.startScan()
|
||||
}
|
||||
|
||||
public func checkCard(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.BRIZZI_INIT_APDU, completionHandler: {response in
|
||||
if (response.sw1 == 0x91 && response.sw2 == 0x00){
|
||||
debugLog("brizzi card")
|
||||
let brizzi = BrizziApi()
|
||||
brizzi.setApduRunner(apRunner: self.apduRunner)
|
||||
brizzi.getUid()
|
||||
} else {
|
||||
self.checkNext01()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public func checkFelicaCard(tag: NFCFeliCaTag){
|
||||
readFelicaCard(tag: tag)
|
||||
}
|
||||
|
||||
func readFelicaCard(tag: NFCFeliCaTag){
|
||||
let kmt = Emoney()
|
||||
|
||||
let serviceCode = Data([0x0B, 0x30])
|
||||
let blockList = Data([0x80, 0x00])
|
||||
|
||||
tag.readWithoutEncryption(
|
||||
serviceCodeList: [serviceCode],
|
||||
blockList: [blockList]
|
||||
) { (status1, status2, blockData, error) in
|
||||
|
||||
if let error = error {
|
||||
self.apduRunner.nfcApi?.stopCheckCard(message: "Gagal membaca: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
|
||||
// Cek status keberhasilan dari kartu (0x00 0x00 berarti sukses)
|
||||
guard status1 == 0x00 && status2 == 0x00 else {
|
||||
self.apduRunner.nfcApi?.stopCheckCard(message: "Error Status: \(status1) \(status2)")
|
||||
return
|
||||
}
|
||||
for (index, data) in blockData.enumerated() {
|
||||
debugLog("Data Blok \(index): \(data.map { String(format: "%02X", $0) }.joined())")
|
||||
if let cardNumberString = String(data: data, encoding: .utf8) {
|
||||
kmt.setCardLabel("KMT")
|
||||
kmt.setCardNumber(cardNumberString)
|
||||
self.readFelicaBalance(tag: tag, kmt: kmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readFelicaBalance(tag: NFCFeliCaTag, kmt: Emoney){
|
||||
let serviceCode = Data([0x17, 0x10])
|
||||
let blockList = Data([0x80, 0x00])
|
||||
|
||||
tag.readWithoutEncryption(
|
||||
serviceCodeList: [serviceCode],
|
||||
blockList: [blockList]
|
||||
) { (status1, status2, blockData, error) in
|
||||
if let error = error {
|
||||
self.apduRunner.nfcApi?.stopCheckCard(message: "Gagal membaca: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
|
||||
if status1 == 0x00 && status2 == 0x00 {
|
||||
let cardBalance = [UInt8](blockData[0])
|
||||
var y: Int = 0
|
||||
for x in 0..<4 {
|
||||
y += Int(cardBalance[x]) << (x * 8)
|
||||
}
|
||||
|
||||
let formatter = NumberFormatter()
|
||||
formatter.locale = Locale(identifier: "id_ID")
|
||||
formatter.numberStyle = .decimal
|
||||
debugLog("balance")
|
||||
kmt.setBalance(y)
|
||||
if let balance = formatter.string(from: NSNumber(value: y)) {
|
||||
debugLog("Saldo: \(balance)") // Hasil contoh: "67.305.985"
|
||||
}
|
||||
self.readFelicaCardHistory(tag: tag, kmt: kmt)
|
||||
// kmt.setTampilRiwayat(false)
|
||||
// self.apduRunner.callback?.complete(emoney: kmt)
|
||||
// self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
|
||||
// self.apduRunner.invalidateSession()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readFelicaCardHistory(tag: NFCFeliCaTag, kmt: Emoney){
|
||||
let serviceCode = Data([0x0F, 0x20])
|
||||
|
||||
// 2. Buat daftar 15 blok (Blok 0 sampai 14) secara otomatis
|
||||
var blockList = [Data]()
|
||||
for i in 0..<15 {
|
||||
blockList.append(Data([0x80, UInt8(i)]))
|
||||
}
|
||||
|
||||
// 3. Panggil fungsi pembacaan
|
||||
tag.readWithoutEncryption(
|
||||
serviceCodeList: [serviceCode],
|
||||
blockList: blockList
|
||||
) { (status1, status2, blockData, error) in
|
||||
var riwayatList: [RiwayatCard] = []
|
||||
if let error = error {
|
||||
debugLog("Error: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
|
||||
if status1 == 0x00 && status2 == 0x00 {
|
||||
debugLog("Berhasil membaca 15 blok!")
|
||||
// blockData akan berisi array of Data, masing-masing 16 byte
|
||||
for (index, data) in blockData.enumerated() {
|
||||
let riwayat = RiwayatCard()
|
||||
var normal = true
|
||||
let subId = data.subdata(in: 8..<10)
|
||||
|
||||
let uid = self.convert(bytes: [UInt8](subId))
|
||||
debugLog("station: \(uid)")
|
||||
|
||||
debugLog("Blok \(index): \(data.map { String(format: "%02X", $0) }.joined())")
|
||||
if (uid == 0){
|
||||
normal = false
|
||||
}
|
||||
if (data.count > 10){
|
||||
let type = data[10]
|
||||
debugLog(type)
|
||||
switch type {
|
||||
case 0x01:
|
||||
riwayat.setProsesTipe(1)
|
||||
riwayat.setTitle("payment".localizeString(string: self.langCode!))
|
||||
debugLog("Pembayaran")
|
||||
case 0x00, 0x03:
|
||||
riwayat.setProsesTipe(0)
|
||||
riwayat.setTitle("topup".localizeString(string: self.langCode!))
|
||||
debugLog("Topup")
|
||||
default:
|
||||
riwayat.setProsesTipe(1)
|
||||
riwayat.setTitle("payment".localizeString(string: self.langCode!))
|
||||
debugLog("Other")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if let station = self.stationMap[uid]{
|
||||
debugLog("station", station.name)
|
||||
riwayat.setLocationName(station.name.uppercased(with: .autoupdatingCurrent))
|
||||
}
|
||||
// let station = self.stationMap[uid]
|
||||
// print("station", station!)
|
||||
// riwayat.setPlace(self.stationMap[uid]!.name)
|
||||
if (normal){
|
||||
|
||||
let subData = data.subdata(in: 0..<4)
|
||||
|
||||
let date = self.getDate(data: [UInt8](subData))
|
||||
riwayat.setTransactionTime(date!)
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = Locale(identifier: "id_ID") // Format Indonesia
|
||||
formatter.dateFormat = "dd MMMM yyyy, HH:mm"
|
||||
|
||||
let dateString = formatter.string(from: date!)
|
||||
debugLog("Hasil Konversi: \(dateString)")
|
||||
|
||||
let amn = data.subdata(in: 4..<8)
|
||||
let amount = amn.withUnsafeBytes { $0.load(as: Int32.self).bigEndian }
|
||||
|
||||
//print("Amount: \(amount)")
|
||||
|
||||
// if (data.count > 10){
|
||||
// let type = data[10]
|
||||
// print(type)
|
||||
// switch type {
|
||||
// case 0x01:
|
||||
// print("Pembayaran")
|
||||
// case 0x00:
|
||||
// print("Topup")
|
||||
// default:
|
||||
// print("Other")
|
||||
// }
|
||||
//
|
||||
// let subId = data.subdata(in: 8..<10)
|
||||
//
|
||||
// let uid = self.convert(bytes: [UInt8](subId))
|
||||
// print("station: \(uid)")
|
||||
// }
|
||||
riwayat.setAmount(Int(amount))
|
||||
let nformatter = NumberFormatter()
|
||||
nformatter.locale = Locale(identifier: "id_ID")
|
||||
nformatter.numberStyle = .decimal
|
||||
if let balance = nformatter.string(from: NSNumber(value: amount)) {
|
||||
debugLog("amount: \(balance)") // Hasil contoh: "67.305.985"
|
||||
}
|
||||
debugLog("")
|
||||
} else {
|
||||
debugLog("RESKA PARKIR")
|
||||
|
||||
let stringData = data.map { String(format: "%02X", $0) }.joined()
|
||||
|
||||
let inputFormatter = DateFormatter()
|
||||
inputFormatter.dateFormat = "ddMMyyyyHHmmssSS"
|
||||
|
||||
let finalData = stringData.prefix(16)
|
||||
// 2. Konversi String ke objek Date
|
||||
if let date = inputFormatter.date(from: String(finalData)) {
|
||||
|
||||
// 3. Inisialisasi Formatter untuk mengubah ke format tujuan
|
||||
let outputFormatter = DateFormatter()
|
||||
outputFormatter.dateFormat = "dd MMM yyyy HH:mm"
|
||||
|
||||
let result = outputFormatter.string(from: date)
|
||||
riwayat.setTransactionTime(date)
|
||||
debugLog(result) // Hasil: 29-01-2026 16:00:44
|
||||
} else {
|
||||
debugLog("Format string tidak cocok")
|
||||
}
|
||||
let amn = data.subdata(in: 8..<12)
|
||||
let amount = amn.withUnsafeBytes { $0.load(as: Int32.self).bigEndian }
|
||||
riwayat.setAmount(Int(amount))
|
||||
//print("Amount: \(amount)")
|
||||
|
||||
|
||||
let nformatter = NumberFormatter()
|
||||
nformatter.locale = Locale(identifier: "id_ID")
|
||||
nformatter.numberStyle = .decimal
|
||||
if let balance = nformatter.string(from: NSNumber(value: amount)) {
|
||||
debugLog("amount: \(balance)") // Hasil contoh: "67.305.985"
|
||||
}
|
||||
}
|
||||
debugLog("")
|
||||
riwayatList.append(riwayat)
|
||||
}
|
||||
kmt.setRiwayatList(riwayatList)
|
||||
kmt.setTampilRiwayat(true)
|
||||
self.apduRunner.callback?.complete(emoney: kmt)
|
||||
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
|
||||
self.apduRunner.invalidateSession()
|
||||
} else {
|
||||
debugLog("Gagal. Status: \(status1), \(status2)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getDate(data: [UInt8]) -> Date? {
|
||||
// 1. Tentukan TimeZone Jakarta
|
||||
let timeZone = TimeZone(identifier: "Asia/Jakarta")!
|
||||
var calendar = Calendar(identifier: .gregorian)
|
||||
calendar.timeZone = timeZone
|
||||
|
||||
// 2. Set tanggal dasar (1 Januari 2000, 07:00:00)
|
||||
var components = DateComponents()
|
||||
components.year = 2000
|
||||
components.month = 1
|
||||
components.day = 1
|
||||
components.hour = 7
|
||||
components.minute = 0
|
||||
components.second = 0
|
||||
|
||||
guard let baseDate = calendar.date(from: components) else { return nil }
|
||||
|
||||
// 3. Ambil selisih detik dari data byte
|
||||
let secondsToAdd = convert(bytes: data)
|
||||
|
||||
// 4. Tambahkan detik ke baseDate
|
||||
let finalDate = calendar.date(byAdding: .second, value: secondsToAdd, to: baseDate)
|
||||
|
||||
return finalDate
|
||||
}
|
||||
|
||||
func convert(bytes: [UInt8]) -> Int {
|
||||
switch bytes.count {
|
||||
case 0:
|
||||
fatalError("Data kosong")
|
||||
case 1:
|
||||
return Int(bytes[0])
|
||||
case 2:
|
||||
// Big-endian: (byte[0] << 8) | byte[1]
|
||||
return (Int(bytes[0]) << 8) | Int(bytes[1])
|
||||
case 3:
|
||||
// (byte[0] << 16) | (byte[1] << 8) | byte[2]
|
||||
return (Int(bytes[0]) << 16) | (Int(bytes[1]) << 8) | Int(bytes[2])
|
||||
default:
|
||||
// Padanan ByteBuffer.wrap(bArr).getInt() (Big-endian)
|
||||
return Int(bytes.withUnsafeBytes { $0.load(as: Int32.self).bigEndian })
|
||||
}
|
||||
}
|
||||
|
||||
public func stopCheckCard(message : String){
|
||||
apduRunner.sessionEx?.invalidate(errorMessage: message)
|
||||
}
|
||||
|
||||
private func checkNext01(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.FLAZZ_INIT_APDU, completionHandler: {response in
|
||||
if (response.sw1 == 0x90 && response.sw2 == 0x00){
|
||||
debugLog("flazz card")
|
||||
let flazz = BcaFlazzApi()
|
||||
flazz.setApduRunner(apRunner: self.apduRunner)
|
||||
flazz.checkFlazzCard()
|
||||
} else {
|
||||
self.checkNext02()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func checkNext02(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.TAPCASH_INIT_APDU, completionHandler: {response in
|
||||
if (response.sw1 == 0x90 && response.sw2 == 0x00){
|
||||
debugLog("tapcash card")
|
||||
let tapCash = TapCashApi()
|
||||
tapCash.setApduRunner(apRunner: self.apduRunner)
|
||||
tapCash.checkBalance()
|
||||
} else {
|
||||
self.checkNext03()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func checkNext03(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.EMONEY_INIT_APDU, completionHandler: {response in
|
||||
if (response.sw1 == 0x90 && response.sw2 == 0x00){
|
||||
debugLog("emoney card")
|
||||
let emoney = MandiriEmoneyApi()
|
||||
emoney.setApduRunner(apRunner: self.apduRunner)
|
||||
emoney.getCardNumber()
|
||||
} else {
|
||||
self.checkNext04()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func checkNext04(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.JACKCARD_INIT_APDU, completionHandler: {response in
|
||||
if (response.sw1 == 0x90 && response.sw2 == 0x00){
|
||||
debugLog("jack card")
|
||||
let jack = JackCardApi()
|
||||
jack.setApduRunner(apRunner: self.apduRunner)
|
||||
jack.getBalance(resp: response.getData())
|
||||
} else {
|
||||
self.checkNext05()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func checkNext05(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.MEGA_APDU01, completionHandler: {response in
|
||||
if (response.sw1 == 0x90 && response.sw2 == 0x00){
|
||||
debugLog("megacash")
|
||||
let mega = MegaCashApi()
|
||||
mega.setApduRunner(apRunner: self.apduRunner)
|
||||
mega.getBalance(resp: response.getData())
|
||||
} else {
|
||||
self.apduRunner.invalidateSession(msg: "Card not supported")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user