Grabba Driver for Android
Unified driver for Grabba devices on the Android operating system
SmartcardAPI Class Reference

Description

Provides access to Grabba contact smart card reader functionality, such as exchanging APDUs.

Callbacks to user-provided code may be triggered in response to relevant events, e.g. insertion of a smart card. Refer to the SmartcardListener class for the details of these callbacks and how to enable them.

Most API functions require an interface ID, so as to support Grabba devices which contain more than one contact smart card interface - e.g. a Grabba device may contain one full-sized card slot and one Secure Access Module (SAM) interface. Users of single-interface devices should use the value returned by defaultInterface() to populate this parameter; refer to that function and to SmartcardInterfaceID for additional details.

Each interface may contain a smart card or not; the cardPresent() method queries this. Only full-sized card slots allow for insertion and removal when the Grabba device is powered; if this occurs, any pending actions on that interface are cancelled, and notifications are provided via any active SmartcardListener objects.

Communication with an inserted card usually involves four steps:

Cards which boot up in "specific mode" (as defined in ISO/IEC 7816-3), or which do not indicate support for non-default parameters or protocols, will not accept PPS exchanges. Consequently, only three steps are needed for them - power up, APDU exchange and power down. The SmartcardListener.PPS_Event callback (for auto PPS exchange) or readyForPPS() method (for manual PPS exchange) may be used to differentiate between cards which support PPS exchange and those which do not.

Grabba devices do not support concurrent smart card operations, even if the operations target different interfaces. Consequently, for correct operation it is necessary to wait for each power-up, power-down or APDU-exchange operation to be completed (with notifications supplied via SmartcardListener objects for asynchronous operations) prior to launching another such operation. Failure to do so will result in DEVICE_BUSY errors being returned to the calling code.

Calls to this class will not succeed until a connection to a Grabba device has been established. Refer to the CoreAPI class for details of how to establish or query this connection.

Thread safety: Everything in this class is fully thread-safe.

Note
This class has no non-static methods or data; consequently, object creation is disabled.

Static Public Member Functions

static boolean cardPresent (@NonNull SmartcardInterfaceID iface)
 Query whether there is currently a contact smart card present in a given interface on a connected Grabba device. More...
 
static SmartcardInterfaceID defaultInterface ()
 Obtain the ID of the default interface for a connected Grabba device. More...
 
static void exchangeAPDU (@NonNull SmartcardInterfaceID iface, @NonNull CommandAPDU command, @NonNull ErrorCode error)
 Asynchronously exchange an APDU (Application Protocol Data Unit) with an inserted smart card in a given interface on a connected Grabba device. More...
 
static void exchangePPS (@NonNull SmartcardInterfaceID iface, @NonNull SmartcardProtocol T, @NonNull SmartcardClock F, @NonNull SmartcardBaud D, @NonNull ErrorCode error)
 Asynchronously exchange a PPS (Protocol and Parameter Selection) with a card in a given interface on a connected Grabba device. More...
 
static void powerDown (@NonNull SmartcardInterfaceID iface, boolean blocking, @NonNull ErrorCode error)
 [DEPRECATED] Attempt to power down a contact smart card in a given card interface on a connected Grabba device More...
 
static void powerDown (@NonNull SmartcardInterfaceID iface, boolean blocking, boolean waitIfCardBusy, @NonNull ErrorCode error)
 Attempt to power down a contact smart card in a given card interface on a connected Grabba device. More...
 
static boolean powered (@NonNull SmartcardInterfaceID iface)
 Query whether a contact smart card is currently powered up in a given card interface on a connected Grabba device. More...
 
static void powerUp (@NonNull SmartcardInterfaceID iface, boolean autoPPS, @NonNull ErrorCode error)
 Attempt to power up a contact smart card, and optionally exchange parameters with it. More...
 
static boolean PPS_Exchanged (@NonNull SmartcardInterfaceID iface)
 Query whether a contact smart card has had a successful PPS exchange since its last power-up. More...
 
static boolean readyForPPS (@NonNull SmartcardInterfaceID iface)
 Query whether a contact smart card is ready for a PPS exchange. More...
 
static boolean supported ()
 Query whether there is currently a connected Grabba device with contact smart card functionality. More...
 
static ResponseAPDU syncExchangeAPDU (@NonNull SmartcardInterfaceID iface, @NonNull CommandAPDU command, @NonNull ErrorCode error)
 Synchronously exchange an APDU (Application Protocol Data Unit) with an inserted smart card in a given interface on a connected Grabba device. More...
 
