Skip to content

Commit

Permalink
feat: switch to Keypop API (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanpierrefortune authored Dec 4, 2023
1 parent e0b700b commit 107cd8b
Show file tree
Hide file tree
Showing 18 changed files with 163 additions and 143 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]
### Upgraded
- Calypsonet Terminal Reader API `1.3.0` -> Keypop Reader API `2.0.0`
- Calypsonet Terminal Calypso API `1.8.0` -> Keypop Calypso Card API `2.0.0`
- Keyple Service Library `2.3.1` -> `3.0.0`
- Keyple Service Resource Library `2.1.1` -> `3.0.0`
- Keyple Calypso Card Library `2.3.5` -> `3.0.0`
- Keyple Util Library `2.3.0` -> `2.3.1`
- Keyple Distributed Local Library `2.2.0` -> `2.3.0`
- Keyple Distributed Network Library `2.2.0` -> `2.3.0`
- Keyple Distributed Remote Library `2.2.1` -> `2.3.0`

### Added
New dependencies
- Keypop Crypto Legacy SAM API `0.3.0`
- Keyple Calypso Crypto LegacySAM Library `0.4.0`

## [2023.05.31]
### Added
Expand Down
14 changes: 7 additions & 7 deletions client/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,20 @@ dependencies {
implementation("org.calypsonet.keyple:keyple-demo-common-lib:2.0.0-SNAPSHOT") { isChanging = true }

// Keyple core
implementation("org.calypsonet.terminal:calypsonet-terminal-reader-java-api:1.3.0")
implementation("org.calypsonet.terminal:calypsonet-terminal-calypso-java-api:1.8.0")
implementation("org.eclipse.keypop:keypop-reader-java-api:2.0.0")
implementation("org.eclipse.keypop:keypop-calypso-card-java-api:2.0.0")
implementation("org.eclipse.keyple:keyple-common-java-api:2.0.0")
implementation("org.eclipse.keyple:keyple-util-java-lib:2.3.0")
implementation("org.eclipse.keyple:keyple-service-java-lib:2.3.1")
implementation("org.eclipse.keyple:keyple-card-calypso-java-lib:2.3.5")
implementation("org.eclipse.keyple:keyple-util-java-lib:2.3.1")
implementation("org.eclipse.keyple:keyple-service-java-lib:3.0.0")
implementation("org.eclipse.keyple:keyple-card-calypso-java-lib:3.0.0")

// Keyple reader plugins
implementation("org.eclipse.keyple:keyple-plugin-android-nfc-java-lib:2.0.1")
implementation("org.eclipse.keyple:keyple-plugin-android-omapi-java-lib:2.0.1")

// Keyple distributed
implementation("org.eclipse.keyple:keyple-distributed-network-java-lib:2.2.0")
implementation("org.eclipse.keyple:keyple-distributed-local-java-lib:2.2.0")
implementation("org.eclipse.keyple:keyple-distributed-network-java-lib:2.3.0")
implementation("org.eclipse.keyple:keyple-distributed-local-java-lib:2.3.0")

// Network
implementation("org.java-websocket:Java-WebSocket:1.3.9")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
package org.calypsonet.keyple.demo.reload.remote.data

import kotlin.jvm.Throws
import org.calypsonet.terminal.reader.CardReader
import org.calypsonet.terminal.reader.ObservableCardReader
import org.calypsonet.terminal.reader.ReaderCommunicationException
import org.eclipse.keyple.core.common.KeyplePluginExtensionFactory
import org.eclipse.keyple.core.service.SmartCardServiceProvider
import org.eclipse.keypop.reader.CardReader
import org.eclipse.keypop.reader.ObservableCardReader
import org.eclipse.keypop.reader.ReaderCommunicationException
import timber.log.Timber

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,14 @@ class ReaderModule {
fun provideLocalServiceClient(
keypleSyncEndPointClient: KeypleSyncEndPointClient
): LocalServiceClient {
if (!SmartCardServiceProvider.getService()
.isDistributedLocalServiceRegistered("localService")) {
SmartCardServiceProvider.getService()
.registerDistributedLocalService(
LocalServiceClientFactoryBuilder.builder("localService")
.withSyncNode(keypleSyncEndPointClient)
.build())
}
return SmartCardServiceProvider.getService()
.getDistributedLocalService("localService")
.getExtension(LocalServiceClient::class.java)
val smartCardService = SmartCardServiceProvider.getService()
val localService =
smartCardService.getDistributedLocalService("localService")
?: smartCardService.registerDistributedLocalService(
LocalServiceClientFactoryBuilder.builder("localService")
.withSyncNode(keypleSyncEndPointClient)
.build())
return localService.getExtension(LocalServiceClient::class.java)
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,26 @@ import kotlin.jvm.Throws
import org.calypsonet.keyple.demo.common.constant.CardConstant
import org.calypsonet.keyple.demo.reload.remote.data.ReaderRepository
import org.calypsonet.keyple.demo.reload.remote.di.scopes.AppScoped
import org.calypsonet.terminal.calypso.card.CalypsoCard
import org.calypsonet.terminal.calypso.transaction.CardTransactionManager
import org.eclipse.keyple.card.calypso.CalypsoExtensionService
import org.eclipse.keyple.core.service.SmartCardServiceProvider
import org.eclipse.keypop.calypso.card.card.CalypsoCard

@AppScoped
class TicketingService @Inject constructor(private var readerRepository: ReaderRepository) {

/** Select card and retrieve CalypsoPO */
@Throws(IllegalStateException::class, Exception::class)
fun getTransactionManager(
fun getCalypsoCard(
readerName: String,
aidEnums: ArrayList<ByteArray>,
protocol: String?
): CardTransactionManager {
): CalypsoCard {
with(ReaderRepository.getReader(readerName)) {
if (isCardPresent) {
val smartCardService = SmartCardServiceProvider.getService()

val readerApiFactory = smartCardService.readerApiFactory

val reader = ReaderRepository.getReader(readerName)

/** Get the generic card extension service */
Expand All @@ -45,23 +46,25 @@ class TicketingService @Inject constructor(private var readerRepository: ReaderR
/** Verify that the extension's API level is consistent with the current service. */
smartCardService.checkCardExtension(calypsoExtension)

val cardSelectionManager = smartCardService.createCardSelectionManager()
val cardSelectionManager = readerApiFactory.createCardSelectionManager()

aidEnums.forEach {
/**
* Generic selection: configures a CardSelector with all the desired attributes to make
* the selection and read additional information afterwards
*/
val cardSelection =
val cardSelector =
if (protocol != null) {
calypsoExtension
.createCardSelection()
readerApiFactory
.createIsoCardSelector()
.filterByDfName(it)
.filterByCardProtocol(protocol)
} else {
calypsoExtension.createCardSelection().filterByDfName(it)
readerApiFactory.createIsoCardSelector().filterByDfName(it)
}
cardSelectionManager.prepareSelection(cardSelection)
cardSelectionManager.prepareSelection(
cardSelector,
calypsoExtension.calypsoCardApiFactory.createCalypsoCardSelectionExtension())
}

val selectionResult = cardSelectionManager.processCardSelectionScenario(reader)
Expand All @@ -72,8 +75,7 @@ class TicketingService @Inject constructor(private var readerRepository: ReaderR
aidEnums[selectionResult.activeSelectionIndex], calypsoCard.dfName)) {
throw IllegalStateException("Unexpected DF name")
}
return calypsoExtension.createCardTransactionWithoutSecurity(
reader, selectionResult.activeSmartCard as CalypsoCard)
return calypsoCard
} else {
throw IllegalStateException("Selection error: AID not found")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ import org.calypsonet.keyple.demo.reload.remote.data.model.AppSettings
import org.calypsonet.keyple.demo.reload.remote.data.model.CardReaderResponse
import org.calypsonet.keyple.demo.reload.remote.data.model.DeviceEnum
import org.calypsonet.keyple.demo.reload.remote.data.model.Status
import org.calypsonet.terminal.reader.ConfigurableCardReader
import org.calypsonet.terminal.reader.ObservableCardReader
import org.calypsonet.terminal.reader.spi.CardReaderObservationExceptionHandlerSpi
import org.calypsonet.terminal.reader.spi.CardReaderObserverSpi
import org.eclipse.keyple.core.service.KeyplePluginException
import org.eclipse.keyple.distributed.LocalServiceClient
import org.eclipse.keyple.plugin.android.nfc.AndroidNfcPlugin
Expand All @@ -33,6 +29,10 @@ import org.eclipse.keyple.plugin.android.nfc.AndroidNfcSupportedProtocols
import org.eclipse.keyple.plugin.android.omapi.AndroidOmapiPlugin
import org.eclipse.keyple.plugin.android.omapi.AndroidOmapiPluginFactoryProvider
import org.eclipse.keyple.plugin.android.omapi.AndroidOmapiReader
import org.eclipse.keypop.reader.ConfigurableCardReader
import org.eclipse.keypop.reader.ObservableCardReader
import org.eclipse.keypop.reader.spi.CardReaderObservationExceptionHandlerSpi
import org.eclipse.keypop.reader.spi.CardReaderObserverSpi
import timber.log.Timber

abstract class AbstractCardActivity :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ import org.calypsonet.keyple.demo.reload.remote.data.model.*
import org.calypsonet.keyple.demo.reload.remote.di.scopes.ActivityScoped
import org.calypsonet.keyple.demo.reload.remote.domain.TicketingService
import org.calypsonet.keyple.demo.reload.remote.ui.cardsummary.CardSummaryActivity
import org.calypsonet.terminal.reader.CardReaderEvent
import org.calypsonet.terminal.reader.ReaderCommunicationException
import org.eclipse.keyple.core.service.KeyplePluginException
import org.eclipse.keyple.core.util.HexUtil
import org.eclipse.keypop.reader.CardReaderEvent
import org.eclipse.keypop.reader.ReaderCommunicationException
import timber.log.Timber

@ActivityScoped
Expand Down Expand Up @@ -128,15 +128,15 @@ class CardReaderActivity : AbstractCardActivity() {
) {
withContext(Dispatchers.IO) {
try {
val transactionManager =
ticketingService.getTransactionManager(selectedDeviceReaderName, aidEnums, protocol)
val calypsoCard =
ticketingService.getCalypsoCard(selectedDeviceReaderName, aidEnums, protocol)
val analyseContractsInput = AnalyzeContractsInputDto(pluginType)
// un-mock for run
val compatibleContractOutput =
localServiceClient.executeRemoteService(
RemoteServiceId.READ_CARD_AND_ANALYZE_CONTRACTS.name,
selectedDeviceReaderName,
transactionManager.calypsoCard,
calypsoCard,
analyseContractsInput,
AnalyzeContractsOutputDto::class.java)

Expand All @@ -154,7 +154,7 @@ class CardReaderActivity : AbstractCardActivity() {
changeDisplay(
CardReaderResponse(
status, "", contracts.size, buildCardTitles(contracts), arrayListOf(), ""),
HexUtil.toHex(transactionManager.calypsoCard.applicationSerialNumber),
HexUtil.toHex(calypsoCard!!.applicationSerialNumber),
finishActivity)
}
} // success,
Expand All @@ -165,7 +165,7 @@ class CardReaderActivity : AbstractCardActivity() {
launchInvalidCardResponse(
String.format(
getString(R.string.card_invalid_structure),
HexUtil.toHex(transactionManager.calypsoCard.applicationSubtype)))
HexUtil.toHex(calypsoCard!!.applicationSubtype)))
} // card rejected
3 -> {
launchInvalidCardResponse(getString(R.string.card_not_personalized))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import org.calypsonet.keyple.demo.reload.remote.data.model.DeviceEnum
import org.calypsonet.keyple.demo.reload.remote.data.model.Status
import org.calypsonet.keyple.demo.reload.remote.di.scopes.ActivityScoped
import org.calypsonet.keyple.demo.reload.remote.domain.TicketingService
import org.calypsonet.terminal.reader.CardReaderEvent
import org.eclipse.keyple.core.util.HexUtil
import org.eclipse.keypop.reader.CardReaderEvent
import timber.log.Timber

@ActivityScoped
Expand Down Expand Up @@ -126,23 +126,22 @@ class PersonalizationActivity : AbstractCardActivity() {
) {
withContext(Dispatchers.IO) {
try {
val transactionManager =
ticketingService.getTransactionManager(selectedDeviceReaderName, aidEnums, protocol)
val calypsoCard =
ticketingService.getCalypsoCard(selectedDeviceReaderName, aidEnums, protocol)
val cardIssuanceInput = CardIssuanceInputDto(pluginType)
val cardIssuanceOutput =
localServiceClient.executeRemoteService(
RemoteServiceId.PERSONALIZE_CARD.name,
selectedDeviceReaderName,
transactionManager.calypsoCard,
calypsoCard,
cardIssuanceInput,
CardIssuanceOutputDto::class.java)
when (cardIssuanceOutput.statusCode) {
0 -> {
runOnUiThread {
changeDisplay(
CardReaderResponse(Status.SUCCESS, "", 0, arrayListOf(), arrayListOf(), ""),
applicationSerialNumber =
HexUtil.toHex(transactionManager.calypsoCard.applicationSerialNumber),
applicationSerialNumber = HexUtil.toHex(calypsoCard!!.applicationSerialNumber),
finishActivity = true)
}
} // success,
Expand All @@ -153,7 +152,7 @@ class PersonalizationActivity : AbstractCardActivity() {
launchInvalidCardResponse(
String.format(
getString(R.string.card_invalid_structure),
HexUtil.toHex(transactionManager.calypsoCard.applicationSubtype)))
HexUtil.toHex(calypsoCard!!.applicationSubtype)))
} // card rejected
}
} catch (e: IllegalStateException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import org.calypsonet.keyple.demo.reload.remote.data.model.DeviceEnum
import org.calypsonet.keyple.demo.reload.remote.data.model.Status
import org.calypsonet.keyple.demo.reload.remote.di.scopes.ActivityScoped
import org.calypsonet.keyple.demo.reload.remote.domain.TicketingService
import org.calypsonet.terminal.reader.CardReaderEvent
import org.eclipse.keyple.core.util.HexUtil
import org.eclipse.keypop.reader.CardReaderEvent
import timber.log.Timber

@ActivityScoped
Expand Down Expand Up @@ -102,11 +102,9 @@ class ReloadActivity : AbstractCardActivity() {
withContext(Dispatchers.IO) {
try {
val readCardSerialNumber = intent.getStringExtra(CARD_APPLICATION_NUMBER)

val transactionManager =
ticketingService.getTransactionManager(selectedDeviceReaderName, aidEnums, protocol)
if (HexUtil.toHex(transactionManager.calypsoCard.applicationSerialNumber) !=
readCardSerialNumber) {
val calypsoCard =
ticketingService.getCalypsoCard(selectedDeviceReaderName, aidEnums, protocol)
if (HexUtil.toHex(calypsoCard!!.applicationSerialNumber) != readCardSerialNumber) {
// Ticket would have been bought for the Card read at step one.
// To avoid swapping we check thant loading is done on the same card
throw IllegalStateException("Not the same card")
Expand All @@ -117,7 +115,7 @@ class ReloadActivity : AbstractCardActivity() {
localServiceClient.executeRemoteService(
RemoteServiceId.READ_CARD_AND_ANALYZE_CONTRACTS.name,
selectedDeviceReaderName,
transactionManager.calypsoCard,
calypsoCard,
analyseContractsInput,
AnalyzeContractsOutputDto::class.java)

Expand All @@ -133,7 +131,7 @@ class ReloadActivity : AbstractCardActivity() {
localServiceClient.executeRemoteService(
RemoteServiceId.READ_CARD_AND_WRITE_CONTRACT.name,
selectedDeviceReaderName,
transactionManager.calypsoCard,
calypsoCard,
writeContractInputDto,
WriteContractOutputDto::class.java)

Expand All @@ -153,7 +151,7 @@ class ReloadActivity : AbstractCardActivity() {
launchInvalidCardResponse(
String.format(
getString(R.string.card_invalid_structure),
HexUtil.toHex(transactionManager.calypsoCard.applicationSubtype)))
HexUtil.toHex(calypsoCard!!.applicationSubtype)))
} // card rejected
}
} catch (e: IllegalStateException) {
Expand Down
2 changes: 1 addition & 1 deletion client/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 2023.05.31
version = 2023.12.04
archivesBaseName = keyple-demo-remote-client-android

# Project-wide Gradle settings.
Expand Down
8 changes: 4 additions & 4 deletions client/dotnet/domain/api/MainServiceApiAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,15 +369,15 @@ private CardResponse ProcessCardRequest(CardRequest cardRequest, ChannelControl
throw new UnexpectedStatusWordException($"Unexpected status word: {apduResponse.StatusWord:X}");
}
}
catch (ReaderIOException ex)
catch (ReaderIOException)
{
_reader.ClosePhysicalChannel();
throw ex;
throw;
}
catch (CardIOException ex)
catch (CardIOException)
{
_reader.ClosePhysicalChannel();
throw ex;
throw;
}
}

Expand Down
18 changes: 10 additions & 8 deletions server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,18 @@ dependencies {
implementation("org.calypsonet.keyple:keyple-demo-common-lib:2.0.0-SNAPSHOT") { isChanging = true }

// Keyple dependencies
implementation("org.calypsonet.terminal:calypsonet-terminal-reader-java-api:1.3.0")
implementation("org.calypsonet.terminal:calypsonet-terminal-calypso-java-api:1.8.0")
implementation("org.eclipse.keypop:keypop-reader-java-api:2.0.0")
implementation("org.eclipse.keypop:keypop-calypso-card-java-api:2.0.0")
implementation("org.eclipse.keypop:keypop-calypso-crypto-legacysam-java-api:0.3.0")
implementation("org.eclipse.keyple:keyple-common-java-api:2.0.0")
implementation("org.eclipse.keyple:keyple-service-java-lib:2.3.1")
implementation("org.eclipse.keyple:keyple-service-resource-java-lib:2.1.1")
implementation("org.eclipse.keyple:keyple-distributed-network-java-lib:2.2.0")
implementation("org.eclipse.keyple:keyple-distributed-remote-java-lib:2.2.1")
implementation("org.eclipse.keyple:keyple-card-calypso-java-lib:2.3.5")
implementation("org.eclipse.keyple:keyple-service-java-lib:3.0.0")
implementation("org.eclipse.keyple:keyple-service-resource-java-lib:3.0.0")
implementation("org.eclipse.keyple:keyple-distributed-network-java-lib:2.3.0")
implementation("org.eclipse.keyple:keyple-distributed-remote-java-lib:2.3.0")
implementation("org.eclipse.keyple:keyple-card-calypso-java-lib:3.0.0")
implementation("org.eclipse.keyple:keyple-card-calypso-crypto-legacysam-java-lib:0.4.0")
implementation("org.eclipse.keyple:keyple-plugin-pcsc-java-lib:2.1.2")
implementation("org.eclipse.keyple:keyple-util-java-lib:2.3.0")
implementation("org.eclipse.keyple:keyple-util-java-lib:2.3.1")
// Quarkus
implementation(enforcedPlatform("io.quarkus:quarkus-universe-bom:1.8.1.Final"))
implementation("io.quarkus:quarkus-resteasy-jsonb")
Expand Down
2 changes: 1 addition & 1 deletion server/dashboard-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dashboard-app",
"version": "2023.05.31",
"version": "2023.12.04",
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.3",
Expand Down
Loading

0 comments on commit 107cd8b

Please sign in to comment.