mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-08-08 11:24:04 -05:00
129 lines
3.5 KiB
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;
|
|
} |