mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-17 19:19:16 +01:00
aciodrv: Add wavepass support to ICCA (#1)
Tested with: aciotest / eamiotest: - DDR Slotted: Node 1: type 3, flag 0, version 1.1.0, product ICCA, build date: Oct 26 2005 13:55:03 - DDR Slotted: Node 2: type 3, flag 0, version 1.1.0, product ICCA, build date: Oct 26 2005 13:55:03 (tested with just 1, as well as a pair) aciotest / eamiotest / IIDX10,12,27: - IIDX Wavepass: Node 1: type 3, flag 0, version 1.5.1, product ICCB, build date: Apr 12 2010 09:29:00 - IIDX Wavepass: Node 2: type 3, flag 0, version 1.5.1, product ICCB, build date: Apr 12 2010 09:29:00 (IIDX13 errors on card-in, probably issue with how eamio is being used as previously eamio-icca had no use on it) aciotest / eamiotest / sdvx1-5: - SDVX Wavepass: Node 1: type 3, flag 0, version 1.5.1, product ICCB, build date: Apr 12 2010 09:29:00 aciotest: - Jubeat Wavepass: Node 1: type 3, flag 0, version 1.7.3, product ICCC, build date: Oct 05 2012 20:26:53 - Museca Wavepass: Node 2: type 3, flag 0, version 1.7.4, product ICCC, build date: Feb 27 2013 16:44:51
This commit is contained in:
parent
609c19b0ca
commit
f9b37c7a72
@ -29,6 +29,14 @@ enum ac_io_icca_sensor_state {
|
||||
AC_IO_ICCA_SENSOR_MASK_BACK_ON = (1 << 5)
|
||||
};
|
||||
|
||||
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,
|
||||
AC_IO_ICCA_STATUS_BUSY_NEW = 0x01,
|
||||
};
|
||||
|
||||
enum ac_io_icca_keypad_mask {
|
||||
AC_IO_ICCA_KEYPAD_MASK_EMPTY = (1 << 0),
|
||||
AC_IO_ICCA_KEYPAD_MASK_3 = (1 << 1),
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
struct aciodrv_device_ctx {
|
||||
HANDLE fd;
|
||||
char node_products[ACIO_MAX_NODES_PER_PORT][ACIO_NODE_PRODUCT_CODE_LEN];
|
||||
struct aciodrv_device_node_version node_versions[ACIO_MAX_NODES_PER_PORT];
|
||||
uint8_t msg_counter;
|
||||
uint8_t node_count;
|
||||
};
|
||||
@ -233,7 +233,7 @@ static uint8_t aciodrv_device_enum_nodes(struct aciodrv_device_ctx *device)
|
||||
return msg.cmd.count;
|
||||
}
|
||||
|
||||
static bool aciodrv_device_get_version(struct aciodrv_device_ctx *device, uint8_t node_id, char product[4])
|
||||
static bool aciodrv_device_get_version(struct aciodrv_device_ctx *device, uint8_t node_id, struct aciodrv_device_node_version *version)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
@ -266,7 +266,10 @@ static bool aciodrv_device_get_version(struct aciodrv_device_ctx *device, uint8_
|
||||
msg.cmd.version.date,
|
||||
msg.cmd.version.time);
|
||||
|
||||
memcpy(product, msg.cmd.version.product_code, 4);
|
||||
memcpy(version->product, msg.cmd.version.product_code, ACIO_NODE_PRODUCT_CODE_LEN);
|
||||
version->major = msg.cmd.version.major;
|
||||
version->minor = msg.cmd.version.minor;
|
||||
version->revision = msg.cmd.version.revision;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -325,7 +328,7 @@ struct aciodrv_device_ctx *aciodrv_device_open_path(const char *port_path, int b
|
||||
|
||||
for (uint8_t i = 0; i < device->node_count; i++) {
|
||||
if (!aciodrv_device_get_version(
|
||||
device, i + 1, device->node_products[i])) {
|
||||
device, i + 1, &device->node_versions[i])) {
|
||||
aciodrv_device_close(device);
|
||||
return NULL;
|
||||
}
|
||||
@ -353,10 +356,19 @@ bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx *device, ui
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(product, device->node_products[node_id], ACIO_NODE_PRODUCT_CODE_LEN);
|
||||
memcpy(product, device->node_versions[node_id].product, ACIO_NODE_PRODUCT_CODE_LEN);
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct aciodrv_device_node_version *aciodrv_device_get_node_product_version(struct aciodrv_device_ctx *device, uint8_t node_id)
|
||||
{
|
||||
if (device->node_count == 0 || node_id > device->node_count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &device->node_versions[node_id];
|
||||
}
|
||||
|
||||
bool aciodrv_send_and_recv(struct aciodrv_device_ctx *device, struct ac_io_message *msg, int max_resp_size)
|
||||
{
|
||||
msg->cmd.seq_no = device->msg_counter++;
|
||||
|
@ -11,6 +11,13 @@
|
||||
|
||||
struct aciodrv_device_ctx;
|
||||
|
||||
struct aciodrv_device_node_version {
|
||||
char product[ACIO_NODE_PRODUCT_CODE_LEN];
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t revision;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open an ACIO device connected to a serial port.
|
||||
*
|
||||
@ -45,6 +52,15 @@ uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx *device);
|
||||
*/
|
||||
bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx *device, uint8_t node_id, char product[ACIO_NODE_PRODUCT_CODE_LEN]);
|
||||
|
||||
/**
|
||||
* Get the product version of an enumerated node.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node. Needs to be in range of the total node count.
|
||||
* @return Pointer to the version struct
|
||||
*/
|
||||
const struct aciodrv_device_node_version *aciodrv_device_get_node_product_version(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Send a message to the ACIO bus and receive an answer.
|
||||
* Use this to implement the protocol for each type of device that can be
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/icca.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
@ -134,4 +135,53 @@ bool aciodrv_icca_read_card(
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool aciodrv_icca_is_slotted(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
struct aciodrv_device_node_version *version;
|
||||
version = aciodrv_device_get_node_product_version(device, node_id);
|
||||
|
||||
// current heuristic is to check if version >= 1.5
|
||||
if (version) {
|
||||
if (version->major == 1) {
|
||||
if (version->minor >= 5) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_icca_poll_felica(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_POLL_FELICA);
|
||||
msg.cmd.nbytes = 4;
|
||||
/* buffer size of data we expect */
|
||||
msg.cmd.count = 1;
|
||||
|
||||
// additional data, not sure
|
||||
msg.cmd.raw[1] = 0x03;
|
||||
msg.cmd.raw[2] = 0xFF;
|
||||
msg.cmd.raw[3] = 0xFF;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
log_warning("Reading card of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -71,4 +71,41 @@ bool aciodrv_icca_read_card(
|
||||
uint8_t node_id,
|
||||
struct ac_io_icca_state *state);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Uses some heruistics based on the product ident to determine if the detected
|
||||
* device is a slotted (true) or wavepass reader (false).
|
||||
*
|
||||
* This function will also return false if the provided node_id is invalid.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @return True on slotted, false on wavepass.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_is_slotted(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Polls the felica chip on wavepass readers. This will cause the state of the
|
||||
* reader to be AC_IO_ICCA_STATUS_BUSY_NEW for a few polls, before returning
|
||||
* either: AC_IO_ICCA_STATUS_IDLE_NEW or AC_IO_ICCA_STATUS_GOT_UID.
|
||||
*
|
||||
* The user should take care to call this every so often to actually get new
|
||||
* felica UIDs, instead of just old NFC idents. The game seems to do it every
|
||||
* 5 or so polls after the last AC_IO_ICCA_STATUS_BUSY_NEW poll.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @return True on success, false on error.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_poll_felica(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id);
|
||||
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
||||
|
@ -5,11 +5,25 @@
|
||||
|
||||
#include "aciodrv/icca.h"
|
||||
|
||||
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(uint32_t));
|
||||
*((uint32_t *) *ctx) = 0;
|
||||
*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);
|
||||
}
|
||||
@ -17,13 +31,17 @@ bool aciotest_icca_handler_init(
|
||||
bool aciotest_icca_handler_update(
|
||||
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx)
|
||||
{
|
||||
if (*((uint32_t *) ctx) == 0) {
|
||||
*((uint32_t *) ctx) = 1;
|
||||
struct icca_handler_ctx *icca_ctx = (struct icca_handler_ctx*)ctx;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,33 +78,48 @@ bool aciotest_icca_handler_update(
|
||||
state.key_events[0],
|
||||
state.key_events[1]);
|
||||
|
||||
/* 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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aciodrv_icca_read_card(device, node_id, 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 >= 5) {
|
||||
if (!aciodrv_icca_poll_felica(device, node_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
icca_ctx->last_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "aciomgr/manager.h"
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/icca.h"
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
@ -44,6 +45,10 @@ static struct aciomgr_port_dispatcher *acio_manager_ctx;
|
||||
|
||||
static int32_t icca_node_id[NUMBER_OF_EMULATED_READERS];
|
||||
|
||||
static bool icca_is_slotted[NUMBER_OF_EMULATED_READERS];
|
||||
|
||||
static int32_t icca_poll_counter[NUMBER_OF_EMULATED_READERS];
|
||||
|
||||
void eam_io_set_loggers(
|
||||
log_formatter_t misc,
|
||||
log_formatter_t info,
|
||||
@ -103,7 +108,7 @@ bool eam_io_init(
|
||||
acio_manager_ctx = aciomgr_port_init(config_icc.port, config_icc.baud);
|
||||
|
||||
if (acio_manager_ctx == NULL) {
|
||||
log_warning("Opening acio device on COM1 failed");
|
||||
log_warning("Opening acio device on %s failed", config_icc.port);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -129,15 +134,15 @@ bool eam_io_init(
|
||||
|
||||
icca_node_id[i] = nid;
|
||||
|
||||
icca_is_slotted[i] = true;
|
||||
icca_poll_counter[i] = 0;
|
||||
|
||||
icca_is_slotted[i] = aciodrv_icca_is_slotted(device, nid);
|
||||
|
||||
if (!aciodrv_icca_init(device, icca_node_id[i])) {
|
||||
log_warning("Initializing icca %d failed", i);
|
||||
|
||||
// if we have at least 1 valid reader, don't fail
|
||||
// (ex: for games that expect only 1 reader)
|
||||
if (i > 0) {
|
||||
aciomgr_port_checkin(acio_manager_ctx);
|
||||
return false;
|
||||
}
|
||||
icca_node_id[i] = INVALID_NODE_ID;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -145,6 +150,11 @@ bool eam_io_init(
|
||||
}
|
||||
}
|
||||
|
||||
if (icca_node_id[0] == INVALID_NODE_ID) {
|
||||
log_warning("No ICC readers detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
aciomgr_port_checkin(acio_manager_ctx);
|
||||
return true;
|
||||
}
|
||||
@ -173,13 +183,24 @@ 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) {
|
||||
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);
|
||||
if (icca_is_slotted[unit_no]) {
|
||||
if ((eam_io_icca_state[unit_no].sensor_state &
|
||||
AC_IO_ICCA_SENSOR_MASK_BACK_ON) > 0) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
// wavepass readers always report (EAM_IO_SENSOR_BACK + EAM_IO_SENSOR_FRONT) + type
|
||||
// but because we can't report status_code back directly
|
||||
// and libacio actually just ignores the sensor_state other then the type
|
||||
// we just return this state like we're a slotted reader so the emulation takes card of it
|
||||
if (eam_io_icca_state[unit_no].status_code == AC_IO_ICCA_STATUS_GOT_UID) {
|
||||
sensors |= (1 << EAM_IO_SENSOR_BACK);
|
||||
sensors |= (1 << EAM_IO_SENSOR_FRONT);
|
||||
}
|
||||
}
|
||||
|
||||
return sensors;
|
||||
@ -202,26 +223,31 @@ bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
// ignore these for wavepass
|
||||
if (!icca_is_slotted[unit_no]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct aciodrv_device_ctx *device = aciomgr_port_checkout(acio_manager_ctx);
|
||||
|
||||
bool response = false;
|
||||
switch (cmd) {
|
||||
case EAM_IO_CARD_SLOT_CMD_CLOSE:
|
||||
response = aciodrv_icca_set_state(
|
||||
device, unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL);
|
||||
device, icca_node_id[unit_no], AC_IO_ICCA_SLOT_STATE_CLOSE, NULL);
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_OPEN:
|
||||
response = aciodrv_icca_set_state(
|
||||
device, unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL);
|
||||
device, icca_node_id[unit_no], AC_IO_ICCA_SLOT_STATE_OPEN, NULL);
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_EJECT:
|
||||
response = aciodrv_icca_set_state(
|
||||
device, unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL);
|
||||
device, icca_node_id[unit_no], AC_IO_ICCA_SLOT_STATE_EJECT, NULL);
|
||||
|
||||
case EAM_IO_CARD_SLOT_CMD_READ:
|
||||
response = aciodrv_icca_read_card(device, unit_no, NULL) &&
|
||||
response = aciodrv_icca_read_card(device, icca_node_id[unit_no], NULL) &&
|
||||
aciodrv_icca_get_state(
|
||||
device, unit_no, &eam_io_icca_state[unit_no]);
|
||||
device, icca_node_id[unit_no], &eam_io_icca_state[unit_no]);
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -240,10 +266,29 @@ bool eam_io_poll(uint8_t unit_no)
|
||||
|
||||
bool response = aciodrv_icca_get_state(
|
||||
aciomgr_port_checkout(acio_manager_ctx),
|
||||
unit_no,
|
||||
icca_node_id[unit_no],
|
||||
&eam_io_icca_state[unit_no]);
|
||||
aciomgr_port_checkin(acio_manager_ctx);
|
||||
|
||||
if (response && !icca_is_slotted[unit_no]) {
|
||||
// we handle wavepass a bit differently to handle polling felica
|
||||
if (eam_io_icca_state[unit_no].status_code != AC_IO_ICCA_STATUS_BUSY_NEW) {
|
||||
++icca_poll_counter[unit_no];
|
||||
}
|
||||
|
||||
// we must manually call this every few polls to actually update the felica state
|
||||
// we don't do it every poll, since card polling isn't that time sensitive of an operation
|
||||
// libacio does it every 5ish polls after the last AC_IO_ICCA_STATUS_BUSY_NEW message
|
||||
if (icca_poll_counter[unit_no] >= 5) {
|
||||
response = aciodrv_icca_poll_felica(
|
||||
aciomgr_port_checkout(acio_manager_ctx),
|
||||
icca_node_id[unit_no]);
|
||||
aciomgr_port_checkin(acio_manager_ctx);
|
||||
|
||||
icca_poll_counter[unit_no] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user