static boolean valid (@NonNull SmartcardInterfaceID iface)
 Query whether a given interface ID represents a valid interface on a connected Grabba device. More...
 

Member Function Documentation

◆ cardPresent()

static boolean cardPresent ( @NonNull SmartcardInterfaceID  iface)
static

Query whether there is currently a contact smart card present in a given interface on a connected Grabba device.

This is a non-blocking call; card presence/absence information is cached internally by the driver.

Parameters
ifaceID of the interface which is being queried
Returns
True if there is a connected Grabba device, the supplied interface ID is valid for that device, and that interface currently holds a card; false otherwise.

◆ defaultInterface()

static SmartcardInterfaceID defaultInterface ( )
static

Obtain the ID of the default interface for a connected Grabba device.

The default interface is as follows:

The result of this function will be fixed for the lifetime of a connection; consequently, it is acceptable to cache the value and then use it for all subsequent API calls.

Note that this interface will always be a valid interface on any Grabba device with contact smart card support. This function should not be called unless such a device is currently connected.

Returns
Either SmartcardInterfaceID.PRIMARY_SLOT or SmartcardInterfaceID.PRIMARY_SAM, depending on device capabilities

◆ exchangeAPDU()

static void exchangeAPDU ( @NonNull SmartcardInterfaceID  iface,
@NonNull CommandAPDU  command,
@NonNull ErrorCode  error 
)
static

Asynchronously exchange an APDU (Application Protocol Data Unit) with an inserted smart card in a given interface on a connected Grabba device.

If the supplied error code indicates no prior errors, there is a connected Grabba device with contact smart card capabilities, the selected interface is valid for that device, and that interface contains a powered-on smart card, then a command APDU will be sent to that card. Following this, the result of the operation will be provided to any active SmartcardListener objects, either as a SmartcardListener.APDU_Event if it succeeds or a SmartcardLIstener.errorEvent if it fails (regardless of reason).

If a prior error is indicated, then no action is taken, and the error code will not be updated.

If there is no connection, the connected Grabba device lacks contact smart card capabilities, the interface ID is invalid for the device, there is no card in the selected interface, or the card has not been powered on, then the error code will be updated accordingly and no further action will be taken.

Parameters
ifaceID of the interface containing the card
commandAPDU to exchange with the card
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected when starting the operation, then this will be updated with the details.
See also
SyncExchangeAPDU for a synchronous (blocking) equivalent to this function.

◆ exchangePPS()

static void exchangePPS ( @NonNull SmartcardInterfaceID  iface,
@NonNull SmartcardProtocol  T,
@NonNull SmartcardClock  F,
@NonNull SmartcardBaud  D,
@NonNull ErrorCode  error 
)
static

Asynchronously exchange a PPS (Protocol and Parameter Selection) with a card in a given interface on a connected Grabba device.

If the supplied error code indicates no prior errors, there is a connected Grabba device with contact smart card capabilities, the selected interface is valid for that device, that interface contains a powered-on smart card, that card supports PPS exchanges, and no PPS or APDU exchanges have taken place since the card was powered up, then a PPS will be sent to that card.

Event notifications will be provided to any active SmartcardListener objects as follows:

If a prior error is indicated, then no action is taken, and the error code will not be updated.

If there is no connection, the connected Grabba device lacks contact smart card capabilities, the interface ID is invalid for the device, there is no card in the selected interface, the card has not been powered on, or a prior PPS or APDU exchange has occurred since the card was powered up, then the error code will be updated accordingly and no further action will be taken.

Note
This method should only be necessary on S- and Z-series devices, and only then in cases where the card's preferred settings are not supported by the Grabba device (i.e. Fi/Di ratio below 31). In all other cases the PPS exchange can be performed automatically; see powerUp() for details.
Parameters
ifaceID of the interface containing the card
TProtocol selection as per ISO/IEC 7816-3
FClock rate conversion integer and maximum supported frequency as per ISO/IEC 7816-3
DBaud rate adjustment integer as per ISO/IEC 7816-3
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected when starting the operation, then this will be updated with the details.

◆ powerDown() [1/2]

static void powerDown ( @NonNull SmartcardInterfaceID  iface,
boolean  blocking,
@NonNull ErrorCode  error 
)
static

