Getnet DocsGetnet Docs

Implementar los servicios de hardware

Esta guía muestra las llamadas exactas que la Middleware App y el Devkit hacen contra tu Manufacturer Service App, servicio por servicio. Úsala para confirmar que tu implementación responde como el software de Getnet espera.

Cómo funciona

Todas las llamadas de abajo llegan a tu servicio a través de mainService, el stub IMainService que la Middleware App obtiene tras vincularse a tu servicio. Cada servicio — tarjeta, impresora, beeper, etc. — cuelga de mainService como una propiedad propia. La mayoría de las operaciones informan de su resultado mediante un callback, no mediante un valor de retorno.

Antes de empezar

Completa la configuración de la integración HAL para que tu servicio se vincule correctamente, y luego ejecuta el Devkit para probar cada llamada a medida que la implementas.

Beeper

El Devkit llama a custom con una duración en milisegundos:

mainService.beeper.custom(500) // 500 milliseconds

Tu implementación de IBeeperService también debe soportar cuatro sonidos con nombre, cada uno con una duración fija:

SonidoDuración
successPitido de 500 ms.
errorPitido de 1000 ms.
digitPitido de 100 ms.
nfcPitido de 100 ms, pausa de 300 ms, pitido de 100 ms.

Tarjeta

Obtén el servicio de tarjeta una vez y luego llama al método de búsqueda que corresponda al tipo de lectura que necesita quien llama:

val cardService = mainService.card

Cada tipo de búsqueda usa una constante fija:

ConstanteValor
MAG"1"
CHIP"2"
NFC"3"

Búsqueda por chip:

cardService.searchChip(1000, object : ICardCallback.Stub() {
    override fun onCard(cardResponse: CardResponse?) {
        val pan = cardResponse?.pan
        cardService.stopAllReaders()
    }
    override fun onMessage(message: String?) {
        cardService.stopAllReaders()
    }
    override fun onError(error: String?) {
        cardService.stopAllReaders()
    }
})

La búsqueda por banda magnética devuelve track1, track2 y track3 en onCard en lugar de pan. La búsqueda NFC devuelve la misma forma de CardResponse que la búsqueda por chip.

Ambas siguen el mismo patrón onCard / onMessage / onError, y ambas deben llamar a stopAllReaders() en cuanto llega un resultado.

Mifare

IMifareService cubre la presencia de tarjeta, la autenticación y la lectura/escritura a nivel de bloque:

mainService.mifare.searchCard(object : IMifareCallback.Stub() {
    override fun onCard(type: Int) { /* card type detected */ }
    override fun onError(error: String?) { /* handle error */ }
})

mainService.mifare.searchCardAndActivate(object : IMifareActivateCallback.Stub() {
    override fun onActivate(key: ByteArray?) { /* card activated */ }
    override fun onError(error: String?) { /* handle error */ }
})

La autenticación de sector y de bloque toma una clave de 6 bytes:

val key = byteArrayOf(0xff.toByte(), 0xff.toByte(), 0xff.toByte(), 0xff.toByte(), 0xff.toByte(), 0xff.toByte())
mainService.mifare.authenticateSectorWithKeyA(sector = 2, key)
mainService.mifare.authenticateBlockWithKeyA(block = 10, key)
mainService.mifare.authenticateSectorWithKeyB(sector = 2, key)
mainService.mifare.authenticateBlockWithKeyB(block = 10, key)

Tras la autenticación, tu servicio debe soportar decrement, increment, readBlock, restore, transfer y writeBlock sobre un índice de bloque dado. También debe soportar close, isExist, activate y halt para el control de sesión. getCardSerialNo devuelve el UID de la tarjeta como cadena hexadecimal.

LED

ILedService expone un par encendido/apagado por color — rojo, azul, amarillo y verde:

mainService.led.turnOnRed()
mainService.led.turnOffRed()

Implementa el mismo par para azul, amarillo y verde.

Impresora

Todos los métodos de IPrinterService deben lanzar IllegalStateException si tu servicio aún no ha inicializado la impresora:

mainService.printer?.init()
    ?: throw IllegalStateException("service isn't initiated")

Una vez inicializada, tu servicio construye un trabajo de impresión a partir de una secuencia de llamadas — addText, addBarCode, addQrCode, addImageBitmap, addImageByteArray — seguida de print o printAndRemovePaper:

mainService.printer?.addText(align, text)
mainService.printer?.print(object : IPrinterCallback.Stub() {
    override fun onSuccess() { /* job printed */ }
    override fun onError(cause: Int) { /* map cause to a status */ }
})

setGray fija el nivel de escala de grises, y defineFontFormat fija la fuente activa. Consulta la referencia de interfaces de servicio para las especificaciones fijas de impresora — tamaño de imagen, límites de caracteres y el umbral de escala de grises que tu servicio debe aplicar.

Cámara

readFront lee la cámara frontal con un tiempo de espera e informa del resultado mediante un callback:

mainService.camera.readFront(
    timeout = 2000,
    callback = object : ICameraCallback.Stub() {
        override fun onSuccess(code: String?) { /* code read */ }
        override fun onTimeout() { /* no result within timeout */ }
        override fun onCancel() { /* caller canceled the read */ }
        override fun onError(error: String?) { /* handle error */ }
    },
)

Estadísticas del sistema

IStatService informa de los recuentos de éxito y de fallo por tipo de lectura, tanto a nivel de dispositivo como por aplicación llamante:

mainService.stats.getAllStatisticsByApp(object : IStatCallback.Stub() {
    override fun onStatistic(statResponse: StatResponse?) {
        val paperStatus = statResponse?.generalPaperStatus
        val mifareStatus = statResponse?.generalMifareStatus
    }
    override fun onError(error: String?) { /* handle error */ }
})

Algunos métodos HAL, como print(userId, callback) y searchMag(userId, timeout, callback), reciben un parámetro userId que identifica a la aplicación llamante. Resuélvelo a un nombre de paquete con packageManager.getNameForUid(userId). Usa ese nombre de paquete para atribuir las estadísticas a la aplicación correcta.

Leer el resultado

Una implementación correcta informa siempre de los eventos de hardware por el callback de quien llama, nunca solo por un valor de retorno. También llama a stopAllReaders() cuando termina una lectura de tarjeta, tanto si tuvo éxito como si no.

Los métodos de impresora son la única excepción que merece mención propia: cualquiera de ellos llamado antes de init() debe lanzar IllegalStateException en lugar de fallar en silencio.

Próximos pasos