Skip to content

Active card removal monitoring issue when stopped #71

@amessara-billettiqueservices

Description

Hello team,

We have a specific use case, in which, when a type of card is detected we stop everything and let another application handle the card.

This revealed an issue in Keyple as we still keep interacting with the reader after a stopCardDetection() has been called.

finalizeCardProcessing() is called, switching the statemachine to WAIT_FOR_CARD_REMOVAL and starting an active card presence monitoring.

03-07-24 18:28:34.317 	 1 	 DEBUG 	 SmartcardNfcReader 	 Finishing handling the card
03-07-24 18:28:34.317 	 1 	 DEBUG 	 org.eclipse.keyple.core.service.ObservableLocalReaderAdapter 	 Reader 'BluebirdReader' of plugin 'BluebirdPlugin' starts the removal sequence of the card.
03-07-24 18:28:34.317 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.WaitForCardProcessingStateAdapter 	 [BluebirdReader] onInternalEvent => Event CARD_PROCESSED received in currentState WAIT_FOR_CARD_PROCESSING
03-07-24 18:28:34.318 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.ObservableReaderStateServiceAdapter 	 [BluebirdReader] Switch currentState from WAIT_FOR_CARD_PROCESSING to WAIT_FOR_CARD_REMOVAL
03-07-24 18:28:34.318 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onDeactivate => WAIT_FOR_CARD_PROCESSING
03-07-24 18:28:34.319 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onActivate => WAIT_FOR_CARD_REMOVAL

stopCardDetection() is called to stop all operations on the card and reader and let the other application work

03-07-24 18:28:34.320 	 1 	 DEBUG 	 SmartcardNfcReader 	 stopCardDetection()
03-07-24 18:28:34.321 	 1280 	 DEBUG 	 org.eclipse.keyple.core.service.CardRemovalActiveMonitoringJobAdapter 	 [BluebirdReader] Polling from isCardPresentPing
03-07-24 18:28:34.321 	 1 	 DEBUG 	 org.eclipse.keyple.core.service.ObservableLocalReaderAdapter 	 Reader 'BluebirdReader' of plugin 'BluebirdPlugin' stops the card detection.
03-07-24 18:28:34.322 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.ObservableLocalReaderAdapter 	 [BluebirdReader] Ping card
03-07-24 18:28:34.322 	 1 	 DEBUG 	 BluebirdReaderAdapter 	 onStopDetection()
03-07-24 18:28:34.322 	 1280 	 DEBUG 	 BluebirdReaderAdapter 	 transmitApdu() apduIn=00C0000000
03-07-24 18:28:34.324 	 1 	 DEBUG 	 BluebirdReaderAdapter 	 extNfcReader.stopScan = 0
03-07-24 18:28:34.326 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.WaitForCardRemovalStateAdapter 	 [BluebirdReader] onInternalEvent => Event STOP_DETECT received in currentState WAIT_FOR_CARD_REMOVAL
03-07-24 18:28:34.327 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.LocalReaderAdapter 	 [BluebirdReader] closeLogicalChannel => Closing of the logical channel.
03-07-24 18:28:34.327 	 1 	 DEBUG 	 BluebirdReaderAdapter 	 closePhysicalChannel()
03-07-24 18:28:34.327 	 1 	 DEBUG 	 org.eclipse.keyple.core.service.ObservableLocalReaderAdapter 	 Reader 'BluebirdReader' notifies the reader event 'CARD_REMOVED' to 1 observer(s).

We see at the same time the state machine being "stopped" (WAIT_FOR_START_DETECTION) and the removal monitoring job requested to stop. (It's a simple request and not an interruption. Ongoing jobs are allowed to finish)

03-07-24 18:28:34.379 	 1280 	 DEBUG 	 BluebirdReaderAdapter 	 transmitApdu() result=6D00
03-07-24 18:28:34.381 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.CardRemovalActiveMonitoringJobAdapter 	 [BluebirdReader] Polling retries : 1
03-07-24 18:28:34.556 	 1 	 DEBUG 	 PeripheralObserver 	 onChange(true,null
03-07-24 18:28:34.557 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.ObservableReaderStateServiceAdapter 	 [BluebirdReader] Switch currentState from WAIT_FOR_CARD_REMOVAL to WAIT_FOR_START_DETECTION
03-07-24 18:28:34.557 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onDeactivate => WAIT_FOR_CARD_REMOVAL
03-07-24 18:28:34.557 	 1 	 DEBUG 	 org.eclipse.keyple.core.service.CardRemovalActiveMonitoringJobAdapter 	 [BluebirdReader] Stop Polling 
03-07-24 18:28:34.558 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onDeactivate => cancel monitoring job CardRemovalActiveMonitoringJobAdapter by thread interruption true
03-07-24 18:28:34.558 	 1 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onActivate => WAIT_FOR_START_DETECTION
03-07-24 18:28:34.558 	 1 	 DEBUG 	 SmartcardNfcReader 	 remove observer
03-07-24 18:28:34.558 	 1 	 DEBUG 	 org.eclipse.keyple.core.service.ObservationManagerAdapter 	 Reader 'BluebirdReader' of plugin 'BluebirdPlugin' is removing the observer 'BluebirdNfcReader'.

200ms later the card removal monitoring job awakens from a Thread.sleep, understands that a stop has been requested BUT tries to close the physical channel and send a CARD_REMOVED event.

03-07-24 18:28:34.582 	 1280 	 DEBUG 	 org.eclipse.keyple.core.service.CardRemovalActiveMonitoringJobAdapter 	 [BluebirdReader] Polling loop has been stopped
03-07-24 18:28:34.583 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.WaitForCardRemovalStateAdapter 	 [BluebirdReader] onInternalEvent => Event CARD_REMOVED received in currentState WAIT_FOR_CARD_REMOVAL
03-07-24 18:28:34.583 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.LocalReaderAdapter 	 [BluebirdReader] closeLogicalChannel => Closing of the logical channel.
03-07-24 18:28:34.583 	 1280 	 DEBUG 	 BluebirdReaderAdapter 	 closePhysicalChannel()
03-07-24 18:28:34.585 	 1280 	 DEBUG 	 org.eclipse.keyple.core.service.ObservableLocalReaderAdapter 	 Reader 'BluebirdReader' notifies the reader event 'CARD_REMOVED' to 0 observer(s).
03-07-24 18:28:34.591 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.ObservableReaderStateServiceAdapter 	 [BluebirdReader] Switch currentState from WAIT_FOR_START_DETECTION to WAIT_FOR_CARD_INSERTION
03-07-24 18:28:34.591 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onDeactivate => WAIT_FOR_START_DETECTION
03-07-24 18:28:34.592 	 1280 	 VERBOSE 	 org.eclipse.keyple.core.service.AbstractObservableStateAdapter 	 [BluebirdReader] onActivate => WAIT_FOR_CARD_INSERTION

This behavior is very problematic as we have already stopped everything and the reader is currently used by another application.

I believe that the issue is in this finally block and simply checking if the loop has been stopped before should fix it.

} finally {
monitoringState.onEvent(ObservableLocalReaderAdapter.InternalEvent.CARD_REMOVED);
}

} finally {
          if(!loop.get()) {
            monitoringState.onEvent(ObservableLocalReaderAdapter.InternalEvent.CARD_REMOVED);
          }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions