Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanpierrefortune committed Dec 1, 2023
1 parent 110846b commit b05b712
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 63 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ 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 Calypso Card Library `2.3.5` -> `3.0.0`
- Keyple Util Library `2.3.0` -> `2.3.1`

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

## [2023.06.01]
### Upgraded
Expand Down
12 changes: 7 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))

// 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.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-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")
implementation("org.eclipse.keyple:keyple-card-calypso-crypto-legacysam-java-lib:0.4.0")

// Keyple reader plugins
implementation("org.eclipse.keyple:keyple-plugin-android-nfc-java-lib:2.0.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ import org.calypsonet.keyple.demo.validation.data.model.Location
import org.calypsonet.keyple.demo.validation.data.model.Status
import org.calypsonet.keyple.demo.validation.data.model.Validation
import org.calypsonet.keyple.demo.validation.data.model.mapper.ValidationMapper
import org.calypsonet.terminal.calypso.WriteAccessLevel
import org.calypsonet.terminal.calypso.card.CalypsoCard
import org.calypsonet.terminal.calypso.transaction.CardSecuritySetting
import org.calypsonet.terminal.calypso.transaction.CardTransactionManager
import org.calypsonet.terminal.reader.CardReader
import org.eclipse.keyple.card.calypso.CalypsoExtensionService
import org.eclipse.keypop.calypso.card.WriteAccessLevel
import org.eclipse.keypop.calypso.card.card.CalypsoCard
import org.eclipse.keypop.calypso.card.transaction.ChannelControl
import org.eclipse.keypop.calypso.card.transaction.SecureRegularModeTransactionManager
import org.eclipse.keypop.calypso.card.transaction.SymmetricCryptoSecuritySetting
import org.eclipse.keypop.reader.CardReader
import timber.log.Timber

class CardRepository {
Expand All @@ -46,23 +47,23 @@ class CardRepository {
validationAmount: Int,
cardReader: CardReader,
calypsoCard: CalypsoCard,
cardSecuritySettings: CardSecuritySetting,
cardSecuritySettings: SymmetricCryptoSecuritySetting,
locations: List<Location>
): CardReaderResponse {

var status: Status = Status.LOADING
var errorMessage: String? = null
val cardTransaction: CardTransactionManager?
val cardTransaction: SecureRegularModeTransactionManager?
var passValidityEndDate: LocalDate? = null
var nbTicketsLeft: Int? = null
var validation: Validation? = null

val calypsoCardExtensionProvider = CalypsoExtensionService.getInstance()
val calypsoCardApiFactory = CalypsoExtensionService.getInstance().calypsoCardApiFactory

// Create a card transaction for validation.
cardTransaction =
try {
calypsoCardExtensionProvider.createCardTransaction(
calypsoCardApiFactory.createSecureRegularModeTransactionManager(
cardReader, calypsoCard, cardSecuritySettings)
} catch (e: Exception) {
Timber.w(e)
Expand All @@ -79,7 +80,7 @@ class CardRepository {
cardTransaction
.prepareOpenSecureSession(WriteAccessLevel.DEBIT)
.prepareReadRecord(CardConstant.SFI_ENVIRONMENT_AND_HOLDER, 1)
.processCommands(false)
.processCommands(ChannelControl.KEEP_OPEN)

// Step 2 - Unpack environment structure from the binary present in the environment record.
val efEnvironmentHolder = calypsoCard.getFileBySfi(CardConstant.SFI_ENVIRONMENT_AND_HOLDER)
Expand All @@ -101,7 +102,9 @@ class CardRepository {
}

// Step 5 - Read and unpack the last event record.
cardTransaction.prepareReadRecord(CardConstant.SFI_EVENTS_LOG, 1).processCommands(false)
cardTransaction
.prepareReadRecord(CardConstant.SFI_EVENTS_LOG, 1)
.processCommands(ChannelControl.KEEP_OPEN)

val efEventLog = calypsoCard.getFileBySfi(CardConstant.SFI_EVENTS_LOG)
val eventContent = efEventLog.data.content
Expand Down Expand Up @@ -168,7 +171,7 @@ class CardRepository {
// Step 11.1 - Read and unpack the contract record for the index being iterated.
cardTransaction
.prepareReadRecord(CardConstant.SFI_CONTRACTS, record)
.processCommands(false)
.processCommands(ChannelControl.KEEP_OPEN)

val efContractParser = calypsoCard.getFileBySfi(CardConstant.SFI_CONTRACTS)
val contractContent = efContractParser.data.allRecordsContent[record]!!
Expand Down Expand Up @@ -225,7 +228,7 @@ class CardRepository {
// Contract #1 and so forth).
cardTransaction
.prepareReadCounter(CardConstant.SFI_COUNTERS, nbContractRecords)
.processCommands(false)
.processCommands(ChannelControl.KEEP_OPEN)

val efCounter = calypsoCard.getFileBySfi(CardConstant.SFI_COUNTERS)
val counterValue = efCounter.data.getContentAsCounterValue(record)
Expand Down Expand Up @@ -266,7 +269,7 @@ class CardRepository {
if (decrement > 0) {
cardTransaction
.prepareDecreaseCounter(CardConstant.SFI_COUNTERS, record, decrement)
.processCommands(false)
.processCommands(ChannelControl.KEEP_OPEN)
nbTicketsLeft = counterValue - decrement
}
}
Expand Down Expand Up @@ -320,7 +323,7 @@ class CardRepository {
val eventBytesToWrite = EventStructureParser().generate(eventToWrite)
cardTransaction
.prepareUpdateRecord(CardConstant.SFI_EVENTS_LOG, 1, eventBytesToWrite)
.processCommands(false)
.processCommands(ChannelControl.KEEP_OPEN)
} else {
Timber.i("Validation procedure result: Failed - No valid contract found")
if (errorMessage.isNullOrEmpty()) {
Expand All @@ -334,9 +337,9 @@ class CardRepository {
// Step 14 - END: Close the session
try {
if (status == Status.SUCCESS) {
cardTransaction.prepareCloseSecureSession().processCommands(true)
cardTransaction.prepareCloseSecureSession().processCommands(ChannelControl.CLOSE_AFTER)
} else {
cardTransaction.prepareCancelSecureSession().processCommands(true)
cardTransaction.prepareCancelSecureSession().processCommands(ChannelControl.CLOSE_AFTER)
}
if (status == Status.LOADING) {
status = Status.ERROR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ import org.calypsonet.keyple.plugin.flowbird.contact.FlowbirdContactReader
import org.calypsonet.keyple.plugin.flowbird.contact.SamSlot
import org.calypsonet.keyple.plugin.flowbird.contactless.FlowbirdContactlessReader
import org.calypsonet.keyple.plugin.flowbird.contactless.FlowbirdSupportContactlessProtocols
import org.calypsonet.terminal.reader.CardReader
import org.calypsonet.terminal.reader.ConfigurableCardReader
import org.calypsonet.terminal.reader.ObservableCardReader
import org.calypsonet.terminal.reader.spi.CardReaderObservationExceptionHandlerSpi
import org.eclipse.keyple.core.service.KeyplePluginException
import org.eclipse.keyple.core.service.Plugin
import org.eclipse.keyple.core.service.SmartCardServiceProvider
import org.eclipse.keyple.plugin.android.nfc.AndroidNfcPlugin
import org.eclipse.keyple.plugin.android.nfc.AndroidNfcPluginFactoryProvider
import org.eclipse.keyple.plugin.android.nfc.AndroidNfcReader
import org.eclipse.keyple.plugin.android.nfc.AndroidNfcSupportedProtocols
import org.eclipse.keypop.reader.CardReader
import org.eclipse.keypop.reader.ConfigurableCardReader
import org.eclipse.keypop.reader.ObservableCardReader
import org.eclipse.keypop.reader.spi.CardReaderObservationExceptionHandlerSpi

class ReaderRepository
@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import dagger.Module
import dagger.Provides
import org.calypsonet.keyple.demo.validation.data.ReaderRepository
import org.calypsonet.keyple.demo.validation.di.scope.AppScoped
import org.calypsonet.terminal.reader.spi.CardReaderObservationExceptionHandlerSpi
import org.eclipse.keypop.reader.spi.CardReaderObservationExceptionHandlerSpi
import timber.log.Timber

@Suppress("unused")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,37 @@ import org.calypsonet.keyple.demo.validation.data.model.CardReaderResponse
import org.calypsonet.keyple.demo.validation.data.model.Location
import org.calypsonet.keyple.demo.validation.data.model.ReaderType
import org.calypsonet.keyple.demo.validation.di.scope.AppScoped
import org.calypsonet.terminal.calypso.WriteAccessLevel
import org.calypsonet.terminal.calypso.card.CalypsoCard
import org.calypsonet.terminal.calypso.sam.CalypsoSam
import org.calypsonet.terminal.calypso.transaction.CardSecuritySetting
import org.calypsonet.terminal.reader.CardReader
import org.calypsonet.terminal.reader.ObservableCardReader
import org.calypsonet.terminal.reader.selection.CardSelectionManager
import org.calypsonet.terminal.reader.selection.CardSelectionResult
import org.calypsonet.terminal.reader.selection.ScheduledCardSelectionsResponse
import org.calypsonet.terminal.reader.spi.CardReaderObserverSpi
import org.eclipse.keyple.card.calypso.CalypsoExtensionService
import org.eclipse.keyple.card.calypso.crypto.legacysam.LegacySamExtensionService
import org.eclipse.keyple.card.calypso.crypto.legacysam.LegacySamUtil
import org.eclipse.keyple.core.service.KeyplePluginException
import org.eclipse.keyple.core.service.SmartCardServiceProvider
import org.eclipse.keyple.core.util.HexUtil
import org.eclipse.keypop.calypso.card.CalypsoCardApiFactory
import org.eclipse.keypop.calypso.card.WriteAccessLevel
import org.eclipse.keypop.calypso.card.card.CalypsoCard
import org.eclipse.keypop.calypso.card.transaction.SymmetricCryptoSecuritySetting
import org.eclipse.keypop.calypso.crypto.legacysam.sam.LegacySam
import org.eclipse.keypop.reader.CardReader
import org.eclipse.keypop.reader.ObservableCardReader
import org.eclipse.keypop.reader.ReaderApiFactory
import org.eclipse.keypop.reader.selection.CardSelectionManager
import org.eclipse.keypop.reader.selection.CardSelectionResult
import org.eclipse.keypop.reader.selection.ScheduledCardSelectionsResponse
import org.eclipse.keypop.reader.spi.CardReaderObserverSpi
import timber.log.Timber

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

private val readerApiFactory: ReaderApiFactory =
SmartCardServiceProvider.getService().readerApiFactory
private val calypsoExtensionService: CalypsoExtensionService =
CalypsoExtensionService.getInstance()
private val calypsoCardApiFactory: CalypsoCardApiFactory =
calypsoExtensionService.calypsoCardApiFactory

private lateinit var calypsoSam: CalypsoSam
private lateinit var calypsoSam: LegacySam
private lateinit var calypsoCard: CalypsoCard
private lateinit var cardSelectionManager: CardSelectionManager
var readersInitialized = false
Expand Down Expand Up @@ -135,44 +143,47 @@ class TicketingService @Inject constructor(private var readerRepository: ReaderR
smartCardService.checkCardExtension(calypsoExtensionService)

// Get a new card selection manager
cardSelectionManager = smartCardService.createCardSelectionManager()
cardSelectionManager = smartCardService.getReaderApiFactory().createCardSelectionManager()

// Prepare card selection case #1: Keyple generic
indexOfKeypleGenericCardSelection =
cardSelectionManager.prepareSelection(
calypsoExtensionService
.createCardSelection()
readerApiFactory
.createIsoCardSelector()
.filterByDfName(CardConstant.AID_KEYPLE_GENERIC)
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()))
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()),
calypsoCardApiFactory.createCalypsoCardSelectionExtension())

// Prepare card selection case #2: CD LIGHT/GTML
indexOfCdLightGtmlCardSelection =
cardSelectionManager.prepareSelection(
calypsoExtensionService
.createCardSelection()
readerApiFactory
.createIsoCardSelector()
.filterByDfName(CardConstant.AID_CD_LIGHT_GTML)
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()))
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()),
calypsoCardApiFactory.createCalypsoCardSelectionExtension())

// Prepare card selection case #3: CALYPSO LIGHT
indexOfCalypsoLightCardSelection =
cardSelectionManager.prepareSelection(
calypsoExtensionService
.createCardSelection()
readerApiFactory
.createIsoCardSelector()
.filterByDfName(CardConstant.AID_CALYPSO_LIGHT)
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()))
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()),
calypsoCardApiFactory.createCalypsoCardSelectionExtension())

// Prepare card selection case #4: Navigo IDF
indexOfNavigoIdfCardSelection =
cardSelectionManager.prepareSelection(
calypsoExtensionService
.createCardSelection()
readerApiFactory
.createIsoCardSelector()
.filterByDfName(CardConstant.AID_NORMALIZED_IDF)
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()))
.filterByCardProtocol(readerRepository.getCardReaderProtocolLogicalName()),
calypsoCardApiFactory.createCalypsoCardSelectionExtension())

// Schedule the execution of the prepared card selection scenario as soon as a card is presented
cardSelectionManager.scheduleCardSelectionScenario(
readerRepository.getCardReader() as ObservableCardReader,
ObservableCardReader.DetectionMode.REPEATING,
ObservableCardReader.NotificationMode.ALWAYS)
}

Expand Down Expand Up @@ -218,10 +229,13 @@ class TicketingService @Inject constructor(private var readerRepository: ReaderR
validationDateTime = LocalDateTime.now())
}

private fun getSecuritySettings(): CardSecuritySetting? {
return calypsoExtensionService
.createCardSecuritySetting()
.setControlSamResource(readerRepository.getSamReader(), calypsoSam)
private fun getSecuritySettings(): SymmetricCryptoSecuritySetting? {
return calypsoCardApiFactory
.createSymmetricCryptoSecuritySetting(
LegacySamExtensionService.getInstance()
.legacySamApiFactory
.createSymmetricCryptoCardTransactionManagerFactory(
readerRepository.getSamReader(), calypsoSam))
.assignDefaultKif(
WriteAccessLevel.PERSONALIZATION, CardConstant.DEFAULT_KIF_PERSONALIZATION)
.assignDefaultKif(WriteAccessLevel.LOAD, CardConstant.DEFAULT_KIF_LOAD)
Expand All @@ -235,19 +249,24 @@ class TicketingService @Inject constructor(private var readerRepository: ReaderR
val smartCardService = SmartCardServiceProvider.getService()

// Create a SAM selection manager.
val samSelectionManager: CardSelectionManager = smartCardService.createCardSelectionManager()
val samSelectionManager: CardSelectionManager =
smartCardService.getReaderApiFactory().createCardSelectionManager()

// Create a SAM selection using the Calypso card extension.
samSelectionManager.prepareSelection(
calypsoExtensionService
.createSamSelection()
.filterByProductType(CalypsoSam.ProductType.SAM_C1))
readerApiFactory
.createBasicCardSelector()
.filterByCardProtocol(
LegacySamUtil.buildPowerOnDataFilter(LegacySam.ProductType.SAM_C1, null)),
LegacySamExtensionService.getInstance()
.legacySamApiFactory
.createLegacySamSelectionExtension())
try {
// SAM communication: run the selection scenario.
val samSelectionResult = samSelectionManager.processCardSelectionScenario(samReader)

// Get the Calypso SAM SmartCard resulting of the selection.
calypsoSam = samSelectionResult.activeSmartCard!! as CalypsoSam
calypsoSam = samSelectionResult.activeSmartCard!! as LegacySam
return true
} catch (e: Exception) {
Timber.e(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import org.calypsonet.keyple.demo.validation.data.model.CardReaderResponse
import org.calypsonet.keyple.demo.validation.data.model.ReaderType
import org.calypsonet.keyple.demo.validation.data.model.Status
import org.calypsonet.keyple.demo.validation.di.scope.ActivityScoped
import org.calypsonet.terminal.reader.CardReaderEvent
import org.calypsonet.terminal.reader.spi.CardReaderObserverSpi
import org.eclipse.keypop.reader.CardReaderEvent
import org.eclipse.keypop.reader.spi.CardReaderObserverSpi
import timber.log.Timber

@ActivityScoped
Expand Down

0 comments on commit b05b712

Please sign in to comment.