Device Connection
Note: If you prefer the older connection flow, you can continue to use it without any modifications.
This document explains the connection handling and its interaction with transactions, configuration,
and printing. It outlines how these processes should be executed and clarifies the expected behavior
when using the DeviceConnection
flow in combination with other flows.
The goal of this connection handling approach is provide freedom on the device connection handling. Key enhancements include:
- Persistent Connections: Device connections are persistent and can be established at any time, even before initiating any transaction or configuring a reader. This ensures that the connection remains available for several tasks without requiring re-initialization.
- Backward compatibility: If needed, you can still use the old way of connecting to devices without any changes.
Connection Handling
The SDKDeviceConnectionControllerFactory
class simplifies the creation of connection controllers
for devices within your workflow. You can use this class to:
- Handle device connection events.
- Manage the connection lifecycle (connect, disconnect, recover errors).
- Abort ongoing connections when required.
The SDKDeviceConnectionControllerFactory
creates a SDKDeviceConnectionController
that is used to
manage the connection lifecycle. It needs a SDKDeviceConnectionControllerListener
for handling
DeviceConnection state and status. Below is an example:
val deviceConnectionListener = SDKDeviceConnectionControllerListener {
override fun onDeviceConnectionStateChanged(state: SDKDeviceConnectionState) {
when (state) {
is SDKDeviceConnectionState.Disconnected -> {
// Device is disconnected.
// In this state you can connect to a device at any time by calling
// state.connect(device) with a device.
state.connect(device)
}
is SDKDeviceConnectionState.Connected -> {
// Device is connected.
// In this state you can disconnect the current device by calling state.disconnect().
state.disconnect()
// When device is connected, information about it can be obtained.
state.device // (`SDKDevice`)
state.deviceInfo // (`SDKDeviceInfo`)
}
is SDKDeviceConnectionState.Error.NonRecoverable<*> -> {
//This state indicates that an error described by SDKDeviceConnectionError and an
// exception has occurred and its NotRecoverable.
// Nothing can be done after the SDKDeviceConnection is in this state.
handleNonRecoverableError(state.error, state.exception)
}
is SDKDeviceConnectionState.Error.Recoverable<*> -> {
// This state indicates that an error described by SDKDeviceConnectionError has
// occurred and its recoverable.
// In this state you can recover the error by calling state.recover().
// Recovering from a RecoverableError will return the SDKDeviceConnection to the
// last "Stable" state to continue.
handleRecoverableError(state.error)
state.recover()
}
is SDKDeviceConnectionState.InUse -> {
// The device is already in use by a transaction, configuration or printing flow.
// You cannot interact with this state.
}
}
}
override fun onDeviceConnectionStatusChanged(status: SDKDeviceConnectionStatus) {
// This status indicates current device status: Disconnected, Connected or Connecting.
// DeviceConnection could be with state InUse and status Disconnected, for example.
}
}
// Create the connection controller
val connection = SDKDeviceConnectionControllerFactory.create(deviceConnectionListener)
Interaction with transaction, configuration or printing flows
- Initiate Connection First: A connection to a device must be successfully established before initiating any other process (transaction, configuration, or printing). Starting any of these processes without an active connection is not possible.
- Existing Connection:
- If there is already a connection initiated by
SDKDeviceConnectionController
, it emits anInUse
state. - When the state is
InUse
, you cannot interact with theSDKDeviceConnectionController
(e.g., attempting to connect again). In this state, it is not possible to abort the connection. If you do that, aSDKCannotAbortException
is thrown. - When any other flow using this device connection emits a final status, the
SDKDeviceConnectionController
will stop beingInuse
state and emit the corresponding state (Connected or Disconnected) and you can interact with it again. - When any other flow using this device connection ends, connection never ends until you finish it. Therefore, reconnection is not necessary if you want to continue with another transaction, configuration or print.
- If there is already a connection initiated by
When using the SDKDeviceConnectionController
in combination with others flows:
- Separate Flows:
- The connection flow manages connection states, while the transaction, configuration or printing flow manages their own states.
- Each flow emits its states independently and should be interacted with separately.
- If other flow needs to provide a device, it must be the same device used in
SDKDeviceConnectionState.Disconnected
inSDKDeviceConnectionController
. - Once the connection is established, you can manage transactions, configurations or printing as
usual.
SDKDeviceConnectionControllerListener
will continue to receive updates on the device connection state.
- Error Recovery:
- If a transaction, configuration or printing encounters a connection error, the
state.recover()
method in the connection controller attempts to reconnect to the same device and return to the last stable state. - If reconnection fails repeatedly, the recovery process will loop until the connection is restored or the user aborts the transaction.
- If a transaction, configuration or printing encounters a connection error, the
- Aborting:
- If a transaction, configuration or printing is aborted and the connection is
InUse
, the connection flow will return to the last stable state.
- If a transaction, configuration or printing is aborted and the connection is
When SDKTransactionIntent's SDKReaderState
, SDKReaderConfigurator's SDKReaderState
, and SDKPrinter's
SDKPrinterState
emit a state, this state has a different meaning depending on whether Legacy mode or
the new DeviceConnection mode is used.
In Legacy mode, the state refers to the actual connection of the device, so a Disconnected state means that the device is physically disconnected from the phone.
In the new DeviceConnection mode, the physical connection is exclusively managed by the
SDKDeviceConnectionController
. In this mode, the state emitted by SDKTransactionIntent
,
SDKReaderConfigurator
, or SDKPrinter
refers to the logical connection between the device and
the "operation" itself.
For example, when an SDKTransactionIntent's SDKReaderState.NotConnected
status is emitted after a
transaction is aborted or completed, it means that the device is no longer "in use" for that
transaction. However, the actual physical connection of the device must be checked through
SDKDeviceConnectionController's SDKDeviceConnectionStatus
.