Skip to content
This repository has been archived by the owner on Sep 13, 2022. It is now read-only.

Commit

Permalink
Refact: Exemple App
Browse files Browse the repository at this point in the history
Feat: Added more generic use case

Signed-off-by: Meddy Menzikoff <m.menzikoff@oneclickflare.fr>
  • Loading branch information
ocfmem committed Feb 25, 2020
1 parent a08001f commit 103a161
Show file tree
Hide file tree
Showing 13 changed files with 526 additions and 151 deletions.
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,16 +8,16 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc

import org.eclipse.keyple.core.seproxy.ReaderPlugin

/**
* The PcscPlugin interface provides the public elements used to manage the Android OMAPI plugin.
*/
interface AndroidNfcPlugin : ReaderPlugin{
interface AndroidNfcPlugin : ReaderPlugin {
companion object {
const val PLUGIN_NAME = "AndroidNfcPlugin"
}
}
}
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,7 +8,7 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc

import org.eclipse.keyple.core.seproxy.AbstractPluginFactory
Expand All @@ -23,5 +23,4 @@ class AndroidNfcPluginFactory : AbstractPluginFactory() {
override fun getPluginInstance(): ReaderPlugin {
return AndroidNfcPluginImpl
}

}
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2018 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,7 +8,7 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc

import org.eclipse.keyple.core.seproxy.SeReader
Expand All @@ -18,7 +18,6 @@ import java.util.HashMap
import java.util.SortedSet
import java.util.TreeSet


