mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-26 06:39:39 +01:00
Stopgap: Modified eamio-icca for wavepass working with mag and slotted readers
The implementation emulates parts of the slotted and magnetic reader command flow to ensure that this implementation is working with games that only operate on slotted or magnetic card readers, e.g. iidx 9-18
This commit is contained in:
parent
f5c8ab6d77
commit
bdb11bb60c
@ -46,6 +46,13 @@ enum ac_io_icca_keypad_mask {
|
||||
AC_IO_ICCA_KEYPAD_MASK_8 = (1 << 15),
|
||||
};
|
||||
|
||||
enum ac_io_icca_status_code {
|
||||
AC_IO_ICCA_STATUS_FAULT = 0x00,
|
||||
AC_IO_ICCA_STATUS_IDLE = 0x01,
|
||||
AC_IO_ICCA_STATUS_GOT_UID = 0x02,
|
||||
AC_IO_ICCA_STATUS_IDLE_NEW = 0x04
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct ac_io_icca_misc {
|
||||
|
@ -29,13 +29,6 @@ enum ac_io_icca_flag {
|
||||
AC_IO_ICCA_FLAG_SOLENOID = 0x40
|
||||
};
|
||||
|
||||
enum ac_io_icca_status_code {
|
||||
AC_IO_ICCA_STATUS_FAULT = 0x00,
|
||||
AC_IO_ICCA_STATUS_IDLE = 0x01,
|
||||
AC_IO_ICCA_STATUS_GOT_UID = 0x02,
|
||||
AC_IO_ICCA_STATUS_IDLE_NEW = 0x04
|
||||
};
|
||||
|
||||
static void ac_io_emu_icca_cmd_send_version(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "acio/icca.h"
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/icca.h"
|
||||
|
||||
@ -32,7 +34,20 @@ static const uint8_t eam_io_keypad_mappings[16] = {EAM_IO_KEYPAD_DECIMAL,
|
||||
EAM_IO_KEYPAD_5,
|
||||
EAM_IO_KEYPAD_8};
|
||||
|
||||
// States to map slotted state machine to a slightly simplified
|
||||
// one that fits the states of the wavepass reader. Probably
|
||||
// the most important part is correct emulation of the slot
|
||||
// sensores to ensure the calling backend's states are set
|
||||
// correctly
|
||||
enum eam_io_icca_card_state {
|
||||
EAM_IO_ICCA_CARD_STATE_IDLE = 0,
|
||||
EAM_IO_ICCA_CARD_STATE_PROBE = 1,
|
||||
};
|
||||
|
||||
static struct ac_io_icca_state eam_io_icca_state[2];
|
||||
static enum eam_io_icca_card_state eam_io_icca_card_state[2];
|
||||
static bool eam_io_icca_card_data_avail[2];
|
||||
static uint8_t eam_io_icca_card_uid_buffer[2][8];
|
||||
|
||||
void eam_io_set_loggers(
|
||||
log_formatter_t misc,
|
||||
@ -56,8 +71,13 @@ bool eam_io_init(
|
||||
log_warning("Initializing icca %d failed", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
eam_io_icca_card_state[i] = EAM_IO_ICCA_CARD_STATE_IDLE;
|
||||
eam_io_icca_card_data_avail[i] = false;
|
||||
}
|
||||
|
||||
log_info("Initialized icca wavepass");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -85,12 +105,10 @@ uint8_t eam_io_get_sensor_state(uint8_t unit_no)
|
||||
{
|
||||
uint8_t sensors = 0;
|
||||
|
||||
if ((eam_io_icca_state[unit_no].sensor_state &
|
||||
AC_IO_ICCA_SENSOR_MASK_BACK_ON) > 0) {
|
||||
// when card data is available, signal this by telling the backend "card fully inserted"
|
||||
// also, keep card "inserted" as long as reading is in progress
|
||||
if (eam_io_icca_card_data_avail[unit_no]) {
|
||||
sensors |= (1 << EAM_IO_SENSOR_BACK);
|
||||
}
|
||||
if ((eam_io_icca_state[unit_no].sensor_state &
|
||||
AC_IO_ICCA_SENSOR_MASK_FRONT_ON) > 0) {
|
||||
sensors |= (1 << EAM_IO_SENSOR_FRONT);
|
||||
}
|
||||
|
||||
@ -99,11 +117,22 @@ uint8_t eam_io_get_sensor_state(uint8_t unit_no)
|
||||
|
||||
uint8_t eam_io_read_card(uint8_t unit_no, uint8_t *card_id, uint8_t nbytes)
|
||||
{
|
||||
memcpy(card_id, eam_io_icca_state[unit_no].uid, nbytes);
|
||||
if (card_id[0] == 0xe0 && card_id[1] == 0x04) {
|
||||
return EAM_IO_CARD_ISO15696;
|
||||
// report back with actual data read from card only if card read command
|
||||
// status reports back there is data
|
||||
if (eam_io_icca_card_data_avail[unit_no]) {
|
||||
memcpy(card_id, eam_io_icca_card_uid_buffer[unit_no], nbytes);
|
||||
|
||||
if (card_id[0] == 0xe0 && card_id[1] == 0x04) {
|
||||
return EAM_IO_CARD_ISO15696;
|
||||
} else {
|
||||
return EAM_IO_CARD_FELICA;
|
||||
}
|
||||
} else {
|
||||
return EAM_IO_CARD_FELICA;
|
||||
// Avoids garbage data reads for wavepass readers since these need to be
|
||||
// polled continuously for data
|
||||
memset(card_id, 0, nbytes);
|
||||
|
||||
return EAM_IO_CARD_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,20 +140,21 @@ bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case EAM_IO_CARD_SLOT_CMD_CLOSE:
|
||||
return aciodrv_icca_set_state(
|
||||
unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL);
|
||||
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_IDLE;
|
||||
return true;
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_OPEN:
|
||||
return aciodrv_icca_set_state(
|
||||
unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL);
|
||||
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_PROBE;
|
||||
|
||||
return true;
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_EJECT:
|
||||
return aciodrv_icca_set_state(
|
||||
unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL);
|
||||
eam_io_icca_card_data_avail[unit_no] = false;
|
||||
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_IDLE;
|
||||
return true;
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_READ:
|
||||
return aciodrv_icca_read_card(unit_no, NULL) &&
|
||||
aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -135,7 +165,35 @@ bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
|
||||
|
||||
bool eam_io_poll(uint8_t unit_no)
|
||||
{
|
||||
return aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]);
|
||||
// On idle, i.e. the game does not signal any interest in reading cards,
|
||||
// just to a standard poll to get the latest status of the readers
|
||||
if (eam_io_icca_card_state[unit_no] == EAM_IO_ICCA_CARD_STATE_IDLE) {
|
||||
return aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]);
|
||||
} else {
|
||||
// When either probing or reading the card, do actual reading by
|
||||
// continuously issueing the read command to either keep probing
|
||||
// for potential cards nearby or actually getting data from
|
||||
// detected cards back.
|
||||
if (aciodrv_icca_read_card(unit_no, NULL) &&
|
||||
aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no])) {
|
||||
|
||||
if (!eam_io_icca_card_data_avail[unit_no] &&
|
||||
eam_io_icca_state[unit_no].status_code == AC_IO_ICCA_STATUS_GOT_UID) {
|
||||
eam_io_icca_card_data_avail[unit_no] = true;
|
||||
|
||||
// tmp store read card id because stupid mag readers are sending open and close
|
||||
// commands all the time which makes creating a sane state machine impossible
|
||||
memcpy(
|
||||
eam_io_icca_card_uid_buffer[unit_no],
|
||||
eam_io_icca_state[unit_no].uid,
|
||||
sizeof(eam_io_icca_card_uid_buffer[unit_no]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct eam_io_config_api *eam_io_get_config_api(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user