Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: switch to Keypop API #20

Merged
merged 9 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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