From 77b8d1956a104de3b27f679b5edfd57ecfc1d395 Mon Sep 17 00:00:00 2001 From: kizzy Date: Sat, 16 May 2026 22:55:51 +0700 Subject: [PATCH] MPU contactless finished / if amount is exceeded 100000 MMK , will route to card capture to proceed chip --- .../baselib/viewModel/EmvBaseViewModel.java | 173 ++++++++++-------- baselib/src/main/res/raw/contacts_config.json | 50 ++--- baselib/src/main/res/raw/mpu_ctls_config.json | 2 +- .../src/main/res/raw/quickpass_config.json | 1 + baselib/src/main/res/raw/rid_config.json | 18 +- 5 files changed, 139 insertions(+), 105 deletions(-) diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java index d613ee9..8bdf03d 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java @@ -26,6 +26,7 @@ import com.nexgo.oaf.apiv3.device.pinpad.PinPad; import com.nexgo.oaf.apiv3.device.pinpad.PinPadKeyCode; import com.nexgo.oaf.apiv3.device.pinpad.PinpadLayoutEntity; import com.nexgo.oaf.apiv3.device.reader.CardInfoEntity; +import com.nexgo.oaf.apiv3.emv.AidEntity; import com.nexgo.oaf.apiv3.emv.CandidateAppInfoEntity; import com.nexgo.oaf.apiv3.emv.EmvCardBrandEnum; import com.nexgo.oaf.apiv3.emv.EmvCvmResultEnum; @@ -178,7 +179,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel { protected int mProcessStep; protected int mAppSelect = 0; - + private boolean mMPUContactlessConfigured = false; private Looper mLooper = Looper.getMainLooper(); private final Handler mHandler = new Handler(mLooper) { @Override @@ -213,6 +214,8 @@ public abstract class EmvBaseViewModel extends BaseViewModel { public void startProcess() { isOfflinePinEntered = false; + mMPUContactlessConfigured = false; + initData(); // Check if initialization was successful @@ -272,10 +275,12 @@ public abstract class EmvBaseViewModel extends BaseViewModel { transData.setUnionPayTransDataEntity(unionPayTransDataEntity); + setTransactionLimitForMPUCtls(false); // emvHandler.contactlessConfigKernelId(EmvCardBrandEnum.EMV_CARD_BRAND_JCB,(byte) 0x01,ByteUtils.hexString2ByteArray("06")); - emvHandler.contactlessAppendAidIntoKernel(EmvCardBrandEnum.EMV_CARD_BRAND_MASTER, (byte) 0x08, ByteUtils.hexString2ByteArray("A000000732100123")); + emvHandler.contactlessAppendAidIntoKernel(EmvCardBrandEnum.EMV_CARD_BRAND_MASTER, (byte) 0x07, ByteUtils.hexString2ByteArray("A0000008890101")); +// emvHandler.contactlessAppendAidIntoKernelFirst(true); LogUtil.d(TAG, "TransData :" + transData.getTransAmount()); LogUtil.d(TAG, "start emv "); @@ -329,76 +334,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel { } } - private void initPayPassTlv() { - emvParamOperation.retrievePayPassData(new ProcessSingleDataResult() { - @Override - public void onSuccess(PayPassEntity data) { - - String DF8117Value = "E0"; - String DF8118Value = "F8"; - String DF8119Value = "28"; - - if (!data.getTerminalCapability().isEmpty()) { - DF8117Value = data.getTerminalCapability().substring(0, 2); - DF8118Value = data.getTerminalCapability().substring(2, 4); - DF8119Value = data.getTerminalCapability().substring(4, 6); - } - String DF8123Value = data.getFloorLimit(); - String DF8124Value = data.getTransLimitCDV(); - String DF8125Value = data.getTransLimit(); - String DF8126Value = ParamHelper.getInstance().convertPaddedString(data.getCvmLimit()); - String DF8120Value = data.getTacDefault(); - String DF8121Value = data.getTacDenial(); - String DF8122Value = data.getTacOnline(); - - String[] tagsPayPass = {"DF8117", "DF8118", "DF8119", "DF811F", "DF811E", "DF812C", - "DF8123", "DF8124", "DF8125", "DF8126", - "DF811B", "DF811D", "DF8120", "DF8121", "DF8122"}; - - String[] valuesPayPass = {DF8117Value, DF8118Value, DF8119Value, "C8", "00", "00", - DF8123Value, DF8124Value, DF8125Value, DF8126Value, - "30", "02", DF8120Value, DF8121Value, DF8122Value}; -// try { -// mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagsPayPass, valuesPayPass); -// -// LogUtil.d(TAG,"<<<<< PayPass TLV data are successfully setup >>>>>"); -// } catch (RemoteException e) { -// throw new RuntimeException(e); -// } - } - - @Override - public void onDataNotFound() { - LogUtil.d(TAG, "PayPass Data not found!"); - } - }); - } - - - protected void increasedKSN() { - pinPad.dukptKsnIncrease(pinIndex); //3 - - LogUtil.d(TAG,"DUKPT KSN Increased!"); - } - - private void getKSN() { - try { - - byte[] result = pinPad.dukptCurrentKsn(pinIndex); - if (result != null) { - String ksnStr = ByteUtil.bytes2HexStr(result); - LogUtil.d(TAG, "ksnStr: " + ksnStr); - mPayDetail.setReference(ksnStr); - mPayDetail.tempKSN = ksnStr; - - LogUtil.d(TAG, "final ksnStr: " + ksnStr); - } else { - LogUtil.e(TAG, "Result code for current KSN:" + result); - } - } catch (Exception e) { - e.printStackTrace(); - } - } private String getTransactionType() { String trnxType = "00"; @@ -600,13 +535,21 @@ public abstract class EmvBaseViewModel extends BaseViewModel { @Override public void onTransInitBeforeGPO() { + + if (mMPUContactlessConfigured) { + LogUtil.d(TAG, "onTransInitBeforeGPO: skipping — MPU contactless already configured"); + emvHandler.onSetTransInitBeforeGPOResponse(true); + return; + } + byte[] aid = emvHandler.getTlv(new byte[]{0x4F}, EmvDataSourceEnum.FROM_KERNEL); - LogUtil.d(TAG, "onTransInitBeforeGPO :"); + LogUtil.d(TAG, "onTransInitBeforeGPO :"+ByteUtil.bytes2HexStr(aid)); String visaTerminalCapability = SystemParamsOperation.getInstance().getVisaTerminalCapability(); String masterTerminalCapability = SystemParamsOperation.getInstance().getMasterTerminalCapability(); String upiTerminalCapability = SystemParamsOperation.getInstance().getUpiTerminalCapability(); + String selectedTerminalCapability = ""; if (aid != null) { @@ -621,6 +564,9 @@ public abstract class EmvBaseViewModel extends BaseViewModel { } else if (aidStr.contains("A000000333") || aidStr.contains("A000000025")) { // UPI selectedTerminalCapability = upiTerminalCapability; + } else if (aidStr.contains("A00000006510") || aidStr.contains("A0000001570040")) { + // UPI + selectedTerminalCapability = "E0F8C8"; } } @@ -640,12 +586,15 @@ public abstract class EmvBaseViewModel extends BaseViewModel { configPaypassParameter(aid); } else if (aidStr.contains("A000000003")) { configPaywaveParameters(); - } else if (aidStr.contains("A000000025")) { -// //imp + } else if (aidStr.contains("A000000333")) { + configureQuickPassParamerter(); } else if (aidStr.contains("A000000541")) { configPureContactlessParameter(); } else if (aidStr.contains("A000000065")) { configJcbContactlessParameter(); + } else if (aidStr.contains("A000000889")) { + configMPUContactlessParameter(); + mMPUContactlessConfigured = true; } } } @@ -1267,6 +1216,75 @@ public abstract class EmvBaseViewModel extends BaseViewModel { } + + } + + private void configMPUContactlessParameter() { + LogUtil.d(TAG,"MPU Contactless Parameter configurations...."); + //kernel configuration, enable RRP and cdcvm + + + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x1B}, new byte[]{(byte) 0x30}); + + //EMV MODE :amount >contactless cvm limit, set 60 = online pin and signature , set 20 = signature + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x18}, new byte[]{(byte) 0xF0}); //F8 + //EMV mode :amount < contactless cvm limit, set 08 = no cvm + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x19}, new byte[]{(byte) 0x28}); //08 + + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x24}, ByteUtils.hexString2ByteArray("000010000000")); + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x25}, ByteUtils.hexString2ByteArray("000010000000")); + emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x26}, ByteUtils.hexString2ByteArray("000010000000")); + + + + emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x1d}, ByteUtils.hexString2ByteArray("6C00800000000000")); + + setTransactionLimitForMPUCtls(true); + + + byte[] getTLVofDF8124 = emvHandler.getTlv(ByteUtil.hexStr2Bytes("DF8124"),EmvDataSourceEnum.FROM_KERNEL); + LogUtil.d(TAG,"DF8124: "+ByteUtil.bytes2HexStr(getTLVofDF8124)); + + + } + + private void setTransactionLimitForMPUCtls(boolean flag){ + if(emvHandler.getAidList() != null) { + for (AidEntity aidEntity:emvHandler.getAidList() + ) { + + if(aidEntity.getAid() != null) { + if(aidEntity.getAid().equals("A00000000410") || aidEntity.getAid().equals("A0000000041010")){ + + if(flag) { + aidEntity.setTransLimit(Long.parseLong("000010000000")); + aidEntity.setContactlessTransLimit(Long.parseLong("000010000000")); + } else { + aidEntity.setTransLimit(Long.parseLong("999999999999")); + aidEntity.setContactlessTransLimit(Long.parseLong("999999999999")); + } + + emvHandler.delOneAid(ByteUtil.hexStr2Bytes(aidEntity.getAid())); + emvHandler.setAidParaList(List.of(aidEntity)); + LogUtil.d(TAG,"added AID+"+aidEntity.getAid()); + } + } + + } + + for (AidEntity aidEntity1:emvHandler.getAidList() + ) { + if (aidEntity1.getAid() != null) { + if (aidEntity1.getAid().equals("A00000000410") || aidEntity1.getAid().equals("A0000000041010")) { + + + LogUtil.d(TAG, " AID+" + aidEntity1.getAid()); + LogUtil.d(TAG, " transactionLimit+" + aidEntity1.getContactlessTransLimit()); + LogUtil.d(TAG, " transactionLimit+" + aidEntity1.getTransLimit()); + } + } + } + } } private void configPaywaveParameters() { @@ -1313,6 +1331,11 @@ public abstract class EmvBaseViewModel extends BaseViewModel { } + private void configPureQuickPassParameter() { + LogUtil.d(TAG, "configQuickPassParameter"); + + + } private void configJcbContactlessParameter() { LogUtil.d(TAG, "configJcbContactlessParameter"); diff --git a/baselib/src/main/res/raw/contacts_config.json b/baselib/src/main/res/raw/contacts_config.json index ec4fcce..0723d52 100644 --- a/baselib/src/main/res/raw/contacts_config.json +++ b/baselib/src/main/res/raw/contacts_config.json @@ -531,9 +531,9 @@ }, { "aidEnable": true, - "aid": "A0000000651010", + "aid": "A00000006510", "cardScheme": "JCB", - "applicationVersion": "0020", + "applicationVersion": "0030", "emvDDOL": "9F3704", "emvTDOL": "9F3704", "partialAidSelection": false, @@ -553,33 +553,33 @@ "currencyCode": "0104" }, { - "aidEnable": true, - "aid": "A00000006510", - "cardScheme": "JCB", - "applicationVersion": "0020", - "emvDDOL": "9F3704", - "emvTDOL": "9F3704", - "partialAidSelection": false, - "targetPercent": "99", - "maxTargetPercent": "99", - "threshold": "00000000", - "tacDefault": "D84000A800", - "tacOnline": "DC4004F800", - "tacDenial": "0000000000", - "floorLimit": "000000000000", - "cvmLimit": 75000, - "transLimit": "999999999999", - "transLimitCDV": "999999999999", - "terminalCapability": "0000000000000000", - "riskManageData": "01", - "cateCode": "2701", - "currencyCode": "0104" - }, + "aidEnable": true, + "aid": "A0000000651010", + "cardScheme": "JCB", + "applicationVersion": "0030", + "emvDDOL": "9F3704", + "emvTDOL": "9F3704", + "partialAidSelection": false, + "targetPercent": "99", + "maxTargetPercent": "99", + "threshold": "00000000", + "tacDefault": "D84000A800", + "tacOnline": "DC4004F800", + "tacDenial": "0000000000", + "floorLimit": "000000000000", + "cvmLimit": 75000, + "transLimit": "999999999999", + "transLimitCDV": "999999999999", + "terminalCapability": "0000000000000000", + "riskManageData": "01", + "cateCode": "2701", + "currencyCode": "0104" +}, { "aidEnable": true, "aid": "A0000001570040", "cardScheme": "JCB", - "applicationVersion": "0020", + "applicationVersion": "0030", "emvDDOL": "9F3704", "emvTDOL": "9F3704", "partialAidSelection": false, diff --git a/baselib/src/main/res/raw/mpu_ctls_config.json b/baselib/src/main/res/raw/mpu_ctls_config.json index 3f6983e..3732939 100644 --- a/baselib/src/main/res/raw/mpu_ctls_config.json +++ b/baselib/src/main/res/raw/mpu_ctls_config.json @@ -14,7 +14,7 @@ "tacOnline": "DC4004F800", "tacDenial": "0000000000", "floorLimit": "000000000000", - "cvmLimit": 100000, + "cvmLimit": 10000000, "transLimit": "000010000000", "transLimitCDV": "999999999999", "terminalCapability": "0000000000000000", diff --git a/baselib/src/main/res/raw/quickpass_config.json b/baselib/src/main/res/raw/quickpass_config.json index 47b3a28..143a86d 100644 --- a/baselib/src/main/res/raw/quickpass_config.json +++ b/baselib/src/main/res/raw/quickpass_config.json @@ -26,6 +26,7 @@ }, { "aidEnable": true, + "aid": "A000000333010102", "cardLabel": "UPI", "applicationVersion": "0002", "emvDDOL": "9F3704", diff --git a/baselib/src/main/res/raw/rid_config.json b/baselib/src/main/res/raw/rid_config.json index 3673d0b..c99a4d7 100644 --- a/baselib/src/main/res/raw/rid_config.json +++ b/baselib/src/main/res/raw/rid_config.json @@ -250,6 +250,16 @@ "expDate": "3230333031323331", "checkSum": "BD331F9996A490B33C13441066A09AD3FEB5F66C" }, + { + "rid": "A000000065", + "indx": "07", + "hashInd": "01", + "arithInd": "00", + "modul": "B8DAB883EF1B5763E4F861F9EA3044B276635D402F3AE5E6B6C0547E368E79A36366DAC5609B6EC486DA1A8D2002CA4F4EFC2CB0EC1573A0B0917969EB60645BAEDF11C050C5D07FED817D11E84A174859A0DAE7F7935F109229C0AC4EE5BFB3D65533A679F0486C5AEFCC937379833BEC45D79DCF97B5228B1910FA03765331", + "exponent": "010001", + "expDate": "20201231", + "checkSum": "4896DD5A9EB5B11B9DCCA6DFE336C009F69F509A" + }, { "rid": "A000000065", "indx": "08", @@ -257,7 +267,7 @@ "arithInd": "00", "modul": "B74670DAD1DC8983652000E5A7F2F8B35DFD083EE593E5BA895C95729F2BADE9C8ABF3DD9CE240C451C6CEFFC768D83CBAC76ABB8FEA58F013C647007CFF7617BAC2AE3981816F25CC7E5238EF34C4F02D0B01C24F80C2C65E7E7743A4FA8E23206A23ECE290C26EA56DB085C5C5EAE26292451FC8292F9957BE8FF20FAD53E5", "exponent": "03", - "expDate": "3230333031323331", + "expDate": "20201231", "checkSum": "DD36D5896228C8C4900742F107E2F91FE50BC7EE" }, { @@ -277,7 +287,7 @@ "arithInd": "00", "modul": "99B63464EE0B4957E4FD23BF923D12B61469B8FFF8814346B2ED6A780F8988EA9CF0433BC1E655F05EFA66D0C98098F25B659D7A25B8478A36E489760D071F54CDF7416948ED733D816349DA2AADDA227EE45936203CBF628CD033AABA5E5A6E4AE37FBACB4611B4113ED427529C636F6C3304F8ABDD6D9AD660516AE87F7F2DDF1D2FA44C164727E56BBC9BA23C0285", "exponent": "03", - "expDate": "3230333031323331", + "expDate": "20201231", "checkSum": "C75E5210CBE6E8F0594A0F1911B07418CADB5BAB" }, { @@ -287,7 +297,7 @@ "arithInd": "00", "modul": "A2583AA40746E3A63C22478F576D1EFC5FB046135A6FC739E82B55035F71B09BEB566EDB9968DD649B94B6DEDC033899884E908C27BE1CD291E5436F762553297763DAA3B890D778C0F01E3344CECDFB3BA70D7E055B8C760D0179A403D6B55F2B3B083912B183ADB7927441BED3395A199EEFE0DEBD1F5FC3264033DA856F4A8B93916885BD42F9C1F456AAB8CFA83AC574833EB5E87BB9D4C006A4B5346BD9E17E139AB6552D9C58BC041195336485", "exponent": "03", - "expDate": "3230333031323331", + "expDate": "20201231", "checkSum": "D9FD62C9DD4E6DE7741E9A17FB1FF2C5DB948BCB" }, { @@ -297,7 +307,7 @@ "arithInd": "00", "modul": "AEED55B9EE00E1ECEB045F61D2DA9A66AB637B43FB5CDBDB22A2FBB25BE061E937E38244EE5132F530144A3F268907D8FD648863F5A96FED7E42089E93457ADC0E1BC89C58A0DB72675FBC47FEE9FF33C16ADE6D341936B06B6A6F5EF6F66A4EDD981DF75DA8399C3053F430ECA342437C23AF423A211AC9F58EAF09B0F837DE9D86C7109DB1646561AA5AF0289AF5514AC64BC2D9D36A179BB8A7971E2BFA03A9E4B847FD3D63524D43A0E8003547B94A8A75E519DF3177D0A60BC0B4BAB1EA59A2CBB4D2D62354E926E9C7D3BE4181E81BA60F8285A896D17DA8C3242481B6C405769A39D547C74ED9FF95A70A796046B5EFF36682DC29", "exponent": "03", - "expDate": "3230333031323331", + "expDate": "20201231", "checkSum": "43A3151513B7ADCEB92DBEA2A262CEB336D26C83" } ] \ No newline at end of file