/**
* Enables Keyple to communicate with the the Android device embedded NFC reader. In the Android
* platform, NFC reader must be link to an application activity.
Expand All @@ -30,9 +29,9 @@ import java.util.TreeSet
*
*
*/
internal object AndroidNfcPluginImpl: AbstractPlugin(AndroidNfcPlugin.PLUGIN_NAME), AndroidNfcPlugin{
internal object AndroidNfcPluginImpl : AbstractPlugin(AndroidNfcPlugin.PLUGIN_NAME), AndroidNfcPlugin {

private val parameters = HashMap<String, String>()// not in use in
private val parameters = HashMap<String, String>() // not in use in

override fun getParameters(): Map<String, String> {

Expand All @@ -45,7 +44,6 @@ internal object AndroidNfcPluginImpl: AbstractPlugin(AndroidNfcPlugin.PLUGIN_NAM
parameters[key] = value
}


/**
* For an Android NFC device, the Android NFC Plugin manages only one @[AndroidNfcReaderImpl].
*
Expand All @@ -55,7 +53,7 @@ internal object AndroidNfcPluginImpl: AbstractPlugin(AndroidNfcPlugin.PLUGIN_NAM
override fun initNativeReaders(): SortedSet<SeReader> {
Timber.d("InitNativeReader() add the unique instance of AndroidNfcReaderImpl")

//Nfc android adapter availability is checked in AndroidNfcFragment
// Nfc android adapter availability is checked in AndroidNfcFragment
val readers = TreeSet<SeReader>()
readers.add(AndroidNfcReaderImpl)
return readers
Expand Down
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2018 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,12 +8,11 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc

import org.eclipse.keyple.core.seproxy.protocol.SeCommonProtocols
import org.eclipse.keyple.core.seproxy.protocol.SeProtocol

import java.util.EnumSet

/**
Expand Down Expand Up @@ -48,9 +47,9 @@ object AndroidNfcProtocolSettings {
* @return a settings map
*/
@Throws(NoSuchElementException::class)
fun getSpecificSettings(specificProtocols: EnumSet<SeCommonProtocols>)
: Map<SeProtocol, String> {
return specificProtocols.filter { allSettings[it] != null }.associateBy({it}, { getSetting(it)})
fun getSpecificSettings(specificProtocols: EnumSet<SeCommonProtocols>):
Map<SeProtocol, String> {
return specificProtocols.filter { allSettings[it] != null }.associateBy({ it }, { getSetting(it) })
}

/**
Expand All @@ -61,7 +60,7 @@ object AndroidNfcProtocolSettings {
* @throws No such Element Exception if protocol not found in settings
*/
@Throws(NoSuchElementException::class)
fun getSetting(seProtocol: SeProtocol): String{
fun getSetting(seProtocol: SeProtocol): String {
return allSettings.getValue(seProtocol)
}
}
}
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,13 +8,12 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc

import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter

import org.eclipse.keyple.core.seproxy.SeReader
import org.eclipse.keyple.core.seproxy.event.ObservableReader

Expand Down
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2018 Calypso Networks Association https://www.calypsonet-asso.org/
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information regarding copyright
* ownership.
Expand All @@ -8,14 +8,15 @@
* Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
********************************************************************************/
package org.eclipse.keyple.plugin.android.nfc


import android.annotation.TargetApi
import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
import org.eclipse.keyple.core.seproxy.exception.KeypleChannelControlException
import org.eclipse.keyple.core.seproxy.exception.KeypleIOReaderException
Expand Down Expand Up @@ -43,7 +44,6 @@ import java.util.HashMap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


/**
* Implementation of [AndroidNfcReader] based on keyple core abstract classes [AbstractObservableLocalReader]
* and
Expand All @@ -56,13 +56,12 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
// keep state between session if required
private var tagProxy: TagProxy? = null

private val parameters = HashMap<String, String>()
private val parameters = HashMap<String, String?>()

private val executorService: ExecutorService

private const val NO_TAG = "no-tag"


/**
* Build Reader Mode flags Integer from parameters
*
Expand All @@ -87,7 +86,6 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
for (seProtocol in this.protocolsMap.keys) {
if (SeCommonProtocols.PROTOCOL_ISO14443_4 == seProtocol) {
flags = flags or NfcAdapter.FLAG_READER_NFC_B or NfcAdapter.FLAG_READER_NFC_A

} else if (seProtocol === SeCommonProtocols.PROTOCOL_MIFARE_UL || seProtocol === SeCommonProtocols.PROTOCOL_MIFARE_CLASSIC) {
flags = flags or NfcAdapter.FLAG_READER_NFC_A
}
Expand Down Expand Up @@ -140,7 +138,7 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
*
* @return parameters
*/
override fun getParameters(): Map<String, String> {
override fun getParameters(): Map<String, String?> {
return parameters
}

Expand All @@ -163,10 +161,9 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
parameters[AndroidNfcReader.FLAG_READER_NO_PLATFORM_SOUNDS],
parameters[AndroidNfcReader.FLAG_READER_PRESENCE_CHECK_DELAY])

val correctParameter = (key == AndroidNfcReader.FLAG_READER_SKIP_NDEF_CHECK && value == "1" || value == "0"
|| key == AndroidNfcReader.FLAG_READER_NO_PLATFORM_SOUNDS && value == "1" || value == "0"
|| key == AndroidNfcReader.FLAG_READER_PRESENCE_CHECK_DELAY && Integer.parseInt(value) > -1)

val correctParameter = (key == AndroidNfcReader.FLAG_READER_SKIP_NDEF_CHECK && value == "1" || value == "0" ||
key == AndroidNfcReader.FLAG_READER_NO_PLATFORM_SOUNDS && value == "1" || value == "0" ||
key == AndroidNfcReader.FLAG_READER_PRESENCE_CHECK_DELAY && Integer.parseInt(value) > -1)

if (correctParameter) {
Timber.w("Adding parameter : $key - $value")
Expand All @@ -175,7 +172,6 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
Timber.w("Unrecognized parameter : $key")
throw IllegalArgumentException("Unrecognized parameter $key : $value")
}

}

/**
Expand All @@ -187,7 +183,6 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
return TransmissionMode.CONTACTLESS
}


/**
* Callback function invoked by @[NfcAdapter] when a @[Tag] is discovered A
* TagTransceiver is created based on the Tag technology see [TagProxy.getTagProxy]
Expand All @@ -196,25 +191,38 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
* @param tag : detected tag
*/
override fun onTagDiscovered(tag: Tag?) {
Timber.i("Received Tag Discovered event")
//nfcAdapter.ignore(tag, 1000, onTagRemoved, Handler(Looper.getMainLooper()));
Timber.i("Received Tag Discovered event $tag")
// addRemovedListener(tag)
tag?.let {
try {
Timber.i("Getting tag proxy")
tagProxy = TagProxy.getTagProxy(tag)
onEvent(InternalEvent.SE_INSERTED)

} catch (e: KeypleReaderException) {
e.printStackTrace()
Timber.e(e)
}
}
}

@TargetApi(24)
private fun addRemovedListener(tag: Tag?) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
nfcAdapter?.ignore(tag, 1000, {
Timber.i("Tag Proxy removed")
tagProxy = null
}, null)
}
}

