How to update readers
This section will give a technical explanation of how to update readers.
- iOS
- Android
- React Native
ReaderConfigurator
is the object in charge of managing the update. To create a ReaderConfigurator
, use the
ReaderConfiguratorFactory
.
let readerConfigurator = ReaderConfiguratorFactory.createConfigurator(delegate: delegate)
Where the delegate implements the ReaderConfiguratorDelegateprotocol
. Each delegate callback will guide you into
completing the configuration, and asking for needed data.
On the ReaderConfiguratorDelegate.onConfigurationRequired
method, you must provide a ReaderConfigurationFiles
object. There are several factories according the configuration type and the reader used, firmware configuration
can be done as follows:
QPOS
QposReaderConfigurationFactory.qposFirmwareFiles(firmware: url)
Where firmware contains the bundle file provided from Geopagos.
MagicPOS
MagicPosReaderConfigurationFactory.qposFirmwareFiles(firmware: url)
Firmware configuration is the same as QPOS.
In the case that the bundle file does not contain a configuration that matches the configuration type and the reader
requested, it will return a .invalidConfiguration
error.
QPOS Mini firmware update (Edge case)
In the case Firmware update fails, the reader is left in a “boot state” (not response to press any key). In this case it is necessary to use a special device to finish the update.
let qposMiniFirmwareRestoreDevice = QposMiniFirmwareRestoreDevice(device: device, readerInfo: readerInfo)
To create a ReaderConfigurator, simply use SDKReaderConfiguratorFactory to create a new SDKReaderConfigurator.
val readerConfigurator = SDKReaderConfiguratorFactory.createConfigurator({LISTENER})
Where LISTENER is the SDKReaderConfiguratorListener for the Configurator and Reader state changes. Each state change received in SDKReaderConfiguratorListener.onReaderConfiguratorStateChanged will guide you into completing the configuration, giving current state information, and asking for needed data.
You must use SDKConfigurationFile object to provide the file source to the sdk using one of the creator methods it provides. Each Reader dependency exposes a ConfigurationFactory to create the corresponding SDKConfigurationFiles. These will only be available if the dependency for that reader is set in the project.
QPOS
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val qposEmvConfiguration = SDKQposReader.ConfigurationFactory.qposEmvBinFiles(bundleFile)
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val qposEmvConfiguration = SDKQposReader.ConfigurationFactory.qposEmvXmlFile(bundleFile)
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val qposFirmwareConfiguration = SDKQposReader.ConfigurationFactory.qposFirmwareFiles(bundleFile)
MagicPOS
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val magicposFirmwareEmvConfiguration = SDKMagicPosReader.ConfigurationFactory.magicPosFirmwareEmvFiles(bundleFile)
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val magicposEmvConfiguration = SDKMagicPosReader.ConfigurationFactory.magicPosEmvFile(bundleFile)
val bundleFile = SDKConfigurationFile({BUNDLE_FILENAME}, SDKConfigurationFile.Source.Asset)
val magicposEmvConfiguration = SDKMagicPosReader.ConfigurationFactory.magicPosFirmwareEmvFiles(bundleFile)
Then, you can pass that SDKConfigurationFiless to the
SDKReaderConfiguratorState.ConfigurationRequired
state.provideConfiguration(configurationFiles)
Update reader
To create a ReaderConfigurator
, simply use createReaderConfigurator
function provided by the useReadersSdk
hook.
const { createReaderConfigurator } = useReadersSdk()
const readerConfigurator = await createReaderConfigurator()
To start the update, call readerConfigurator.start()
. This method receives two callbacks:
- onReaderConfiguratorStateChanged
- onReaderStateChanged
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
// handles reader configurator state
}
const onReaderStateChanged = (state, params) => {
// handles reader state
}
Provide reader
Provide the reader to update.
Call the method readerConfigurator.provideDevice()
in ReaderConfiguratorStates.DeviceRequired
state.
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.DeviceRequired:
await readerConfigurator.provideDevice(reader.id)
break
}
}
Provide configuration
Provide the configuration.
Call the function readerConfigurator.provideConfiguration()
in ReaderConfiguratorStates.ConfigurationRequired
state.
There are two possible ways to pass the configuration file to the Configurator.
Reading file from apk
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.ConfigurationRequired:
await readerConfigurator.provideConfiguration({
readerId: reader.id,
filePath: 'configurationBundle.zip',
source: ConfigurationSources.Storage,
})
break
}
}
Reading file from local storage
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.ConfigurationRequired:
const path = RNFS.DocumentDirectoryPath + '/configurationBundle.zip'
await readerConfigurator.provideConfiguration({
readerId: reader.id,
filePath: path,
source: ConfigurationSources.Storage,
})
break
}
}
Update completed
Check for ReaderConfiguratorStates.ConfigurationRequired
state.
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.ConfigurationCompleted:
console.log('Configuration completed!!!')
break
}
}
Update error
During an update, two kind of errors can occur: recoverable and not recoverable. In the recoverable, it’s possible to retry the update calling the associate callback, in the not recoverable errors, the update finished, and it's necessary to start the process again.
Recoverable Error
Call the method readerConfigurator.recoverFromError()
in ReaderConfiguratorStates.RecoverableError
state
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.RecoverableError:
await readerConfigurator.recoverFromError()
break
}
}
Nonrecoverable Error
Check for ReaderConfiguratorStates.RecoverableError
state
const onReaderConfiguratorStateChanged = async (readerConfigurator: ReaderConfigurator, state: ReaderConfiguratorStates, params) => {
switch (state) {
case ReaderConfiguratorStates.NonRecoverableError:
console.log('Non Recoverable error:', params['error'])
break
}
}