bemanitools/src/main/aciotest/icca.c

129 lines
3.5 KiB
C

#include "aciotest/icca.h"
#include <stdio.h>
#include <stdlib.h>
#include "aciodrv/icca.h"
#define IDLE_RESPONSES_BETWEEN_FELICA_POLLS 5
struct icca_handler_ctx {
bool init;
bool slotted_reader;
uint8_t last_poll;
};
bool aciotest_icca_handler_init(
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx)
{
*ctx = malloc(sizeof(struct icca_handler_ctx));
struct icca_handler_ctx *icca_ctx = (struct icca_handler_ctx *) *ctx;
icca_ctx->init = false;
icca_ctx->slotted_reader = true;
icca_ctx->last_poll = 0;
icca_ctx->slotted_reader = aciodrv_icca_is_slotted(device, node_id);
return aciodrv_icca_init(device, node_id);
}
bool aciotest_icca_handler_update(
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx)
{
struct icca_handler_ctx *icca_ctx = (struct icca_handler_ctx *) ctx;
if (icca_ctx->init == false) {
icca_ctx->init = true;
if (icca_ctx->slotted_reader) {
/* eject cards that were left in the reader */
if (!aciodrv_icca_set_state(
device, node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) {
return false;
}
}
}
struct ac_io_icca_state state;
if (!aciodrv_icca_get_state(device, node_id, &state)) {
return false;
}
printf(
">>> ICCA %d:\n"
"status_code: %d\n"
"sensor_state: %d\n"
"keypad_started: %d\n"
"card_type: %d\n"
"UUID: %02X%02X%02X%02X%02X%02X%02X%02X\n"
"key_state: %04X\n"
"key_events[0]: %02X\n"
"key_events[1]: %02X\n",
node_id,
state.status_code,
state.sensor_state,
state.keypad_started,
state.card_type,
state.uid[0],
state.uid[1],
state.uid[2],
state.uid[3],
state.uid[4],
state.uid[5],
state.uid[6],
state.uid[7],
state.key_state,
state.key_events[0],
state.key_events[1]);
if (icca_ctx->slotted_reader) {
/* eject card with "empty" key */
if (state.key_state & AC_IO_ICCA_KEYPAD_MASK_EMPTY) {
if (!aciodrv_icca_set_state(
device, node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) {
return false;
}
}
/* allow new card to be inserted when slot is clear */
if (!(state.sensor_state & AC_IO_ICCA_SENSOR_MASK_BACK_ON) &&
!(state.sensor_state & AC_IO_ICCA_SENSOR_MASK_FRONT_ON)) {
if (!aciodrv_icca_set_state(
device, node_id, AC_IO_ICCA_SLOT_STATE_OPEN, NULL)) {
return false;
}
}
/* lock the card when fully inserted */
if ((state.sensor_state & AC_IO_ICCA_SENSOR_MASK_BACK_ON) &&
(state.sensor_state & AC_IO_ICCA_SENSOR_MASK_FRONT_ON)) {
if (!aciodrv_icca_set_state(
device, node_id, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL)) {
return false;
}
if (!aciodrv_icca_read_card(device, node_id, NULL)) {
return false;
}
}
} else {
// wavepass reader, see eamio-icca for why this is done this way
if (state.status_code != AC_IO_ICCA_STATUS_BUSY_NEW) {
++icca_ctx->last_poll;
}
if (icca_ctx->last_poll >= IDLE_RESPONSES_BETWEEN_FELICA_POLLS) {
if (!aciodrv_icca_poll_felica(device, node_id)) {
return false;
}
icca_ctx->last_poll = 0;
}
}
return true;
}