/**
*
* @return true if a SE is present
*/
public override fun checkSePresence(): Boolean {
return tagProxy != null && tagProxy!!.isConnected
val result = tagProxy != null && tagProxy?.isConnected == true
Timber.d("checkSePresence: $result $tagProxy")
return result
// TODO: the right implementation is:
// return tagProxy != null;
// To be updated when the onTagRemoved will be available
Expand All @@ -223,7 +231,7 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
public override fun getATR(): ByteArray? {
val atr = tagProxy?.atr
Timber.d("ATR : ${ByteArrayUtil.toHex(atr)}")
return if(atr?.isNotEmpty() == true) atr else null
return if (atr?.isNotEmpty() == true) atr else null
}

public override fun isPhysicalChannelOpen(): Boolean {
Expand All @@ -237,12 +245,10 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
Timber.d("Connect to tag..")
tagProxy?.connect()
Timber.i("Tag connected successfully : ${printTagId()}")

} catch (e: IOException) {
Timber.e(e, "Error while connecting to Tag ")
throw KeypleChannelControlException("Error while opening physical channel", e)
}

} else {
Timber.i("Tag is already connected to : ${printTagId()}")
}
Expand Down Expand Up @@ -273,24 +279,24 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
@Throws(KeypleIOReaderException::class)
public override fun transmitApdu(apduIn: ByteArray): ByteArray {
Timber.d("Send data to card : ${apduIn.size} bytes")
return with(tagProxy){
if(this == null){
return with(tagProxy) {
if (this == null) {
throw KeypleIOReaderException(
"Error while transmitting APDU, invalid out data buffer")
}else{
} else {
try {
val bytes = transceive(apduIn)
if(bytes.size<2){
if (bytes.size <2) {
throw KeypleIOReaderException(
"Error while transmitting APDU, invalid out data buffer")
}else{
} else {
Timber.d("Receive data from card : ${ByteArrayUtil.toHex(bytes)}")
bytes
}
}catch (e: IOException){
} catch (e: IOException) {
throw KeypleIOReaderException(
"Error while transmitting APDU, invalid out data buffer", e)
}catch (e: NoSuchElementException){
} catch (e: NoSuchElementException) {
throw KeypleReaderException("Error while transmitting APDU, no such Element", e)
}
}
Expand All @@ -314,10 +320,10 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR
}

override fun printTagId(): String {
return with(tagProxy){
if(this == null){
return with(tagProxy) {
if (this == null) {
NO_TAG
}else{
} else {
// build a user friendly TechList
val techList = tag.techList.joinToString(separator = ", ") { it.replace("android.nfc.tech.", "") }
// build a hexa TechId
Expand Down Expand Up @@ -345,6 +351,5 @@ internal object AndroidNfcReaderImpl : AbstractObservableLocalReader(AndroidNfcR

override fun disableNFCReaderMode(activity: Activity) {
nfcAdapter?.disableReaderMode(activity)

}
}

0 comments on commit 103a161

Please sign in to comment.