├── .idea
├── .name
├── .gitignore
├── vcs.xml
├── compiler.xml
├── misc.xml
└── gradle.xml
├── Secure
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── rmp
│ │ │ │ └── secure
│ │ │ │ ├── pin
│ │ │ │ ├── PinEntryView.kt
│ │ │ │ └── PinEntry.kt
│ │ │ │ ├── SecureEngine.kt
│ │ │ │ └── common
│ │ │ │ └── hexToByteArray.kt
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── boder_gray.xml
│ │ │ └── layout
│ │ │ └── pin_entry_layout.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── rmp
│ │ │ └── secure
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── rmp
│ │ └── secure
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── themes.xml
│ │ │ │ └── colors.xml
│ │ │ ├── drawable
│ │ │ │ ├── error.png
│ │ │ │ ├── warning.jpg
│ │ │ │ ├── tap_to_pay.png
│ │ │ │ ├── txn_approve.png
│ │ │ │ ├── txn_decline.png
│ │ │ │ ├── boder_dark_gray.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── main_activity.xml
│ │ │ │ ├── splash_activity.xml
│ │ │ │ ├── fragment_txn_result.xml
│ │ │ │ ├── fragment_error.xml
│ │ │ │ ├── fragment_warning.xml
│ │ │ │ ├── fragment_pin_entry.xml
│ │ │ │ ├── fragment_loading.xml
│ │ │ │ ├── fragment_detect_card.xml
│ │ │ │ ├── fragment_amount_entry.xml
│ │ │ │ ├── fragment_transaction_info_confirm.xml
│ │ │ │ └── key_broad_num.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── rmp
│ │ │ │ └── emvnfcdemo
│ │ │ │ ├── data
│ │ │ │ ├── TransactionType.kt
│ │ │ │ ├── Currency.kt
│ │ │ │ ├── Amount.kt
│ │ │ │ ├── Track2.kt
│ │ │ │ └── TransactionData.kt
│ │ │ │ ├── ui
│ │ │ │ ├── fragment
│ │ │ │ │ ├── PinEntryFragment.kt
│ │ │ │ │ ├── LoadingFragment.kt
│ │ │ │ │ ├── DetectCardFragment.kt
│ │ │ │ │ ├── ErrorFragment.kt
│ │ │ │ │ ├── WarningFragment.kt
│ │ │ │ │ ├── TxnResultFragment.kt
│ │ │ │ │ ├── TxnInfoConfirmFragment.kt
│ │ │ │ │ └── AmountEntryFragment.kt
│ │ │ │ ├── UiController.kt
│ │ │ │ └── UiControllerImpl.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── SplashActivity.kt
│ │ │ │ └── transaction
│ │ │ │ ├── cardreader
│ │ │ │ └── CardReaderIpml.kt
│ │ │ │ └── EmvProcess.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── rmp
│ │ │ └── emvnfcdemo
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── rmp
│ │ └── emvnfcdemo
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── EmvEngine
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── rmp
│ │ │ │ └── emvengine
│ │ │ │ ├── data
│ │ │ │ ├── OdaType.kt
│ │ │ │ ├── RSAPublicKey.kt
│ │ │ │ ├── TransactionDecision.kt
│ │ │ │ ├── HostAuthResponseCode.kt
│ │ │ │ ├── Capk.kt
│ │ │ │ ├── EmvTags.kt
│ │ │ │ ├── CvmMethod.kt
│ │ │ │ ├── aid.kt
│ │ │ │ ├── TransactionData.kt
│ │ │ │ ├── EmvError.kt
│ │ │ │ ├── EmvCoreError.kt
│ │ │ │ └── TlvObject.kt
│ │ │ │ ├── CardReader.kt
│ │ │ │ ├── process
│ │ │ │ ├── ClessEmvProcess.kt
│ │ │ │ ├── EntryPoint.kt
│ │ │ │ └── EntryPointImpl.kt
│ │ │ │ ├── common
│ │ │ │ ├── RSAHelper.kt
│ │ │ │ ├── CommandHelper.kt
│ │ │ │ ├── HexStringUtil.kt
│ │ │ │ └── LogUtils.kt
│ │ │ │ ├── EmvCore.kt
│ │ │ │ └── EmvCoreImpl.kt
│ │ └── AndroidManifest.xml
│ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── rmp
│ │ │ └── emvengine
│ │ │ └── ExampleInstrumentedTest.kt
│ └── test
│ │ └── java
│ │ └── com
│ │ └── rmp
│ │ └── emvengine
│ │ └── ExampleUnitTest.kt
├── proguard-rules.pro
└── build.gradle
├── HostController
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── rmp
│ │ │ └── hostcontroller
│ │ │ ├── HostTransactionData.kt
│ │ │ ├── HostController.kt
│ │ │ └── Iso8583HostController.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── rmp
│ │ │ └── hostcontroller
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── rmp
│ │ └── hostcontroller
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── static
├── step1.png
├── step2.png
├── step3.png
├── step4.png
└── step5.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
├── gradle.properties
├── README.md
├── gradlew.bat
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | EMV Nfc demo
--------------------------------------------------------------------------------
/Secure/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/EmvEngine/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/EmvEngine/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Secure/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/HostController/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/HostController/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/static/step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/static/step1.png
--------------------------------------------------------------------------------
/static/step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/static/step2.png
--------------------------------------------------------------------------------
/static/step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/static/step3.png
--------------------------------------------------------------------------------
/static/step4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/static/step4.png
--------------------------------------------------------------------------------
/static/step5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/static/step5.png
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EMV Nfc demo
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/drawable/error.png
--------------------------------------------------------------------------------
/Secure/src/main/java/com/rmp/secure/pin/PinEntryView.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.secure.pin
2 |
3 | import android.content.Context
4 | import android.view.View
--------------------------------------------------------------------------------
/app/src/main/res/drawable/warning.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/drawable/warning.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/tap_to_pay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/drawable/tap_to_pay.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/txn_approve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/drawable/txn_approve.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/txn_decline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/drawable/txn_decline.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/OdaType.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | enum class OdaType {
4 | SDA,
5 | DDA,
6 | CDA,
7 | FDDA
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/data/TransactionType.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.data
2 |
3 | enum class TransactionType(val value: String) {
4 | SALE("SALE")
5 | }
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rememberpassword/Nfc-emv-application-demo/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/RSAPublicKey.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | data class RSAPublicKey (
4 | val modulus: ByteArray,
5 | val exponent: ByteArray
6 | )
--------------------------------------------------------------------------------
/Secure/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/HostController/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/TransactionDecision.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | enum class TransactionDecision(val value: Int) {
4 | AAC(0x00),
5 | TC(0x40),
6 | ARQC(0x80),
7 | }
--------------------------------------------------------------------------------
/HostController/src/main/java/com/rmp/hostcontroller/HostTransactionData.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.hostcontroller
2 |
3 | data class HostTransactionData(
4 | val amount: String,
5 | val currency: String,
6 |
7 | )
8 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/HostAuthResponseCode.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | internal object HostAuthResponseCode {
4 | val LIST_APPROVE_RESPONSE = listOf("00","08","10","78")
5 | }
--------------------------------------------------------------------------------
/HostController/src/main/java/com/rmp/hostcontroller/HostController.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.hostcontroller
2 |
3 | interface HostController {
4 |
5 | fun performFinancialTransaction(transactionData: HostTransactionData): HostTransactionData
6 |
7 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/Capk.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | data class Capk (
4 | val index: Int,
5 | val rid: ByteArray,
6 | val modulus: ByteArray,
7 | val exponent: ByteArray,
8 | val sha: ByteArray?
9 | )
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jul 11 22:33:26 ICT 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/Secure/src/main/res/drawable/boder_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/boder_dark_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/data/Currency.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.data
2 |
3 | enum class Currency (
4 | val label: String,
5 | val symbol: String,
6 | val code: Int,
7 | val exponent: Int
8 | ){
9 | USD("USD","$",840,2),
10 | EURO("EURO","€",978,2),
11 | }
12 |
--------------------------------------------------------------------------------
/Secure/src/main/java/com/rmp/secure/SecureEngine.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.secure
2 |
3 | import android.content.Context
4 | import com.rmp.secure.pin.PinEntry
5 |
6 | class SecureEngine(private val context: Context) {
7 |
8 | fun getPinEntry(): PinEntry{
9 | return PinEntry(context)
10 | }
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/EmvTags.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | enum class EmvTags(val value: Long) {
4 | //define tag for emv engine module
5 | EMV_CL_FLOOR_LIMIT(0xDF8101L), // cless floor limit
6 | EMV_CL_CVM_LIMIT(0xDF8102L), //cless cvm limit
7 | EMV_CL_TRANS_LIMIT(0xDF8103L),//cless transaction limit
8 |
9 |
10 | }
--------------------------------------------------------------------------------
/HostController/src/main/java/com/rmp/hostcontroller/Iso8583HostController.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.hostcontroller
2 |
3 | class Iso8583HostController: HostController {
4 |
5 | override fun performFinancialTransaction(transactionData: HostTransactionData): HostTransactionData {
6 |
7 |
8 | //TODO("Not yet implemented")
9 |
10 | return transactionData
11 | }
12 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/CvmMethod.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | enum class CvmMethod {
4 | NO_CVM,
5 | ONLINE_PIN,
6 | OFFLINE_PL_PIN,
7 | OFFLINE_PL_PIN_SIGN,
8 | OFFLINE_EN_PIN,
9 | OFFLINE_EN_PIN_SIGN,
10 | CDCVM,
11 | SIGNATURE
12 | }
13 | enum class PinEntryStatus{
14 | EXC_SUCCESS,
15 | ERROR,
16 | CANCEL,
17 | BYPASS
18 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | jcenter() // Warning: this repository is going to shut down soon
7 | }
8 | }
9 | rootProject.name = "EMV Nfc demo"
10 | include ':app'
11 | include ':EmvEngine'
12 | include ':Secure'
13 | include ':HostController'
14 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
11 |
--------------------------------------------------------------------------------
/Secure/src/test/java/com/rmp/secure/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.secure
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/aid.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | data class Aid(
4 | val aid: String,
5 | val label: String? = null,
6 | val priority: Int? = null,
7 | val isPartial: Boolean? = null,
8 | val data: List? = null,
9 | )
10 |
11 | enum class KernelId(val value: Int) {
12 | EMV(0),
13 | VISA(3),
14 | MASTER(2),
15 | AMEX(4),
16 | DISCOVER(6),
17 | POBC(7),
18 | JCB(5)
19 | }
--------------------------------------------------------------------------------
/HostController/src/test/java/com/rmp/hostcontroller/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.hostcontroller
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/rmp/emvnfcdemo/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo
2 |
3 |
4 | import org.junit.Test
5 |
6 | import org.junit.Assert.*
7 |
8 | /**
9 | * Example local unit test, which will execute on the development machine (host).
10 | *
11 | * See [testing documentation](http://d.android.com/tools/testing).
12 | */
13 | class ExampleUnitTest {
14 | @Test
15 | fun addition_isCorrect() {
16 | val s = "0509"
17 |
18 | val z = 0
19 |
20 | }
21 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/CardReader.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine
2 |
3 | interface CardReader {
4 |
5 | suspend fun detectClessCardAndActive(detectTime: Int): Boolean
6 |
7 | fun close()
8 |
9 | fun transmitData(data: ByteArray): TransmitResult
10 |
11 | fun isCardRemoved(): Boolean
12 | }
13 |
14 | data class TransmitResult (
15 | val error: CardReaderError?,
16 | val data: ByteArray?
17 | )
18 |
19 | enum class CardReaderError {
20 | CARD_REMOVED,
21 | CANT_ACTIVE
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/data/Amount.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.data
2 |
3 | data class Amount (
4 | val value: Long,
5 | val currency: Currency
6 | ) {
7 |
8 |
9 | fun toAmountWithCurrency(): String {
10 | var result = value.toString()
11 | if (result.length <= 3) {
12 | result = result.padStart(3, '0')
13 | }
14 | // add '.'
15 | return result.substring(0, result.length - 2) + "." + result.substring(result.length - 2) + currency.symbol
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/data/Track2.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.data
2 |
3 | class Track2(
4 | val pan: String,
5 | val expDate: String,
6 | val serviceCode: String,
7 | val additionalData: String?
8 | )
9 |
10 | fun String.toTrack2(): Track2? {
11 | val track2Format = """(\d{1,19})(D|d)(\d{4})(\d{3})([^\?]*)"""
12 | val regex = Regex(track2Format)
13 | val matchValue = regex.matchEntire(this)?.groupValues
14 |
15 | return matchValue?.let {
16 | Track2(it[1], it[3], it[4], if (it.size == 4) it[5] else null)
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/process/ClessEmvProcess.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.process
2 |
3 | import com.rmp.emvengine.data.TlvObject
4 |
5 | internal interface ClessEmvProcess {
6 |
7 | fun preprocessing(data: List)
8 |
9 | fun initiateTransaction()
10 |
11 | fun readRecord()
12 |
13 | fun offlineDataAuthenticationAndProcessingRestriction()
14 |
15 | fun cardholderVerification()
16 |
17 | fun terminalRiskManagement()
18 |
19 | fun terminalActionAnalysis()
20 |
21 | fun cardActionlActionAnalysis()
22 |
23 | fun getLastError(): String?
24 |
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/ui/fragment/PinEntryFragment.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.ui.fragment
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.rmp.emvnfcdemo.R
9 |
10 | class PinEntryFragment: Fragment() {
11 |
12 | override fun onCreateView(
13 | inflater: LayoutInflater,
14 | container: ViewGroup?,
15 | savedInstanceState: Bundle?
16 | ): View? {
17 | return inflater.inflate(R.layout.fragment_pin_entry,container,false)
18 | }
19 | }
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
--------------------------------------------------------------------------------
/Secure/src/androidTest/java/com/rmp/secure/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.secure
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.rmp.secure.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/rmp/emvnfcdemo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.rmp.emvnfcdemo", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/EmvEngine/src/androidTest/java/com/rmp/emvengine/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.rmp.emvengine.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/process/EntryPoint.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.process
2 |
3 | import com.rmp.emvengine.data.Aid
4 | import com.rmp.emvengine.data.TlvObject
5 |
6 | internal interface EntryPoint {
7 |
8 | fun preprocessing(data: List)
9 |
10 | fun combinationSelection(list: List): List?
11 |
12 | fun finalCombinationSelection(aid: Aid): List?
13 |
14 | fun kernelActivation()
15 |
16 | fun initiateTransaction()
17 |
18 | fun readRecord()
19 |
20 | fun offlineDataAuthenticationAndProcessingRestriction()
21 |
22 | fun cardholderVerification(data: List)
23 |
24 | fun terminalRiskManagement()
25 |
26 | fun terminalActionAnalysis()
27 |
28 | fun cardActionlActionAnalysis()
29 |
30 | fun getLastError(): String?
31 |
32 | }
--------------------------------------------------------------------------------
/EmvEngine/src/main/java/com/rmp/emvengine/data/TransactionData.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvengine.data
2 |
3 | internal class TransactionData {
4 |
5 | val terminalData: MutableMap = mutableMapOf()
6 | val cardData: MutableMap = mutableMapOf()
7 | val cardAppData: MutableList = mutableListOf()
8 | var transactionDecision: TransactionDecision = TransactionDecision.AAC
9 | var cvm : CvmMethod? = null
10 | var kernelId: KernelId? = null
11 | var recordOda: ByteArray = byteArrayOf()
12 | var isOdaSuccess = false
13 | var capk: Capk? = null
14 | var odaType: OdaType? = null
15 |
16 |
17 |
18 | fun getData(tag: Long): ByteArray?{
19 | return terminalData[tag]?.value ?: cardData[tag]?.value
20 | }
21 | fun getData(tag: String) = getData(tag.toLong(16))
22 |
23 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/HostController/src/androidTest/java/com/rmp/hostcontroller/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.hostcontroller
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.rmp.hostcontroller.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/Secure/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/EmvEngine/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/HostController/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/data/TransactionData.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.data
2 |
3 | import com.rmp.emvengine.data.Aid
4 | import com.rmp.emvengine.data.CvmMethod
5 | import com.rmp.emvengine.data.TransactionDecision
6 |
7 | class TransactionData {
8 |
9 | var transactionType: TransactionType = TransactionType.SALE
10 | var amount: Amount? = null
11 | var cvmMethod: CvmMethod? = null
12 | var txnDecision: TransactionDecision? = null
13 | var txnDate: String? = null // format: yyMMdd
14 | var txnDateDisplay: String? = null // format: dd/MM/yyyy
15 | var txnTime: String? = null // format: HHmmss
16 | var txnTimeDisplay: String? = null // format: HH:mm:ss
17 |
18 | //
19 | var pan: String? = null
20 | var expiredDate: String? = null
21 | var track2: Track2? = null
22 | var selectedAid: Aid? = null
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/ui/fragment/LoadingFragment.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.ui.fragment
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.ProgressBar
8 | import android.widget.TextView
9 | import androidx.fragment.app.Fragment
10 | import com.rmp.emvnfcdemo.R
11 |
12 | class LoadingFragment(private val title: String): Fragment() {
13 |
14 |
15 | override fun onCreateView(
16 | inflater: LayoutInflater,
17 | container: ViewGroup?,
18 | savedInstanceState: Bundle?
19 | ): View? {
20 | return inflater.inflate(R.layout.fragment_loading,container,false)
21 | }
22 |
23 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
24 | super.onViewCreated(view, savedInstanceState)
25 | view.findViewById(R.id.tv_title).text = title
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/splash_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rmp/emvnfcdemo/ui/fragment/DetectCardFragment.kt:
--------------------------------------------------------------------------------
1 | package com.rmp.emvnfcdemo.ui.fragment
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.Button
8 | import android.widget.TextView
9 | import androidx.fragment.app.Fragment
10 | import com.rmp.emvnfcdemo.R
11 | import com.rmp.emvnfcdemo.ui.UiAction
12 |
13 | class DetectCardFragment(
14 | private val amount: String,
15 | private val cb: (UiAction) -> Unit
16 | ) : Fragment() {
17 |
18 | override fun onCreateView(
19 | inflater: LayoutInflater,
20 | container: ViewGroup?,
21 | savedInstanceState: Bundle?
22 | ): View? {
23 | return inflater.inflate(R.layout.fragment_detect_card, container,false)
24 | }
25 |
26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
27 | super.onViewCreated(view, savedInstanceState)
28 | view.findViewById(R.id.tv_amount).text = amount
29 | view.findViewById