[DEPRECATED] Attempt to power down a contact smart card in a given card interface on a connected Grabba device

This is a deprecated form of powerDown() provided solely for compatibility purposes. Behaviour is identical to calling the current version of the function with its waitIfCardBusy parameter set to false. Refer to that function's documentation for details.

Parameters
ifaceID of the interface containing the card
blockingIf true (recommended), call is blocking and operation is synchronous; if false, call is non-blocking and operation is asynchronous.
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected when starting the operation, or if the operation is synchronous, then this will be updated with the details.

◆ powerDown() [2/2]

static void powerDown ( @NonNull SmartcardInterfaceID  iface,
boolean  blocking,
boolean  waitIfCardBusy,
@NonNull ErrorCode  error 
)
static

Attempt to power down a contact smart card in a given card interface on a connected Grabba device.

If the supplied error code indicates no prior errors, there is a connected Grabba device with contact smart card capabilities, the given interface is valid, and that interface contains a smart card, then an attempt will be made to power that card down.

If a prior error is indicated, or if the card in question is already powered down, then no action is taken, and the error code will not be updated.

If there is no connection, the connected Grabba device lacks contact smart card capabilities, the given interface ID is invalid for that device, or there is no card in the selected interface, then the error code will be updated accordingly and no further action will be taken.

This operation may be performed either synchronously or asynchronously:

  • Synchronous mode: This call blocks until either an error is detected or the operation is successfully completed. Any detected errors will be returned via the error parameter; no error events will be sent to SmartcardListener objects. However, powerDownEvent will still trigger if/when the card is powered down.
  • Asynchronous mode: This call is non-blocking, and can only detect a small subset of possible error conditions. If the operation is successfully commenced, then NO_ERROR is returned, and notifications will be sent to SmartcardListener objects when the operation completes:
Parameters
ifaceID of the interface containing the card
blockingIf true (recommended), call is blocking and operation is synchronous; if false, call is non-blocking and operation is asynchronous.
waitIfCardBusyModifies behaviour as follows:
  • If power-down call occurs when card is inactive: parameter has no effect
  • If card is busy with another operation (e.g. APDU exchange):
    • If parameter is true (recommended): power-down is triggered after earlier operation completes
      • If blocking parameter is also true, then this call will block through the earlier op and then the power-down op
    • If parameter is false: DEVICE_BUSY error is returned; power-down does not occur
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected when starting the operation, or if the operation is synchronous, then this will be updated with the details.

◆ powered()

static boolean powered ( @NonNull SmartcardInterfaceID  iface)
static

Query whether a contact smart card is currently powered up in a given card interface on a connected Grabba device.

This is a non-blocking call; communication status is cached internally by the driver.

Parameters
ifaceID of the interface which is being queried
Returns
True if there is a connected Grabba device, the supplied interface ID is valid for that device, and that interface currently holds a card which has been powered up; false otherwise.

◆ powerUp()

static void powerUp ( @NonNull SmartcardInterfaceID  iface,
boolean  autoPPS,
@NonNull ErrorCode  error 
)
static

Attempt to power up a contact smart card, and optionally exchange parameters with it.

If the supplied error code indicates no prior errors, there is a connected Grabba device with contact smart card capabilities, the given interface is valid, and that interface contains a smart card, then an attempt will be made to power that card up, and if that succeeds then a Protocol and Parameter Selection (PPS) message exchange will optionally be triggered.

If a prior error is indicated, then no action is taken, and the error code will not be updated.

If there is no connection, the connected Grabba device lacks contact smart card capabilities, there is no card in the selected interface, or the card in question is already powered on, then the error code will be updated accordingly and no further action will be taken.

The results of the operation, if attempted, will be communicated as events to any active SmartcardListener objects:

The triggering of the power-up event may be used to inform the calling code as to the card's state - if that event doesn't trigger, then the card can be assumed to be powered down at the end of the operation.

The parameters selected for automatic PPS exchange (if enabled and supported) will be as follows:

  • If card's indicated parameter values are supported by the Grabba device, then they will be used
    • Note that this should always be the case for S2- and GT-series devices; users of such devices should consequently always set autoPPS to true
  • Otherwise, the default parameter values will be used (Fd = 372, Dd = 1, f_max = 5MHz, protocol T0 unless card only supports T1)

If the PPS exchange fails, then it is still possible to use the card; call powerUp again with autoPPS set to false, then call exchangePPS() with appropriate settings to manually configure the session protocol and parameters. However, if the card cannot be powered up in the first place then it is probably unusable.

