aimeio: Implement full aime reader function in aimeio (#94)

This PR implements the missing NFC, FeliCa, and Mifare command handlers in `aimeio`. This expands the reader's capability to support games and tools that utilize these specific radio functions.

**Changes:**
* Implemented NFC radio control functions.
* Added MIFARE and FeliCa command handling.
* Updated `aimeio` DLL exports and hook definitions.

**Testing Status:**
* I have verified the implementation using a virtual `aimeio` test environment, and the command handling works as expected.
   But I currently do not have access to a physical card reader, so haven't been able to verify the behavior on actual hardware yet.

Reviewed-on: https://gitea.tendokyu.moe/TeamTofuShop/segatools/pulls/94
Co-authored-by: グローランプ <130208311+Gl0w1amp@users.noreply.github.com>
Co-committed-by: グローランプ <130208311+Gl0w1amp@users.noreply.github.com>
This commit is contained in:
グローランプ
2026-02-08 11:01:01 +00:00
committed by Dniel97
parent 966eeeeb87
commit 21e5238b0a
23 changed files with 1103 additions and 17 deletions
+166
View File
@@ -27,6 +27,8 @@ static uint8_t aime_io_aime_id[10];
static uint8_t aime_io_felica_id[8];
static bool aime_io_aime_id_present;
static bool aime_io_felica_id_present;
static bool aime_io_radio_on = true;
static bool aime_io_update_mode;
static void aime_io_config_read(
struct aime_io_config *cfg,
@@ -244,6 +246,10 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
/* Don't do anything more if the scan key is not held */
if (!aime_io_radio_on) {
return S_OK;
}
sense = GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000;
if (!sense) {
@@ -349,6 +355,166 @@ HRESULT aime_io_nfc_get_felica_id(uint8_t unit_no, uint64_t *IDm)
return S_OK;
}
HRESULT aime_io_nfc_get_mifare_uid(
uint8_t unit_no,
uint8_t *uid,
size_t uid_size)
{
(void) uid;
(void) uid_size;
if (unit_no != 0 || !aime_io_aime_id_present) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_mifare_select(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size)
{
(void) uid;
(void) uid_size;
if (unit_no != 0) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_mifare_set_key(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *key,
size_t key_size)
{
(void) key_type;
(void) key;
(void) key_size;
if (unit_no != 0) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_mifare_authenticate(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *payload,
size_t payload_size)
{
(void) key_type;
(void) payload;
(void) payload_size;
if (unit_no != 0) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_mifare_read_block(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size)
{
(void) uid;
(void) uid_size;
(void) block_no;
(void) block;
(void) block_size;
if (unit_no != 0) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_felica_transact(
uint8_t unit_no,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written)
{
(void) req;
(void) req_size;
(void) res;
(void) res_size;
(void) res_size_written;
if (unit_no != 0) {
return S_FALSE;
}
return S_FALSE;
}
HRESULT aime_io_nfc_radio_on(uint8_t unit_no)
{
if (unit_no != 0) {
return S_FALSE;
}
aime_io_radio_on = true;
aime_io_update_mode = false;
return S_OK;
}
HRESULT aime_io_nfc_radio_off(uint8_t unit_no)
{
if (unit_no != 0) {
return S_FALSE;
}
aime_io_radio_on = false;
return S_OK;
}
HRESULT aime_io_nfc_to_update_mode(uint8_t unit_no)
{
if (unit_no != 0) {
return S_FALSE;
}
aime_io_update_mode = true;
return S_OK;
}
HRESULT aime_io_nfc_send_hex_data(
uint8_t unit_no,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out)
{
(void) payload;
(void) payload_size;
if (unit_no != 0) {
return S_FALSE;
}
if (status_out != NULL) {
*status_out = (payload_size == 0x2b) ? 0x20 : 0x00;
}
return S_OK;
}
void aime_io_led_set_color(uint8_t unit_no, uint8_t r, uint8_t g, uint8_t b)
{}
+134
View File
@@ -76,6 +76,140 @@ HRESULT aime_io_nfc_get_aime_id(
*/
HRESULT aime_io_nfc_get_felica_id(uint8_t unit_no, uint64_t *IDm);
/*
MIFARE key selector values used by the set key/authenticate functions.
Minimum API version: 0x0101
*/
enum {
AIME_IO_MIFARE_KEY_AIME = 0,
AIME_IO_MIFARE_KEY_BANA = 1,
};
/*
Attempt to read the 4-byte MIFARE UID of the currently present card.
Parameters:
- unit_no: Always 0 as of the current API version
- uid: Pointer to a four-byte buffer that will receive the UID
- uid_size: Size of the buffer at *uid. Always 4.
Returns:
- S_OK if a MIFARE card is present and the UID was read successfully
- S_FALSE if no MIFARE card is present (*uid will be ignored)
- Any HRESULT error if an error occured.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_get_mifare_uid(
uint8_t unit_no,
uint8_t *uid,
size_t uid_size);
/*
Select a MIFARE card by UID (optional for real readers).
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_mifare_select(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size);
/*
Supply a MIFARE authentication key to the reader.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_mifare_set_key(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *key,
size_t key_size);
/*
Perform a MIFARE authentication sequence.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_mifare_authenticate(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *payload,
size_t payload_size);
/*
Read a 16-byte MIFARE block from the card.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_mifare_read_block(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size);
/*
Forward a raw FeliCa request to a real reader.
Parameters:
- req: FeliCa request buffer, including the length byte
- res: FeliCa response buffer, including the length byte
- res_size_written: Output size of the response (bytes written to *res)
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_felica_transact(
uint8_t unit_no,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written);
/*
Enable the reader's RF field.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_radio_on(uint8_t unit_no);
/*
Disable the reader's RF field.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_radio_off(uint8_t unit_no);
/*
Put the reader into firmware update mode.
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_to_update_mode(uint8_t unit_no);
/*
Forward a raw hex-data command to the reader.
Parameters:
- payload: Command payload bytes
- payload_size: Size of the payload
- status_out: Optional pointer to receive the SG status byte
Minimum API version: 0x0101
*/
HRESULT aime_io_nfc_send_hex_data(
uint8_t unit_no,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out);
/*
Change the color and brightness of the card reader's RGB lighting
+31 -1
View File
@@ -10,7 +10,7 @@
enum {
AIME_DLL_SYM_COUNT_V100 = 5,
AIME_DLL_SYM_COUNT_V101 = 7,
AIME_DLL_SYM_COUNT_V101 = 17,
};
const struct dll_bind_sym aime_dll_syms[] = {
@@ -35,6 +35,36 @@ const struct dll_bind_sym aime_dll_syms[] = {
}, {
.sym = "aime_io_vfd_set_state",
.off = offsetof(struct aime_dll, vfd_set_state),
}, {
.sym = "aime_io_nfc_get_mifare_uid",
.off = offsetof(struct aime_dll, nfc_get_mifare_uid),
}, {
.sym = "aime_io_nfc_mifare_select",
.off = offsetof(struct aime_dll, nfc_mifare_select),
}, {
.sym = "aime_io_nfc_mifare_set_key",
.off = offsetof(struct aime_dll, nfc_mifare_set_key),
}, {
.sym = "aime_io_nfc_mifare_authenticate",
.off = offsetof(struct aime_dll, nfc_mifare_authenticate),
}, {
.sym = "aime_io_nfc_mifare_read_block",
.off = offsetof(struct aime_dll, nfc_mifare_read_block),
}, {
.sym = "aime_io_nfc_felica_transact",
.off = offsetof(struct aime_dll, nfc_felica_transact),
}, {
.sym = "aime_io_nfc_radio_on",
.off = offsetof(struct aime_dll, nfc_radio_on),
}, {
.sym = "aime_io_nfc_radio_off",
.off = offsetof(struct aime_dll, nfc_radio_off),
}, {
.sym = "aime_io_nfc_to_update_mode",
.off = offsetof(struct aime_dll, nfc_to_update_mode),
}, {
.sym = "aime_io_nfc_send_hex_data",
.off = offsetof(struct aime_dll, nfc_send_hex_data),
},
};
+40
View File
@@ -14,6 +14,46 @@ struct aime_dll {
uint8_t *luid,
size_t luid_size);
HRESULT (*nfc_get_felica_id)(uint8_t unit_no, uint64_t *IDm);
HRESULT (*nfc_get_mifare_uid)(
uint8_t unit_no,
uint8_t *uid,
size_t uid_size);
HRESULT (*nfc_mifare_select)(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size);
HRESULT (*nfc_mifare_set_key)(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *key,
size_t key_size);
HRESULT (*nfc_mifare_authenticate)(
uint8_t unit_no,
uint8_t key_type,
const uint8_t *payload,
size_t payload_size);
HRESULT (*nfc_mifare_read_block)(
uint8_t unit_no,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size);
HRESULT (*nfc_felica_transact)(
uint8_t unit_no,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written);
HRESULT (*nfc_radio_on)(uint8_t unit_no);
HRESULT (*nfc_radio_off)(uint8_t unit_no);
HRESULT (*nfc_to_update_mode)(uint8_t unit_no);
HRESULT (*nfc_send_hex_data)(
uint8_t unit_no,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out);
void (*led_set_color)(uint8_t unit_no, uint8_t r, uint8_t g, uint8_t b);
void (*vfd_set_text)(
const uint8_t *text,
+352 -16
View File
@@ -12,6 +12,8 @@
#include "board/sg-nfc.h"
#include "board/sg-nfc-cmd.h"
#include "aimeio/aimeio.h"
#include "iccard/aime.h"
#include "iccard/felica.h"
@@ -57,6 +59,38 @@ static HRESULT sg_nfc_cmd_mifare_read_block(
const struct sg_nfc_req_mifare_read_block *req,
struct sg_nfc_res_mifare_read_block *res);
static HRESULT sg_nfc_cmd_mifare_select(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res);
static HRESULT sg_nfc_cmd_mifare_set_key(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res,
uint8_t key_type);
static HRESULT sg_nfc_cmd_mifare_authenticate(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res,
uint8_t key_type);
static HRESULT sg_nfc_cmd_radio_on(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res);
static HRESULT sg_nfc_cmd_radio_off(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res);
static HRESULT sg_nfc_cmd_to_update_mode(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res);
static HRESULT sg_nfc_cmd_felica_encap(
struct sg_nfc *nfc,
const struct sg_nfc_req_felica_encap *req,
@@ -195,19 +229,49 @@ static HRESULT sg_nfc_dispatch(
&req->felica_encap,
&res->felica_encap);
case SG_NFC_CMD_MIFARE_SELECT_TAG:
return sg_nfc_cmd_mifare_select(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
return sg_nfc_cmd_mifare_set_key(
nfc,
&req->simple,
&res->simple,
AIME_IO_MIFARE_KEY_AIME);
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
return sg_nfc_cmd_mifare_set_key(
nfc,
&req->simple,
&res->simple,
AIME_IO_MIFARE_KEY_BANA);
case SG_NFC_CMD_MIFARE_AUTHENTICATE_AIME:
return sg_nfc_cmd_mifare_authenticate(
nfc,
&req->simple,
&res->simple,
AIME_IO_MIFARE_KEY_AIME);
case SG_NFC_CMD_MIFARE_AUTHENTICATE_BANA:
return sg_nfc_cmd_mifare_authenticate(
nfc,
&req->simple,
&res->simple,
AIME_IO_MIFARE_KEY_BANA);
case SG_NFC_CMD_RADIO_ON:
return sg_nfc_cmd_radio_on(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_RADIO_OFF:
return sg_nfc_cmd_radio_off(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_TO_UPDATE_MODE:
return sg_nfc_cmd_to_update_mode(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_SEND_HEX_DATA:
return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_MIFARE_SELECT_TAG:
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
case SG_NFC_CMD_RADIO_ON:
case SG_NFC_CMD_RADIO_OFF:
case SG_NFC_CMD_TO_UPDATE_MODE:
return sg_nfc_cmd_dummy(nfc, &req->simple, &res->simple);
default:
sg_nfc_dprintf(nfc, "Unimpl command %02x\n", req->simple.hdr.cmd);
@@ -300,7 +364,9 @@ static HRESULT sg_nfc_poll_aime(
struct sg_nfc *nfc,
struct sg_nfc_poll_mifare *mifare)
{
bool has_uid;
uint8_t luid[10];
uint8_t uid[4];
HRESULT hr;
/* Call backend */
@@ -317,12 +383,30 @@ static HRESULT sg_nfc_poll_aime(
sg_nfc_dprintf(nfc, "AiMe card is present\n");
/* Construct response (use an arbitrary UID) */
has_uid = false;
if (nfc->ops->get_mifare_uid != NULL) {
hr = nfc->ops->get_mifare_uid(nfc->ops_ctx, uid, sizeof(uid));
if (FAILED(hr)) {
return hr;
}
if (hr == S_OK) {
has_uid = true;
}
}
/* Construct response */
mifare->type = 0x10;
mifare->id_len = sizeof(mifare->uid);
// mifare->uid = _byteswap_ulong(0x8FBECBFF);
mifare->uid = _byteswap_ulong(0x01020304);
if (has_uid) {
memcpy(&mifare->uid, uid, sizeof(uid));
} else {
// mifare->uid = _byteswap_ulong(0x8FBECBFF);
mifare->uid = _byteswap_ulong(0x01020304);
}
/* Initialize MIFARE IC emulator */
@@ -372,11 +456,182 @@ static HRESULT sg_nfc_poll_felica(
return S_OK;
}
static HRESULT sg_nfc_cmd_mifare_select(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res)
{
const uint8_t *payload;
HRESULT hr;
if (req->payload_len != sizeof(uint32_t)) {
sg_nfc_dprintf(nfc, "%s: Payload size is incorrect\n", __func__);
return E_FAIL;
}
payload = (const uint8_t *) req + sizeof(*req);
if (nfc->ops->mifare_select != NULL) {
hr = nfc->ops->mifare_select(nfc->ops_ctx, payload, req->payload_len);
if (FAILED(hr)) {
return hr;
}
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_mifare_set_key(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res,
uint8_t key_type)
{
const uint8_t *payload;
HRESULT hr;
payload = (const uint8_t *) req + sizeof(*req);
if (nfc->ops->mifare_set_key != NULL) {
hr = nfc->ops->mifare_set_key(
nfc->ops_ctx,
key_type,
payload,
req->payload_len);
if (FAILED(hr)) {
return hr;
}
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_mifare_authenticate(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res,
uint8_t key_type)
{
const uint8_t *payload;
HRESULT hr;
payload = (const uint8_t *) req + sizeof(*req);
if (nfc->ops->mifare_authenticate != NULL) {
hr = nfc->ops->mifare_authenticate(
nfc->ops_ctx,
key_type,
payload,
req->payload_len);
if (FAILED(hr)) {
return hr;
}
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_radio_on(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res)
{
HRESULT hr;
if (nfc->ops->radio_on == NULL) {
sg_res_init(res, req, 0);
return S_OK;
}
hr = nfc->ops->radio_on(nfc->ops_ctx);
if (FAILED(hr)) {
return hr;
}
if (hr == S_FALSE) {
sg_res_init(res, req, 0);
return S_OK;
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_radio_off(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res)
{
HRESULT hr;
if (nfc->ops->radio_off == NULL) {
sg_res_init(res, req, 0);
return S_OK;
}
hr = nfc->ops->radio_off(nfc->ops_ctx);
if (FAILED(hr)) {
return hr;
}
if (hr == S_FALSE) {
sg_res_init(res, req, 0);
return S_OK;
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_to_update_mode(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res)
{
HRESULT hr;
if (nfc->ops->to_update_mode == NULL) {
sg_res_init(res, req, 0);
return S_OK;
}
hr = nfc->ops->to_update_mode(nfc->ops_ctx);
if (FAILED(hr)) {
return hr;
}
if (hr == S_FALSE) {
sg_res_init(res, req, 0);
return S_OK;
}
sg_res_init(res, req, 0);
return S_OK;
}
static HRESULT sg_nfc_cmd_mifare_read_block(
struct sg_nfc *nfc,
const struct sg_nfc_req_mifare_read_block *req,
struct sg_nfc_res_mifare_read_block *res)
{
const uint8_t *uid_bytes;
HRESULT hr;
uint32_t uid;
if (req->req.payload_len != sizeof(req->payload)) {
@@ -385,10 +640,30 @@ static HRESULT sg_nfc_cmd_mifare_read_block(
return E_FAIL;
}
uid_bytes = (const uint8_t *) &req->payload.uid;
uid = _byteswap_ulong(req->payload.uid);
sg_nfc_dprintf(nfc, "Read uid %08x block %i\n", uid, req->payload.block_no);
if (nfc->ops->mifare_read_block != NULL) {
hr = nfc->ops->mifare_read_block(
nfc->ops_ctx,
uid_bytes,
sizeof(req->payload.uid),
req->payload.block_no,
res->block,
sizeof(res->block));
if (FAILED(hr)) {
return hr;
}
if (hr == S_OK) {
sg_res_init(&res->res, &req->req, sizeof(res->block));
return S_OK;
}
}
if (req->payload.block_no > 14) {
sg_nfc_dprintf(nfc, "MIFARE block number out of range\n");
@@ -455,6 +730,7 @@ static HRESULT sg_nfc_cmd_felica_encap(
{
struct const_iobuf f_req;
struct iobuf f_res;
size_t res_size_written;
HRESULT hr;
/* First byte of encapsulated request and response is a length byte
@@ -472,6 +748,32 @@ static HRESULT sg_nfc_cmd_felica_encap(
return E_FAIL;
}
if (nfc->ops->felica_transact != NULL) {
res_size_written = 0;
hr = nfc->ops->felica_transact(
nfc->ops_ctx,
req->payload,
req->payload[0],
res->payload,
sizeof(res->payload),
&res_size_written);
if (FAILED(hr)) {
return hr;
}
if (hr == S_OK) {
if (res_size_written == 0 ||
res_size_written > sizeof(res->payload)) {
return E_FAIL;
}
sg_res_init(&res->res, &req->req, res_size_written);
return S_OK;
}
}
f_req.bytes = req->payload;
f_req.nbytes = req->payload[0];
f_req.pos = 1;
@@ -507,14 +809,48 @@ static HRESULT sg_nfc_cmd_send_hex_data(
const struct sg_req_header *req,
struct sg_res_header *res)
{
sg_res_init(res, req, 0);
const uint8_t *payload;
HRESULT hr;
uint8_t status;
/* Firmware checksum length? */
if (req->payload_len == 0x2b) {
/* The firmware is identical flag? */
res->status = 0x20;
if (nfc->ops->send_hex_data == NULL) {
sg_res_init(res, req, 0);
/* Firmware checksum length? */
if (req->payload_len == 0x2b) {
/* The firmware is identical flag? */
res->status = 0x20;
}
return S_OK;
}
payload = (const uint8_t *) req + sizeof(*req);
status = 0;
hr = nfc->ops->send_hex_data(
nfc->ops_ctx,
payload,
req->payload_len,
&status);
if (FAILED(hr)) {
return hr;
}
if (hr == S_FALSE) {
sg_res_init(res, req, 0);
if (req->payload_len == 0x2b) {
res->status = 0x20;
}
return S_OK;
}
sg_res_init(res, req, 0);
res->status = status;
return S_OK;
}
+34
View File
@@ -14,6 +14,40 @@ struct sg_nfc_ops {
HRESULT (*poll)(void *ctx);
HRESULT (*get_aime_id)(void *ctx, uint8_t *luid, size_t nbytes);
HRESULT (*get_felica_id)(void *ctx, uint64_t *IDm);
HRESULT (*get_mifare_uid)(void *ctx, uint8_t *uid, size_t nbytes);
HRESULT (*mifare_select)(void *ctx, const uint8_t *uid, size_t nbytes);
HRESULT (*mifare_set_key)(
void *ctx,
uint8_t key_type,
const uint8_t *key,
size_t nbytes);
HRESULT (*mifare_authenticate)(
void *ctx,
uint8_t key_type,
const uint8_t *payload,
size_t nbytes);
HRESULT (*mifare_read_block)(
void *ctx,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size);
HRESULT (*felica_transact)(
void *ctx,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written);
HRESULT (*radio_on)(void *ctx);
HRESULT (*radio_off)(void *ctx);
HRESULT (*to_update_mode)(void *ctx);
HRESULT (*send_hex_data)(
void *ctx,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out);
// TODO Banapass, AmuseIC
};
+186
View File
@@ -24,12 +24,62 @@ static HRESULT sg_reader_nfc_get_aime_id(
uint8_t *luid,
size_t luid_size);
static HRESULT sg_reader_nfc_get_felica_id(void *ctx, uint64_t *IDm);
static HRESULT sg_reader_nfc_get_mifare_uid(
void *ctx,
uint8_t *uid,
size_t uid_size);
static HRESULT sg_reader_nfc_mifare_select(
void *ctx,
const uint8_t *uid,
size_t uid_size);
static HRESULT sg_reader_nfc_mifare_set_key(
void *ctx,
uint8_t key_type,
const uint8_t *key,
size_t key_size);
static HRESULT sg_reader_nfc_mifare_authenticate(
void *ctx,
uint8_t key_type,
const uint8_t *payload,
size_t payload_size);
static HRESULT sg_reader_nfc_mifare_read_block(
void *ctx,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size);
static HRESULT sg_reader_nfc_felica_transact(
void *ctx,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written);
static HRESULT sg_reader_nfc_radio_on(void *ctx);
static HRESULT sg_reader_nfc_radio_off(void *ctx);
static HRESULT sg_reader_nfc_to_update_mode(void *ctx);
static HRESULT sg_reader_nfc_send_hex_data(
void *ctx,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out);
static void sg_reader_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b);
static const struct sg_nfc_ops sg_reader_nfc_ops = {
.poll = sg_reader_nfc_poll,
.get_aime_id = sg_reader_nfc_get_aime_id,
.get_felica_id = sg_reader_nfc_get_felica_id,
.get_mifare_uid = sg_reader_nfc_get_mifare_uid,
.mifare_select = sg_reader_nfc_mifare_select,
.mifare_set_key = sg_reader_nfc_mifare_set_key,
.mifare_authenticate = sg_reader_nfc_mifare_authenticate,
.mifare_read_block = sg_reader_nfc_mifare_read_block,
.felica_transact = sg_reader_nfc_felica_transact,
.radio_on = sg_reader_nfc_radio_on,
.radio_off = sg_reader_nfc_radio_off,
.to_update_mode = sg_reader_nfc_to_update_mode,
.send_hex_data = sg_reader_nfc_send_hex_data,
};
static const struct sg_led_ops sg_reader_led_ops = {
@@ -201,6 +251,142 @@ static HRESULT sg_reader_nfc_get_felica_id(void *ctx, uint64_t *IDm)
return aime_dll.nfc_get_felica_id(0, IDm);
}
static HRESULT sg_reader_nfc_get_mifare_uid(
void *ctx,
uint8_t *uid,
size_t uid_size)
{
if (aime_dll.nfc_get_mifare_uid == NULL) {
return S_FALSE;
}
return aime_dll.nfc_get_mifare_uid(0, uid, uid_size);
}
static HRESULT sg_reader_nfc_mifare_select(
void *ctx,
const uint8_t *uid,
size_t uid_size)
{
if (aime_dll.nfc_mifare_select == NULL) {
return S_FALSE;
}
return aime_dll.nfc_mifare_select(0, uid, uid_size);
}
static HRESULT sg_reader_nfc_mifare_set_key(
void *ctx,
uint8_t key_type,
const uint8_t *key,
size_t key_size)
{
if (aime_dll.nfc_mifare_set_key == NULL) {
return S_FALSE;
}
return aime_dll.nfc_mifare_set_key(0, key_type, key, key_size);
}
static HRESULT sg_reader_nfc_mifare_authenticate(
void *ctx,
uint8_t key_type,
const uint8_t *payload,
size_t payload_size)
{
if (aime_dll.nfc_mifare_authenticate == NULL) {
return S_FALSE;
}
return aime_dll.nfc_mifare_authenticate(
0,
key_type,
payload,
payload_size);
}
static HRESULT sg_reader_nfc_mifare_read_block(
void *ctx,
const uint8_t *uid,
size_t uid_size,
uint8_t block_no,
uint8_t *block,
size_t block_size)
{
if (aime_dll.nfc_mifare_read_block == NULL) {
return S_FALSE;
}
return aime_dll.nfc_mifare_read_block(
0,
uid,
uid_size,
block_no,
block,
block_size);
}
static HRESULT sg_reader_nfc_felica_transact(
void *ctx,
const uint8_t *req,
size_t req_size,
uint8_t *res,
size_t res_size,
size_t *res_size_written)
{
if (aime_dll.nfc_felica_transact == NULL) {
return S_FALSE;
}
return aime_dll.nfc_felica_transact(
0,
req,
req_size,
res,
res_size,
res_size_written);
}
static HRESULT sg_reader_nfc_radio_on(void *ctx)
{
if (aime_dll.nfc_radio_on == NULL) {
return S_FALSE;
}
return aime_dll.nfc_radio_on(0);
}
static HRESULT sg_reader_nfc_radio_off(void *ctx)
{
if (aime_dll.nfc_radio_off == NULL) {
return S_FALSE;
}
return aime_dll.nfc_radio_off(0);
}
static HRESULT sg_reader_nfc_to_update_mode(void *ctx)
{
if (aime_dll.nfc_to_update_mode == NULL) {
return S_FALSE;
}
return aime_dll.nfc_to_update_mode(0);
}
static HRESULT sg_reader_nfc_send_hex_data(
void *ctx,
const uint8_t *payload,
size_t payload_size,
uint8_t *status_out)
{
if (aime_dll.nfc_send_hex_data == NULL) {
return S_FALSE;
}
return aime_dll.nfc_send_hex_data(0, payload, payload_size, status_out);
}
static void sg_reader_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b)
{
aime_dll.led_set_color(0, r, g, b);
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -10,6 +10,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -10,6 +10,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -10,6 +10,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -14,6 +14,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -15,6 +15,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
+10
View File
@@ -9,6 +9,16 @@ EXPORTS
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
aime_io_nfc_get_mifare_uid
aime_io_nfc_mifare_select
aime_io_nfc_mifare_set_key
aime_io_nfc_mifare_authenticate
aime_io_nfc_mifare_read_block
aime_io_nfc_felica_transact
aime_io_nfc_radio_on
aime_io_nfc_radio_off
aime_io_nfc_to_update_mode
aime_io_nfc_send_hex_data
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1