Device Setup & Readiness
A Miura reader must be in a known-good state before it can transact: on the OS and MPI versions the SDK supports, with security keys loaded, its ECC terminal certificate signed and installed, and its configuration current. All of this is coordinated by a single entry point: ensureDeviceReady().
Ensuring the device is ready to transact
ensureDeviceReady() brings the selected device into a Toro-compatible state. In one call it will, as needed:
- Reset the reader to the SDK's required MPI version.
- Reset the reader to the SDK's required OS version.
- Reconnect to the reader after any reboot triggered by the above.
- Check the TMS for pending updates.
- Sign and install the ECC terminal certificate.
- Inject security keys (SRED / PIN).
- Apply pending configuration updates.
toro.ensureDeviceReady(
onStateChanged = { state ->
Log.d(TAG, "Device setup: $state")
// Drive end-user messaging from `state`
},
onSuccess = {
Log.d(TAG, "Device is ready")
},
onError = { error ->
Log.e(TAG, "Device setup failed", error)
}
// onManualEccSigningRequired is optional in Kotlin (defaults to a no-op) and is
// TEST-device only, so it is omitted here. See "Manual ECC signing" below.
)Safe to re-run
ensureDeviceReady() is safe to call repeatedly. Steps that are already satisfied are skipped, so it only does the work the device actually needs. If the device is already on the correct OS and MPI, has its keys and certificate, and has no pending TMS updates, no changes are made to the device (the TMS status check still runs each time to determine that).
Because of this, you should call it both:
- when first pairing a new reader, and
- on every app launch (and/or whenever a device is selected).
On a healthy device the only unavoidable work is a single StatusReport to the TMS to confirm there are no pending updates.
Which OS / MPI versions?
ensureDeviceReady() targets the specific OS and MPI versions that the current Toro SDK release is built and tested against. The values the SDK requires are exposed as constants on MiuraDeviceInfo (MiuraDeviceInfo.REQUIRED_OS_VERSION and MiuraDeviceInfo.REQUIRED_MPI_VERSION), which indicate which MPI and OS that SDK release is designed for. The osVersionOk / mpiVersionOk fields of baselineStatus are derived from them.
Tracking progress: DeviceSetupState
The onStateChanged callback fires on the main thread each time setup moves to a new phase, with a DeviceSetupState value. Use it to show appropriate messaging to the operator and cardholder.
Automatic reconnection after reboot
Resetting the OS/MPI or applying certain updates causes the reader to reboot. The reader gives no direct "reboot finished" signal, so the SDK reconnects automatically by polling for the connection to come back, then continues, with no integrator intervention required. While this is happening, onStateChanged reports RECONNECTING.
Manual ECC signing (TEST devices only)
Most integrations can ignore this section. For PROD devices, ensureDeviceReady() provisions the ECC terminal certificate end-to-end via the TMS, so there is nothing to do — and PROD devices never reach the manual-signing state. Manual ECC signing only ever applies to TEST devices used during development, where there is no TMS CSR-signing service and the certificate must instead be signed out-of-band by the device manufacturer.
Because it is a development-only, low-frequency step, you are not expected to build manual-signing support into your app. The onManualEccSigningRequired callback is only ever invoked for TEST devices, which your production app will never see, so PROD integrations can ignore it entirely:
- Kotlin — the callback is optional; it defaults to a no-op, so you can simply omit it.
- Java — DeviceSetupListener.onManualEccSigningRequired must be implemented, but the body can be left empty.
Instead, use our sample app to provision TEST devices. It ships as a ready-made APK with a complete manual-signing UI, so you can get a TEST device's certificate signed and installed without writing any of this yourself.
What happens under the hood
For completeness, when a TEST device needs its ECC certificate signed, setup:
- Generates the CSR on the device.
- Halts at DeviceSetupState.MANUAL_ECC_SIGNING_REQUIRED and delivers the raw CSR bytes via the onManualEccSigningRequired callback. (When this happens, onSuccess/onError are not called for that run.)
To complete provisioning:
- Get the CSR signed, producing a signed terminal-ecc-cert.json.
- Install it with installEccTerminalCert(); the device restarts automatically on success.
- Call ensureDeviceReady() again to finish setup.
The sample app implements exactly this flow. If you do need to drive it yourself, the callback receives the CSR bytes:
Error handling
If a setup step fails, onError is invoked on the main thread with a ToroException. Setup does not partially "succeed"; re-running ensureDeviceReady() after resolving the cause will resume from wherever the device currently is, skipping any steps already completed.