mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-26 14:41:53 +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),
|
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)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
struct ac_io_icca_misc {
|
struct ac_io_icca_misc {
|
||||||
|
@ -29,13 +29,6 @@ enum ac_io_icca_flag {
|
|||||||
AC_IO_ICCA_FLAG_SOLENOID = 0x40
|
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(
|
static void ac_io_emu_icca_cmd_send_version(
|
||||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "acio/icca.h"
|
||||||
|
|
||||||
#include "aciodrv/device.h"
|
#include "aciodrv/device.h"
|
||||||
#include "aciodrv/icca.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_5,
|
||||||
EAM_IO_KEYPAD_8};
|
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 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(
|
void eam_io_set_loggers(
|
||||||
log_formatter_t misc,
|
log_formatter_t misc,
|
||||||
@ -56,8 +71,13 @@ bool eam_io_init(
|
|||||||
log_warning("Initializing icca %d failed", i);
|
log_warning("Initializing icca %d failed", i);
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +105,10 @@ uint8_t eam_io_get_sensor_state(uint8_t unit_no)
|
|||||||
{
|
{
|
||||||
uint8_t sensors = 0;
|
uint8_t sensors = 0;
|
||||||
|
|
||||||
if ((eam_io_icca_state[unit_no].sensor_state &
|
// when card data is available, signal this by telling the backend "card fully inserted"
|
||||||
AC_IO_ICCA_SENSOR_MASK_BACK_ON) > 0) {
|
// 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);
|
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);
|
sensors |= (1 << EAM_IO_SENSOR_FRONT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,32 +117,44 @@ 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)
|
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);
|
// 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) {
|
if (card_id[0] == 0xe0 && card_id[1] == 0x04) {
|
||||||
return EAM_IO_CARD_ISO15696;
|
return EAM_IO_CARD_ISO15696;
|
||||||
} else {
|
} else {
|
||||||
return EAM_IO_CARD_FELICA;
|
return EAM_IO_CARD_FELICA;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
|
bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case EAM_IO_CARD_SLOT_CMD_CLOSE:
|
case EAM_IO_CARD_SLOT_CMD_CLOSE:
|
||||||
return aciodrv_icca_set_state(
|
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_IDLE;
|
||||||
unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL);
|
return true;
|
||||||
|
|
||||||
case EAM_IO_CARD_SLOT_CMD_OPEN:
|
case EAM_IO_CARD_SLOT_CMD_OPEN:
|
||||||
return aciodrv_icca_set_state(
|
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_PROBE;
|
||||||
unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL);
|
|
||||||
|
return true;
|
||||||
|
|
||||||
case EAM_IO_CARD_SLOT_CMD_EJECT:
|
case EAM_IO_CARD_SLOT_CMD_EJECT:
|
||||||
return aciodrv_icca_set_state(
|
eam_io_icca_card_data_avail[unit_no] = false;
|
||||||
unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL);
|
eam_io_icca_card_state[unit_no] = EAM_IO_ICCA_CARD_STATE_IDLE;
|
||||||
|
return true;
|
||||||
|
|
||||||
case EAM_IO_CARD_SLOT_CMD_READ:
|
case EAM_IO_CARD_SLOT_CMD_READ:
|
||||||
return aciodrv_icca_read_card(unit_no, NULL) &&
|
return true;
|
||||||
aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
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)
|
bool eam_io_poll(uint8_t 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]);
|
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)
|
const struct eam_io_config_api *eam_io_get_config_api(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user