Improve NFC history readers and prepare production build
This commit is contained in:
@ -13,6 +13,7 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
var riwayatList: [RiwayatCard] = []
|
||||
var uid : String?
|
||||
var rawLog : String = ""
|
||||
private var historyRetryCount = 0
|
||||
|
||||
public override init() {}
|
||||
|
||||
@ -73,24 +74,44 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
let brizziSamHelper = BrizziSamHelper()
|
||||
brizziSamHelper.keyCard = data.hexEncodedString()
|
||||
let random = "8DC0DC40FE1DC582CF7099E2AACFBC10".hex2byte()
|
||||
let command = self.emoney.getCardNumber() + self.uid! + "FF"
|
||||
let decrypted = BrizziSamHelper.decryptDeSeDe(random)?.hexEncodedString()
|
||||
guard let uid = self.uid else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
return
|
||||
}
|
||||
let command = self.emoney.getCardNumber() + uid + "FF"
|
||||
guard let decrypted = BrizziSamHelper.decryptDeSeDe(random)?.hexEncodedString() else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
return
|
||||
}
|
||||
|
||||
let decryptedFinal = decrypted?.subString(from: 0, to: 32)
|
||||
let encrypted = BrizziSamHelper.encryptDeSeDe(command, decryptedFinal!, "0000000000000000")?.hexEncodedString()
|
||||
let decryptedFinal = decrypted.subString(from: 0, to: 32)
|
||||
guard decryptedFinal.count == 32,
|
||||
let encrypted = BrizziSamHelper.encryptDeSeDe(command, decryptedFinal, "0000000000000000")?.hexEncodedString() else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
return
|
||||
}
|
||||
|
||||
brizziSamHelper.encryptedKey = encrypted?.subString(from: 0, to: 32)
|
||||
brizziSamHelper.encryptedKey = encrypted.subString(from: 0, to: 32)
|
||||
|
||||
|
||||
let randomHex = "3C37029CA595FE4E7E62FCB2F7909B2C".hex2byte()
|
||||
let randomHexDecrypted = BrizziSamHelper.decryptDeSeDe(randomHex)
|
||||
let randomHexFinal = randomHexDecrypted?.hexEncodedString().subString(from: 0, to: 32) ?? ""
|
||||
|
||||
let randomHexFinal = randomHexDecrypted?.hexEncodedString().subString(from: 0, to: 32)
|
||||
let randomHexEncrypted = BrizziSamHelper.encryptDeSeDe(brizziSamHelper.encryptedKey!, randomHexFinal!, brizziSamHelper.authKey)
|
||||
brizziSamHelper.random = (randomHexEncrypted?.hexEncodedString())!.subString(from: 0, to: 32)
|
||||
guard randomHexFinal.count == 32,
|
||||
let encryptedKey = brizziSamHelper.encryptedKey,
|
||||
let randomHexEncrypted = BrizziSamHelper.encryptDeSeDe(encryptedKey, randomHexFinal, brizziSamHelper.authKey)?.hexEncodedString() else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
return
|
||||
}
|
||||
brizziSamHelper.random = randomHexEncrypted.subString(from: 0, to: 32)
|
||||
|
||||
|
||||
let samChallenge = brizziSamHelper.generateSamRandom().subString(from: 0, to: 32)
|
||||
guard samChallenge.count == 32 else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
return
|
||||
}
|
||||
let BRI_APDU04 = NFCISO7816APDU(instructionClass : 0x90, instructionCode : 0xAF, p1Parameter : 0x00, p2Parameter : 0x00, data : Data(_: samChallenge.hex2byte()), expectedResponseLength : CommonConstants.LE_GET_ALL_RESPONSE_DATA)
|
||||
apduRunner.exchangeApdu(apduCommand: BRI_APDU04, completionHandler: {response in
|
||||
if (response.sw1 == 0x91 && response.sw2 == 0x00) || (response.sw1 == 0x91 && response.sw2 == 0xAF){
|
||||
@ -105,12 +126,42 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.BRI_APDU05, completionHandler: {response in
|
||||
if (response.sw1 == 0x91 && response.sw2 == 0x00) || (response.sw1 == 0x91 && response.sw2 == 0xAF){
|
||||
self.emoney.setBalance(self.getRealBalance(reverseHexa: response.getData().hexEncodedString().subString(from: 0, to: 8)))
|
||||
self.getLog()
|
||||
self.historyRetryCount = 0
|
||||
self.startHistoryRead()
|
||||
} else {
|
||||
self.apduRunner.invalidateSession(msg: "readFailed".localizeString(string: self.langCode!))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func startHistoryRead() {
|
||||
rawLog = ""
|
||||
riwayatList.removeAll()
|
||||
getLog()
|
||||
}
|
||||
|
||||
private func retryHistoryRead(reason: String) {
|
||||
if historyRetryCount < 1 {
|
||||
historyRetryCount += 1
|
||||
debugLog("Retrying Brizzi history read: \(reason)")
|
||||
startHistoryRead()
|
||||
} else {
|
||||
finalizeHistoryRead()
|
||||
}
|
||||
}
|
||||
|
||||
private func finalizeHistoryRead() {
|
||||
if (self.parseLog()){
|
||||
self.riwayatList = self.riwayatList.sorted {
|
||||
($0.getTransationTime() ?? Date.distantPast) > ($1.getTransationTime() ?? Date.distantPast)
|
||||
}
|
||||
self.emoney.setRiwayatList(self.riwayatList)
|
||||
self.emoney.setTampilRiwayat(true)
|
||||
}
|
||||
self.updateScreen()
|
||||
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
|
||||
self.apduRunner.invalidateSession()
|
||||
}
|
||||
|
||||
private func getLog(){
|
||||
apduRunner.exchangeApdu(apduCommand: EmoneyApduCommands.BRI_LOG01, completionHandler: {response in
|
||||
@ -118,9 +169,7 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
self.rawLog.append(response.getData().hexEncodedString())
|
||||
self.getMoreLog()
|
||||
} else {
|
||||
self.updateScreen()
|
||||
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
|
||||
self.apduRunner.invalidateSession()
|
||||
self.retryHistoryRead(reason: "initial log status \(response.sw1)-\(response.sw2)")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -131,16 +180,12 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
self.rawLog.append(response.getData().hexEncodedString())
|
||||
self.getMoreLog()
|
||||
} else {
|
||||
self.rawLog.append(response.getData().hexEncodedString())
|
||||
|
||||
if (self.parseLog()){
|
||||
self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending })
|
||||
self.emoney.setRiwayatList(self.riwayatList)
|
||||
self.emoney.setTampilRiwayat(true)
|
||||
if (response.sw1 == 0x91 && response.sw2 == 0x00) || (response.sw1 == 0x90 && response.sw2 == 0x00) {
|
||||
self.rawLog.append(response.getData().hexEncodedString())
|
||||
self.finalizeHistoryRead()
|
||||
} else {
|
||||
self.retryHistoryRead(reason: "continuation log status \(response.sw1)-\(response.sw2)")
|
||||
}
|
||||
self.updateScreen()
|
||||
self.apduRunner.sessionEx?.alertMessage = "readFinish".localizeString(string: self.langCode!)
|
||||
self.apduRunner.invalidateSession()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -163,7 +208,11 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
riwayat.setAmount(self.getRealBalance(reverseHexa: data.subString(from: 46, to: 52)))
|
||||
|
||||
let time = self.getTransactionTime(formatDate: data.subString(from: 32, to: 38), formatTime: data.subString(from: 38, to: 44))
|
||||
riwayat.setTransactionTime(time!)
|
||||
guard let time else {
|
||||
debugLog("Skipping Brizzi log with invalid timestamp: \(data)")
|
||||
continue
|
||||
}
|
||||
riwayat.setTransactionTime(time)
|
||||
|
||||
riwayatList.append(riwayat)
|
||||
}
|
||||
@ -173,8 +222,11 @@ public class BrizziApi : UnifiedNfcApi {
|
||||
|
||||
func getTransactionTime(formatDate : String, formatTime : String) -> Date?{
|
||||
let dateFormatter2 = DateFormatter()
|
||||
dateFormatter2.locale = Locale(identifier: "en_US_POSIX")
|
||||
dateFormatter2.dateFormat = "HHmmss"
|
||||
let date12 = dateFormatter2.date(from: formatTime)!
|
||||
guard let date12 = dateFormatter2.date(from: formatTime) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
dateFormatter2.dateFormat = "hh:mm a"
|
||||
let date22 = dateFormatter2.string(from: date12)
|
||||
|
||||
Reference in New Issue
Block a user