Parameters
ifaceID of the interface containing the card
autoPPSThis parameter controls triggering of automatic PPS exchanges; it should be set true for all card types on S2- or GT-series devices, and for most card types on S- or Z-series devices. Behaviour is as follows:
  • If card supports PPS exchange and autoPPS == true: PPS exchange is performed automatically after a successful power-up
  • If card supports PPS exchange and autoPPS == false: no automatic PPS exchange; exchangePPS() must be called post power-up
  • If card doesn't support PPS exchange: this parameter has no effect; no automatic PPS exchange will occur
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected when starting the operation, then this will be updated with the details.

◆ PPS_Exchanged()

static boolean PPS_Exchanged ( @NonNull SmartcardInterfaceID  iface)
static

Query whether a contact smart card has had a successful PPS exchange since its last power-up.

This is a non-blocking call; PPS exchange status is cached internally by the driver.

Parameters
ifaceID of the interface which is being queried
Returns
True if there is a connected Grabba device, the supplied interface ID is valid for that device, that interface currently holds a card which has been powered up, and there has been a successful PPS exchange operation since it was last powered up; false otherwise

◆ readyForPPS()

static boolean readyForPPS ( @NonNull SmartcardInterfaceID  iface)
static

Query whether a contact smart card is ready for a PPS exchange.

This is a non-blocking call; PPS exchange status is cached internally by the driver.

A card is ready for PPS exchange if:

  • It has been powered up
  • It supports PPS exchange - which requires:
    • Card boots in negotiable mode (the vast majority of cards do this)
    • Card supports non-default parameter values (e.g. for faster-than-default transfer speeds) or more than one protocol
  • No PPS exchanges (whether manual or automatic) have been attempted since the card was powered up
  • No APDU exchanges have been attempted since the card was powered up
Parameters
ifaceID of the interface which is being queried
Returns
True if there is a connected Grabba device, the supplied interface ID is valid for that device, that interface currently holds a card which has been powered up, the card supports PPS exchanges, and no PPS or APDU exchanges have occurred with the card since it was powered up; false otherwise

◆ supported()

static boolean supported ( )
static

Query whether there is currently a connected Grabba device with contact smart card functionality.

This is a non-blocking call; device capabilities are cached internally by the driver.

Returns
True if there is a connected Grabba device and that device supports contact smart card functionality; false otherwise.

◆ syncExchangeAPDU()

static ResponseAPDU syncExchangeAPDU ( @NonNull SmartcardInterfaceID  iface,
@NonNull CommandAPDU  command,
@NonNull ErrorCode  error 
)
static

Synchronously exchange an APDU (Application Protocol Data Unit) with an inserted smart card in a given interface on a connected Grabba device.

If the supplied error code indicates no prior errors, there is a connected Grabba device with contact smart card capabilities, the selected interface is valid for that device, and that interface contains a powered-on smart card, then a command APDU will be sent to that card. If the operation fails, the error code will be updated; if it succeeds, the APDU received in response will be returned.

If a prior error is indicated, then no action is taken, and the error code will not be updated.

If there is no connection, the connected Grabba device lacks contact smart card capabilities, the interface ID is invalid for the device, there is no card in the selected interface, or the card has not been powered on, then the error code will be updated accordingly and no further action will be taken.

Note
This call will not result in any events being triggered on SmartcardListener objects; all returned information is delivered via parameters and the method result, and this call will block for as long as is necessary to complete the operation or detect its failure. Consequently, this function should not be called from any threads which have to perform latency-sensitive tasks (e.g. UI updates).
Parameters
ifaceID of the interface containing the card
commandAPDU to exchange with the card
errorError code; operation proceeds only if set to NO_ERROR. If an error is detected during the operation, then this will be updated with the details.
Returns
The response APDU received from the card, if the operation completed successfully, otherwise a default-constructed APDU (status 0x6F00, no response data)
See also
ExchangeAPDU for an asynchronous (non-blocking) equivalent to this function.

◆ valid()

static boolean valid ( @NonNull SmartcardInterfaceID  iface)
static

Query whether a given interface ID represents a valid interface on a connected Grabba device.

Parameters
ifaceID of the interface which is being queried
Returns
True if there is a connected Grabba device and the supplied ID corresponds to a valid contact smart card interface on that device; false otherwise.