diff --git a/CHANGELOG.md b/CHANGELOG.md index 19fecf5..137ad45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `TaskCanceledException`: added constructor `(String message, Throwable cause)` for consistency + with the other exceptions of the package. ### Changed - Migrated the CI pipeline from Jenkins to GitHub Actions. +- `ReaderSpi`: clarified the contracts of `openPhysicalChannel()`, `closePhysicalChannel()` and + `checkCardPresence()` regarding physical channel state management (see Javadoc for details). +- `ReaderSpi.getPowerOnData()`: documented lifecycle (meaningful only after a successful + `openPhysicalChannel()`) and allowed empty return value. +- `CardRemovalWaiterNonBlockingSpi`: the service now uses `checkCardPresence()` instead of + `transmitApdu()` for card removal polling. This change is conditioned by the plugin API version: + the new behaviour applies only when the plugin declares API version `2.4` or higher. +- Various Javadoc corrections and minor clarifications. +### Fixed +- `CardRemovalWaiterAsynchronousApi`: corrected `@link` pointing to a deprecated SPI. ## [2.3.2] - 2025-04-18 ### Changed diff --git a/gradle.properties b/gradle.properties index d7a3340..64b9946 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group = org.eclipse.keyple title = Keyple Plugin Java API description = API dedicated to plugins development -version = 2.3.3-SNAPSHOT +version = 2.4.0-SNAPSHOT # Java Configuration javaSourceLevel = 1.8 diff --git a/src/main/java/org/eclipse/keyple/core/plugin/CardRemovalWaiterAsynchronousApi.java b/src/main/java/org/eclipse/keyple/core/plugin/CardRemovalWaiterAsynchronousApi.java index 299ea43..ff1f9bb 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/CardRemovalWaiterAsynchronousApi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/CardRemovalWaiterAsynchronousApi.java @@ -13,7 +13,7 @@ /** * API associated to a {@link - * org.eclipse.keyple.core.plugin.spi.reader.observable.state.removal.WaitForCardRemovalAutonomousSpi} + * org.eclipse.keyple.core.plugin.spi.reader.observable.state.removal.CardRemovalWaiterAsynchronousSpi} * * @since 2.2.0 */ diff --git a/src/main/java/org/eclipse/keyple/core/plugin/PluginApiProperties.java b/src/main/java/org/eclipse/keyple/core/plugin/PluginApiProperties.java index 27bd0b7..ca46c08 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/PluginApiProperties.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/PluginApiProperties.java @@ -22,7 +22,7 @@ public final class PluginApiProperties { * * @since 2.0.0 */ - public static final String VERSION = "2.3"; + public static final String VERSION = "2.4"; /** Private constructor */ private PluginApiProperties() {} diff --git a/src/main/java/org/eclipse/keyple/core/plugin/TaskCanceledException.java b/src/main/java/org/eclipse/keyple/core/plugin/TaskCanceledException.java index c18c315..151d21a 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/TaskCanceledException.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/TaskCanceledException.java @@ -26,4 +26,13 @@ public class TaskCanceledException extends Exception { public TaskCanceledException(String message) { super(message); } + + /** + * @param message the message to identify the exception context + * @param cause the cause + * @since 2.3.3 + */ + public TaskCanceledException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/AutonomousObservablePluginSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/AutonomousObservablePluginSpi.java index f47516b..6d4ba08 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/AutonomousObservablePluginSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/AutonomousObservablePluginSpi.java @@ -26,6 +26,10 @@ public interface AutonomousObservablePluginSpi extends PluginSpi { /** * Connects the associated Keyple Core {@link AutonomousObservablePluginApi} API. * + *

This method is no longer called by the framework since version 2.2.0. Implementations + * migrating to {@link #setCallback(AutonomousObservablePluginApi)} may provide an empty body for + * this method. + * * @param autonomousObservablePluginApi The API to connect. * @since 2.0.0 * @deprecated Use {@link #setCallback(AutonomousObservablePluginApi)} instead. diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/ReaderSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/ReaderSpi.java index 321fb82..290a80a 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/ReaderSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/ReaderSpi.java @@ -15,8 +15,10 @@ import org.eclipse.keyple.core.plugin.ReaderIOException; /** - * Reader able to communicate with smart cards whose purpose is to remain present in the reader (for - * example a SAM reader). + * Reader able to communicate with smart cards. + * + *

This is the base interface for all reader types, including readers with permanently present + * cards (e.g. SAM readers) and observable readers detecting card insertion and removal. * *

The target devices must comply with the following Calypsonet Terminal requirements: * @@ -40,27 +42,36 @@ public interface ReaderSpi { String getName(); /** - * Validates the opening of the physical channel. Performs the actual opening if this has not been - * done by the {@link #checkCardPresence()} method. In all cases, memorizes the new state for the - * operation of the {@link #isPhysicalChannelOpen()} method. After executing this method, the - * reader is able to send APDUs to the card. + * Ensures that the physical channel is open and that the card is ready to receive APDU commands. + * + *

On successful return: + * + *

+ * + *

If {@link #checkCardPresence()} has already opened the physical channel (e.g. for + * contactless readers performing anti-collision during presence detection), this method is a + * no-op. * * @throws ReaderIOException If the communication with the reader has failed. - * @throws CardIOException If the communication with the card has failed. + * @throws CardIOException If no card is present or if the communication with the card has failed. * @since 2.0.0 */ void openPhysicalChannel() throws ReaderIOException, CardIOException; /** - * Tells the reader that card processing is complete and that the next step is to remove the card - * from the reader. + * Closes the physical channel. * - *

If the reader has the ability to sense the presence of the card without communicating with - * it, then this method must proceed to the actual closing of the physical channel (e.g. power - * down in the case of a contact reader). Otherwise, this method is limited to changing the - * logical opening state of the physical channel and letting the removal procedure do the closing. + *

* - * @throws ReaderIOException If the communication with the reader has failed. + * @throws ReaderIOException If the card is present and the close operation fails (reader + * problem). * @since 2.0.0 */ void closePhysicalChannel() throws ReaderIOException; @@ -69,20 +80,26 @@ public interface ReaderSpi { * Tells if the physical channel is open or not. * * @return True is the physical channel is open, false if not. + * @since 2.0.0 */ boolean isPhysicalChannelOpen(); /** * Verifies the presence of a card. * - *

Depending on the reader's capabilities, this method will either use a card presence - * indicator without necessarily communicating with the card (for example, in the case of a - * contact reader equipped with a physical insertion detector using a switch), or will communicate - * with the card (in the case of contactless hunting). In the latter case, we can consider that - * the physical channel has been opened (and therefore no longer needs to be opened in the {@link - * #openPhysicalChannel()} method). + *

The behavior of this method depends on the state of the physical channel: + * + *

* - * @return True if a card is present + * @return {@code true} if a card is present, {@code false} otherwise. * @throws ReaderIOException If the communication with the reader has failed. * @since 2.0.0 */ @@ -92,6 +109,7 @@ public interface ReaderSpi { * Gets the power-on data. * *

The power-on data is defined as the data retrieved by the reader when the card is inserted. + * This method is only meaningful after {@link #openPhysicalChannel()} has returned successfully. * *

In the case of a contact reader, this is the Answer To Reset data (ATR) defined by ISO7816. * @@ -101,9 +119,11 @@ public interface ReaderSpi { * the ISO14443 protocol (ATQA, ATQB, ATS, SAK, etc). * *

These data being variable from one reader to another, they are defined here in string format - * which can be either a hexadecimal string or any other relevant information. + * which can be either a hexadecimal string or any other relevant information. An empty string may + * be returned if no power-on data is available (e.g. for a reader with a permanently powered + * card). * - * @return A not empty String. + * @return A non-null String, possibly empty. * @since 2.0.0 */ String getPowerOnData(); @@ -111,9 +131,11 @@ public interface ReaderSpi { /** * Transmits an APDU and returns its response. * - *

Caution: the implementation must handle the case where the card response is 61xy and - * execute the appropriate get response command (Calypsonet Terminal requirement - * "RL-SW-61XX.1"). + *

Caution: the implementation must handle the ISO 7816-3 T=0 protocol specificity at the + * transport level: status word {@code 61xx} (response bytes available) requires automatically + * issuing a {@code GET RESPONSE} command (Calypsonet Terminal requirement "RL-SW-61XX.1"). This + * is handled at the SPI level because its behavior depends on the underlying reader + * implementation (T=0, T=1, PC/SC). * * @param apduIn The data to be sent to the card. * @return A buffer of at least 2 bytes. diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/ObservableReaderSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/ObservableReaderSpi.java index 2f9d5ce..3620560 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/ObservableReaderSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/ObservableReaderSpi.java @@ -13,13 +13,14 @@ import org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi; import org.eclipse.keyple.core.plugin.spi.reader.observable.state.insertion.*; +import org.eclipse.keyple.core.plugin.spi.reader.observable.state.processing.*; import org.eclipse.keyple.core.plugin.spi.reader.observable.state.removal.*; /** * Reader able to detect the insertion and removal of cards. * *

In addition, an observable reader must also define its observation capabilities for the card - * insertion and removal steps. + * insertion, removal, and optionally processing steps. * *

For the card insertion state, it must implement one of the following interfaces: * @@ -37,6 +38,18 @@ *

  • {@link CardRemovalWaiterNonBlockingSpi} * * + *

    For the card processing state (monitoring card presence between APDU commands), it may + * optionally implement: + * + *

    + * + *

    Readers implementing {@link CardRemovalWaiterAsynchronousSpi} (e.g. Android NFC readers) do + * not need to implement {@link CardPresenceMonitorBlockingSpi}: the asynchronous removal callback + * covers all phases, including processing. + * * @since 2.0.0 */ public interface ObservableReaderSpi extends ReaderSpi { diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/processing/CardPresenceMonitorBlockingSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/processing/CardPresenceMonitorBlockingSpi.java index a6151d0..fdff8b3 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/processing/CardPresenceMonitorBlockingSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/processing/CardPresenceMonitorBlockingSpi.java @@ -24,12 +24,12 @@ public interface CardPresenceMonitorBlockingSpi { /** - * Monitors the card presence indefinitely (the method is blocking as long as the card is - * present). + * Monitors the card presence indefinitely (the method is blocking as long as the card is present) + * and returns normally when the card is removed. * *

    This monitoring can be cancelled for an internal (for example timeout) or external reason - * (for example invocation of {@link #stopCardPresenceMonitoringDuringProcessing()}), in this case - * an exception is raised. + * (for example invocation of {@link #stopCardPresenceMonitoringDuringProcessing()}), in which + * case an exception is raised. * * @throws ReaderIOException If the communication with the reader has failed. * @throws TaskCanceledException If the task has been canceled and is no longer active. diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterBlockingSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterBlockingSpi.java index e1b3803..1982520 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterBlockingSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterBlockingSpi.java @@ -32,7 +32,7 @@ public interface CardRemovalWaiterBlockingSpi { *

    This wait can be cancelled for an internal (for example timeout) or external reason (for * example invocation of {@link #stopWaitForCardRemoval()}), in this case an exception is raised. * - * @throws ReaderIOException If the communication with the reader + * @throws ReaderIOException If the communication with the reader has failed. * @throws TaskCanceledException If the task has been canceled and is no longer active * @since 2.2.0 */ diff --git a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterNonBlockingSpi.java b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterNonBlockingSpi.java index baaeddd..d568511 100644 --- a/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterNonBlockingSpi.java +++ b/src/main/java/org/eclipse/keyple/core/plugin/spi/reader/observable/state/removal/CardRemovalWaiterNonBlockingSpi.java @@ -12,20 +12,20 @@ package org.eclipse.keyple.core.plugin.spi.reader.observable.state.removal; /** - * This SPI is specifically designed for plugins that don't handle card removal autonomously but - * requires the sending of an APDU to detect the card removal. + * This SPI is specifically designed for plugins that don't handle card removal autonomously. * *

    When a plugin implements this SPI, the {@link - * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#transmitApdu(byte[])} method will be called + * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#checkCardPresence()} method will be called * periodically by the service when a card removal is expected. The card is considered removed when - * the transmission fails. + * {@code checkCardPresence()} returns {@code false} (which also triggers the internal closure of + * the physical channel). * - *

    The value returned by the {@link #getCardRemovalMonitoringSleepDuration()} will be used as an + *

    The value returned by {@link #getCardRemovalMonitoringSleepDuration()} will be used as an * argument to {@link Thread#sleep(long)} between two calls to {@link - * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#transmitApdu}. + * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#checkCardPresence()}. * *

    A typical example of readers conforming to this mode of operation are terminals embedding a - * slave RF communication module without card presence feature. + * slave RF communication module without autonomous card presence detection. * * @since 2.2.0 */ @@ -33,7 +33,7 @@ public interface CardRemovalWaiterNonBlockingSpi { /** * Provides the value of the sleep duration (in milliseconds) inserted between two calls to {@link - * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#transmitApdu}. + * org.eclipse.keyple.core.plugin.spi.reader.ReaderSpi#checkCardPresence()}. * * @return A positive value (0 is allowed). * @since 2.2.0 diff --git a/src/main/uml/api_class_diagram.puml b/src/main/uml/api_class_diagram.puml index 7bc2abf..0304cea 100644 --- a/src/main/uml/api_class_diagram.puml +++ b/src/main/uml/api_class_diagram.puml @@ -1,6 +1,6 @@ @startuml title - Keyple - keyple-plugin-java-api - 2.3.+ (2024-03-26) + Keyple - keyple-plugin-java-api - 2.4.+ (2026-03-31) end title ' == THEME == @@ -88,6 +88,8 @@ package "org.eclipse.keyple.core.plugin" as api { } +class "<>\n**final** TaskCanceledException" as TaskCanceledException <> { +TaskCanceledException (String message) + +TaskCanceledException (String message, + \tThrowable cause) } package spi { together { @@ -169,9 +171,9 @@ package "org.eclipse.keyple.core.plugin" as api { } +interface "DontWaitForCardRemovalDuringProcessingSpi" as DontWaitForCardRemovalDuringProcessingSpi <> { } - +interface "CardPresenceMonitorBlockingSpi" as CardPresenceMonitorBlockingSpi <> { - +void monitorCardPresenceDuringProcessing () - +void stopCardPresenceMonitoringDuringProcessing () + +interface "CardPresenceMonitorBlockingSpi" as CardPresenceMonitorBlockingSpi <> { + +void monitorCardPresenceDuringProcessing () + +void stopCardPresenceMonitoringDuringProcessing () } } package insertion { diff --git a/src/main/uml/api_class_diagram.svg b/src/main/uml/api_class_diagram.svg index 368e623..a627d41 100644 --- a/src/main/uml/api_class_diagram.svg +++ b/src/main/uml/api_class_diagram.svg @@ -1 +1 @@ -Keyple - keyple-plugin-java-api - 2.3.+ (2024-03-26)Keyple - keyple-plugin-java-api - 2.3.+ (2024-03-26)org.eclipse.keyple.core.pluginspireaderobservablestateprocessinginsertionremovalfinalPluginApiPropertiesfinalString VERSIONAutonomousObservablePluginApivoid onReaderConnected (Set<ReaderSpi> readers)void onReaderDisconnected (Set<String> readerNames)WaitForCardInsertionAutonomousReaderApivoid onCardInserted ()WaitForCardRemovalAutonomousReaderApivoid onCardRemoved ()CardInsertionWaiterAsynchronousApivoid onCardInserted ()CardRemovalWaiterAsynchronousApivoid onCardRemoved ()«Exception»finalPluginIOExceptionPluginIOException (String message)PluginIOException (String message,Throwable cause)«Exception»finalReaderIOExceptionReaderIOException (String message)ReaderIOException (String message,Throwable cause)«Exception»finalCardIOExceptionCardIOException (String message)CardIOException (String message,Throwable cause)«Exception»finalTaskCanceledExceptionTaskCanceledException (String message)PoolPluginFactorySpiString getPluginApiVersion ()String getCommonApiVersion ()String getPoolPluginName ()PoolPluginSpi getPoolPlugin ()PluginFactorySpiString getPluginApiVersion ()String getCommonApiVersion ()String getPluginName ()PluginSpi getPlugin ()PoolPluginSpiString getName ()SortedSet<String> getReaderGroupReferences ()PoolReaderSpi allocateReader (String readerGroupReference)void releaseReader (ReaderSpi readerSpi)void onUnregister ()PluginSpiString getName ()Set<ReaderSpi> searchAvailableReaders ()void onUnregister ()ObservablePluginSpiint getMonitoringCycleDuration ()Set<String> searchAvailableReaderNames ()ReaderSpi searchReader (String readerName)AutonomousObservablePluginSpivoid connect (AutonomousObservablePluginApiautonomousObservablePluginApi)void setCallback (AutonomousObservablePluginApi callback)ReaderSpiString getName () void openPhysicalChannel ()void closePhysicalChannel ()boolean isPhysicalChannelOpen () boolean checkCardPresence ()String getPowerOnData ()byte[] transmitApdu (byte[] apduIn)boolean isContactless ()void onUnregister ()PoolReaderSpiObject getSelectedSmartCard ()ConfigurableReaderSpiboolean isProtocolSupported (String readerProtocol)void activateProtocol (String readerProtocol)void deactivateProtocol (String readerProtocol)boolean isCurrentProtocol (String readerProtocol)AutonomousSelectionReaderSpibyte[] openChannelForAid (byte[] dfName, byte isoControlMask)void closeLogicalChannel ()ObservableReaderSpivoid onStartDetection ()void onStopDetection ()WaitForCardRemovalBlockingDuringProcessingSpivoid waitForCardRemovalDuringProcessing ()void stopWaitForCardRemovalDuringProcessing ()DontWaitForCardRemovalDuringProcessingSpiCardPresenceMonitorBlockingSpivoid monitorCardPresenceDuringProcessing ()void stopCardPresenceMonitoringDuringProcessing ()WaitForCardInsertionBlockingSpivoid waitForCardInsertion ()void stopWaitForCardInsertion ()CardInsertionWaiterBlockingSpivoid waitForCardInsertion ()void stopWaitForCardInsertion ()WaitForCardInsertionNonBlockingSpiCardInsertionWaiterNonBlockingSpiint getCardInsertionMonitoringSleepDuration ()WaitForCardInsertionAutonomousSpivoid connect (WaitForCardInsertionAutonomousReaderApiwaitForCardInsertionAutonomousReaderApi)CardInsertionWaiterAsynchronousSpivoid setCallback (CardInsertionWaiterAsynchronousApi callback)WaitForCardRemovalBlockingSpivoid waitForCardRemoval ()void stopWaitForCardRemoval ()CardRemovalWaiterBlockingSpivoid waitForCardRemoval ()void stopWaitForCardRemoval ()WaitForCardRemovalNonBlockingSpiCardRemovalWaiterNonBlockingSpiint getCardRemovalMonitoringSleepDuration ()WaitForCardRemovalAutonomousSpivoid connect (WaitForCardRemovalAutonomousReaderApiwaitForCardRemovalAutonomousReaderApi)CardRemovalWaiterAsynchronousSpivoid setCallback (CardRemovalWaiterAsynchronousApi callback)provideAPI versionprovideprovideprovideAPI versionprovideprovideuseuseuseuseuse \ No newline at end of file +Keyple - keyple-plugin-java-api - 2.4.+ (2026-03-31)Keyple - keyple-plugin-java-api - 2.4.+ (2026-03-31)org.eclipse.keyple.core.pluginspireaderobservablestateprocessinginsertionremovalfinalPluginApiPropertiesfinalString VERSIONAutonomousObservablePluginApivoid onReaderConnected (Set<ReaderSpi> readers)void onReaderDisconnected (Set<String> readerNames)WaitForCardInsertionAutonomousReaderApivoid onCardInserted ()WaitForCardRemovalAutonomousReaderApivoid onCardRemoved ()CardInsertionWaiterAsynchronousApivoid onCardInserted ()CardRemovalWaiterAsynchronousApivoid onCardRemoved ()«Exception»finalPluginIOExceptionPluginIOException (String message)PluginIOException (String message,Throwable cause)«Exception»finalReaderIOExceptionReaderIOException (String message)ReaderIOException (String message,Throwable cause)«Exception»finalCardIOExceptionCardIOException (String message)CardIOException (String message,Throwable cause)«Exception»finalTaskCanceledExceptionTaskCanceledException (String message)TaskCanceledException (String message,   Throwable cause)PoolPluginFactorySpiString getPluginApiVersion ()String getCommonApiVersion ()String getPoolPluginName ()PoolPluginSpi getPoolPlugin ()PluginFactorySpiString getPluginApiVersion ()String getCommonApiVersion ()String getPluginName ()PluginSpi getPlugin ()PoolPluginSpiString getName ()SortedSet<String> getReaderGroupReferences ()PoolReaderSpi allocateReader (String readerGroupReference)void releaseReader (ReaderSpi readerSpi)void onUnregister ()PluginSpiString getName ()Set<ReaderSpi> searchAvailableReaders ()void onUnregister ()ObservablePluginSpiint getMonitoringCycleDuration ()Set<String> searchAvailableReaderNames ()ReaderSpi searchReader (String readerName)AutonomousObservablePluginSpivoid connect (AutonomousObservablePluginApiautonomousObservablePluginApi)void setCallback (AutonomousObservablePluginApi callback)ReaderSpiString getName () void openPhysicalChannel ()void closePhysicalChannel ()boolean isPhysicalChannelOpen () boolean checkCardPresence ()String getPowerOnData ()byte[] transmitApdu (byte[] apduIn)boolean isContactless ()void onUnregister ()PoolReaderSpiObject getSelectedSmartCard ()ConfigurableReaderSpiboolean isProtocolSupported (String readerProtocol)void activateProtocol (String readerProtocol)void deactivateProtocol (String readerProtocol)boolean isCurrentProtocol (String readerProtocol)AutonomousSelectionReaderSpibyte[] openChannelForAid (byte[] dfName, byte isoControlMask)void closeLogicalChannel ()ObservableReaderSpivoid onStartDetection ()void onStopDetection ()WaitForCardRemovalBlockingDuringProcessingSpivoid waitForCardRemovalDuringProcessing ()void stopWaitForCardRemovalDuringProcessing ()DontWaitForCardRemovalDuringProcessingSpiCardPresenceMonitorBlockingSpivoid monitorCardPresenceDuringProcessing ()void stopCardPresenceMonitoringDuringProcessing ()WaitForCardInsertionBlockingSpivoid waitForCardInsertion ()void stopWaitForCardInsertion ()CardInsertionWaiterBlockingSpivoid waitForCardInsertion ()void stopWaitForCardInsertion ()WaitForCardInsertionNonBlockingSpiCardInsertionWaiterNonBlockingSpiint getCardInsertionMonitoringSleepDuration ()WaitForCardInsertionAutonomousSpivoid connect (WaitForCardInsertionAutonomousReaderApiwaitForCardInsertionAutonomousReaderApi)CardInsertionWaiterAsynchronousSpivoid setCallback (CardInsertionWaiterAsynchronousApi callback)WaitForCardRemovalBlockingSpivoid waitForCardRemoval ()void stopWaitForCardRemoval ()CardRemovalWaiterBlockingSpivoid waitForCardRemoval ()void stopWaitForCardRemoval ()WaitForCardRemovalNonBlockingSpiCardRemovalWaiterNonBlockingSpiint getCardRemovalMonitoringSleepDuration ()WaitForCardRemovalAutonomousSpivoid connect (WaitForCardRemovalAutonomousReaderApiwaitForCardRemovalAutonomousReaderApi)CardRemovalWaiterAsynchronousSpivoid setCallback (CardRemovalWaiterAsynchronousApi callback)provideAPI versionprovideprovideprovideAPI versionprovideprovideuseuseuseuseuse \ No newline at end of file