forked from Hay1tsme/segatools
Overhaul card reader emulation
This commit is contained in:
@ -6,6 +6,9 @@ board_lib = static_library(
|
||||
dependencies : [
|
||||
capnhook.get_variable('hook_dep'),
|
||||
],
|
||||
link_with : [
|
||||
iccard_lib,
|
||||
],
|
||||
sources : [
|
||||
'config.c',
|
||||
'config.h',
|
||||
|
@ -2,18 +2,21 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
enum {
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,
|
||||
SG_NFC_CMD_40_POLL = 0x40,
|
||||
SG_NFC_CMD_41_POLL = 0x41,
|
||||
SG_NFC_CMD_MIFARE_POLL = 0x42,
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_50 = 0x50,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY = 0x54,
|
||||
SG_NFC_CMD_MIFARE_55 = 0x55,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */
|
||||
SG_NFC_CMD_RESET = 0x62,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
};
|
||||
|
||||
struct sg_nfc_resp_get_fw_version {
|
||||
@ -41,23 +44,34 @@ struct sg_nfc_req_poll_40 {
|
||||
uint8_t payload;
|
||||
};
|
||||
|
||||
struct sg_nfc_resp_mifare_poll {
|
||||
struct sg_nfc_poll_mifare {
|
||||
uint8_t type;
|
||||
uint8_t id_len;
|
||||
uint32_t uid;
|
||||
};
|
||||
|
||||
struct sg_nfc_poll_felica {
|
||||
uint8_t type;
|
||||
uint8_t id_len;
|
||||
uint64_t IDm;
|
||||
uint64_t PMm;
|
||||
};
|
||||
|
||||
struct sg_nfc_resp_poll {
|
||||
struct sg_resp_header resp;
|
||||
union {
|
||||
uint8_t none;
|
||||
uint8_t some[7];
|
||||
} payload;
|
||||
uint8_t count;
|
||||
uint8_t payload[250];
|
||||
};
|
||||
|
||||
struct sg_nfc_req_mifare_select_tag {
|
||||
struct sg_resp_header resp;
|
||||
uint8_t uid[4];
|
||||
uint32_t uid;
|
||||
};
|
||||
|
||||
struct sg_nfc_req_mifare_read_block {
|
||||
struct sg_req_header req;
|
||||
struct {
|
||||
uint8_t uid[4];
|
||||
uint32_t uid;
|
||||
uint8_t block_no;
|
||||
} payload;
|
||||
};
|
||||
@ -67,6 +81,17 @@ struct sg_nfc_resp_mifare_read_block {
|
||||
uint8_t block[16];
|
||||
};
|
||||
|
||||
struct sg_nfc_req_felica_encap {
|
||||
struct sg_req_header req;
|
||||
uint64_t IDm;
|
||||
uint8_t payload[243];
|
||||
};
|
||||
|
||||
struct sg_nfc_resp_felica_encap {
|
||||
struct sg_resp_header resp;
|
||||
uint8_t payload[250];
|
||||
};
|
||||
|
||||
union sg_nfc_req_any {
|
||||
uint8_t bytes[256];
|
||||
struct sg_req_header simple;
|
||||
@ -74,6 +99,7 @@ union sg_nfc_req_any {
|
||||
struct sg_nfc_req_mifare_read_block mifare_read_block;
|
||||
struct sg_nfc_req_mifare_50 mifare_50;
|
||||
struct sg_nfc_req_poll_40 poll_40;
|
||||
struct sg_nfc_req_felica_encap felica_encap;
|
||||
};
|
||||
|
||||
union sg_nfc_resp_any {
|
||||
@ -81,6 +107,9 @@ union sg_nfc_resp_any {
|
||||
struct sg_resp_header simple;
|
||||
struct sg_nfc_resp_get_fw_version get_fw_version;
|
||||
struct sg_nfc_resp_get_hw_version get_hw_version;
|
||||
struct sg_nfc_resp_mifare_poll mifare_poll;
|
||||
struct sg_nfc_resp_poll poll;
|
||||
struct sg_nfc_resp_mifare_read_block mifare_read_block;
|
||||
struct sg_nfc_resp_felica_encap felica_encap;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
319
board/sg-nfc.c
319
board/sg-nfc.c
@ -4,13 +4,18 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/sg-cmd.h"
|
||||
#include "board/sg-nfc.h"
|
||||
#include "board/sg-nfc-cmd.h"
|
||||
|
||||
#include "iccard/aime.h"
|
||||
#include "iccard/felica.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
static HRESULT sg_nfc_dispatch(
|
||||
void *ctx,
|
||||
@ -18,50 +23,48 @@ static HRESULT sg_nfc_dispatch(
|
||||
void *v_resp);
|
||||
|
||||
static HRESULT sg_nfc_cmd_reset(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_resp_header *resp);
|
||||
|
||||
static HRESULT sg_nfc_cmd_get_fw_version(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_get_fw_version *resp);
|
||||
|
||||
static HRESULT sg_nfc_cmd_get_hw_version(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_get_hw_version *resp);
|
||||
|
||||
static HRESULT sg_nfc_cmd_mifare_poll(
|
||||
const struct sg_nfc *nfc,
|
||||
static HRESULT sg_nfc_cmd_poll(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_mifare_poll *resp);
|
||||
struct sg_nfc_resp_poll *resp);
|
||||
|
||||
static HRESULT sg_nfc_poll_aime(
|
||||
struct sg_nfc *nfc,
|
||||
struct sg_nfc_poll_mifare *mifare);
|
||||
|
||||
static HRESULT sg_nfc_poll_felica(
|
||||
struct sg_nfc *nfc,
|
||||
struct sg_nfc_poll_felica *felica);
|
||||
|
||||
static HRESULT sg_nfc_cmd_mifare_read_block(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_nfc_req_mifare_read_block *req,
|
||||
struct sg_nfc_resp_mifare_read_block *resp);
|
||||
|
||||
static HRESULT sg_nfc_mifare_read_block_1(
|
||||
const struct sg_nfc *nfc,
|
||||
uint32_t uid,
|
||||
uint8_t *block);
|
||||
|
||||
static HRESULT sg_nfc_mifare_read_block_2(
|
||||
const struct sg_nfc *nfc,
|
||||
uint32_t uid,
|
||||
uint8_t *block);
|
||||
static HRESULT sg_nfc_cmd_felica_encap(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_nfc_req_felica_encap *req,
|
||||
struct sg_nfc_resp_felica_encap *resp);
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_resp_header *resp);
|
||||
|
||||
static const uint8_t sg_nfc_block_1[] = {
|
||||
'S', 'B', 'D', 'T', 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xC6, 0x22,
|
||||
};
|
||||
|
||||
void sg_nfc_init(
|
||||
struct sg_nfc *nfc,
|
||||
uint8_t addr,
|
||||
@ -120,7 +123,7 @@ static HRESULT sg_nfc_dispatch(
|
||||
const void *v_req,
|
||||
void *v_resp)
|
||||
{
|
||||
const struct sg_nfc *nfc;
|
||||
struct sg_nfc *nfc;
|
||||
const union sg_nfc_req_any *req;
|
||||
union sg_nfc_resp_any *resp;
|
||||
|
||||
@ -149,11 +152,11 @@ static HRESULT sg_nfc_dispatch(
|
||||
&req->simple,
|
||||
&resp->get_hw_version);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_POLL:
|
||||
return sg_nfc_cmd_mifare_poll(
|
||||
case SG_NFC_CMD_POLL:
|
||||
return sg_nfc_cmd_poll(
|
||||
nfc,
|
||||
&req->simple,
|
||||
&resp->mifare_poll);
|
||||
&resp->poll);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_READ_BLOCK:
|
||||
return sg_nfc_cmd_mifare_read_block(
|
||||
@ -161,12 +164,18 @@ static HRESULT sg_nfc_dispatch(
|
||||
&req->mifare_read_block,
|
||||
&resp->mifare_read_block);
|
||||
|
||||
case SG_NFC_CMD_40_POLL:
|
||||
case SG_NFC_CMD_41_POLL:
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY:
|
||||
case SG_NFC_CMD_FELICA_ENCAP:
|
||||
return sg_nfc_cmd_felica_encap(
|
||||
nfc,
|
||||
&req->felica_encap,
|
||||
&resp->felica_encap);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE:
|
||||
case SG_NFC_CMD_MIFARE_SELECT_TAG:
|
||||
case SG_NFC_CMD_MIFARE_50:
|
||||
case SG_NFC_CMD_MIFARE_55:
|
||||
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:
|
||||
return sg_nfc_cmd_dummy(nfc, &req->simple, &resp->simple);
|
||||
|
||||
default:
|
||||
@ -177,7 +186,7 @@ static HRESULT sg_nfc_dispatch(
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_reset(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_resp_header *resp)
|
||||
{
|
||||
@ -189,7 +198,7 @@ static HRESULT sg_nfc_cmd_reset(
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_get_fw_version(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_get_fw_version *resp)
|
||||
{
|
||||
@ -201,7 +210,7 @@ static HRESULT sg_nfc_cmd_get_fw_version(
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_get_hw_version(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_get_hw_version *resp)
|
||||
{
|
||||
@ -212,54 +221,124 @@ static HRESULT sg_nfc_cmd_get_hw_version(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_mifare_poll(
|
||||
const struct sg_nfc *nfc,
|
||||
static HRESULT sg_nfc_cmd_poll(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_resp_mifare_poll *resp)
|
||||
struct sg_nfc_resp_poll *resp)
|
||||
{
|
||||
uint32_t uid;
|
||||
struct sg_nfc_poll_mifare mifare;
|
||||
struct sg_nfc_poll_felica felica;
|
||||
HRESULT hr;
|
||||
|
||||
uid = 0;
|
||||
hr = nfc->ops->mifare_poll(nfc->ops_ctx, &uid);
|
||||
|
||||
if (hr == S_OK) {
|
||||
if (uid == 0 || uid == -1) {
|
||||
sg_nfc_dprintf(nfc, "nfc->ops->mifare_poll returned bad uid\n");
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
sg_nfc_dprintf(nfc, "Mifare card is present\n");
|
||||
|
||||
sg_resp_init(&resp->resp, req, sizeof(resp->payload.some));
|
||||
resp->payload.some[0] = 0x01; /* Chunk size? */
|
||||
resp->payload.some[1] = 0x10; /* Unknown */
|
||||
resp->payload.some[2] = 0x04; /* Chunk size? */
|
||||
resp->payload.some[3] = uid >> 24; /* UID byte 0 */
|
||||
resp->payload.some[4] = uid >> 16; /* UID byte 1 */
|
||||
resp->payload.some[5] = uid >> 8; /* UID byte 2 */
|
||||
resp->payload.some[6] = uid ; /* UID byte 3 */
|
||||
|
||||
return S_OK;
|
||||
} else if (hr == S_FALSE) {
|
||||
sg_resp_init(&resp->resp, req, sizeof(resp->payload.none));
|
||||
resp->payload.none = 0x00;
|
||||
|
||||
return S_OK;
|
||||
} else if (FAILED(hr)) {
|
||||
sg_nfc_dprintf(nfc, "nfc->ops->mifare_poll error: %x\n", (int) hr);
|
||||
hr = nfc->ops->poll(nfc->ops_ctx);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
} else {
|
||||
sg_nfc_dprintf(nfc, "nfc->ops->mifare_poll bad return: %x\n", (int) hr);
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
hr = sg_nfc_poll_felica(nfc, &felica);
|
||||
|
||||
if (SUCCEEDED(hr) && hr != S_FALSE) {
|
||||
sg_resp_init(&resp->resp, req, 1 + sizeof(felica));
|
||||
memcpy(resp->payload, &felica, sizeof(felica));
|
||||
resp->count = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hr = sg_nfc_poll_aime(nfc, &mifare);
|
||||
|
||||
if (SUCCEEDED(hr) && hr != S_FALSE) {
|
||||
sg_resp_init(&resp->resp, req, 1 + sizeof(mifare));
|
||||
memcpy(resp->payload, &mifare, sizeof(mifare));
|
||||
resp->count = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
sg_resp_init(&resp->resp, req, 1);
|
||||
resp->count = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_poll_aime(
|
||||
struct sg_nfc *nfc,
|
||||
struct sg_nfc_poll_mifare *mifare)
|
||||
{
|
||||
uint8_t luid[10];
|
||||
HRESULT hr;
|
||||
|
||||
/* Call backend */
|
||||
|
||||
if (nfc->ops->get_aime_id != NULL) {
|
||||
hr = nfc->ops->get_aime_id(nfc->ops_ctx, luid, sizeof(luid));
|
||||
} else {
|
||||
hr = S_FALSE;
|
||||
}
|
||||
|
||||
if (FAILED(hr) || hr == S_FALSE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
sg_nfc_dprintf(nfc, "AiMe card is present\n");
|
||||
|
||||
/* Construct response (use an arbitrary UID) */
|
||||
|
||||
mifare->type = 0x10;
|
||||
mifare->id_len = sizeof(mifare->uid);
|
||||
mifare->uid = _byteswap_ulong(0x01020304);
|
||||
|
||||
/* Initialize MIFARE IC emulator */
|
||||
|
||||
hr = aime_card_populate(&nfc->mifare, luid, sizeof(luid));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_poll_felica(
|
||||
struct sg_nfc *nfc,
|
||||
struct sg_nfc_poll_felica *felica)
|
||||
{
|
||||
uint64_t IDm;
|
||||
HRESULT hr;
|
||||
|
||||
/* Call backend */
|
||||
|
||||
if (nfc->ops->get_felica_id != NULL) {
|
||||
hr = nfc->ops->get_felica_id(nfc->ops_ctx, &IDm);
|
||||
} else {
|
||||
hr = S_FALSE;
|
||||
}
|
||||
|
||||
if (FAILED(hr) || hr == S_FALSE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
sg_nfc_dprintf(nfc, "FeliCa card is present\n");
|
||||
|
||||
/* Construct poll response */
|
||||
|
||||
felica->type = 0x20;
|
||||
felica->id_len = sizeof(felica->IDm) + sizeof(felica->PMm);
|
||||
felica->IDm = _byteswap_uint64(IDm);
|
||||
felica->PMm = _byteswap_uint64(felica_get_generic_PMm());
|
||||
|
||||
/* Initialize FeliCa IC emulator */
|
||||
|
||||
nfc->felica.IDm = IDm;
|
||||
nfc->felica.PMm = felica_get_generic_PMm();
|
||||
nfc->felica.system_code = 0x0000;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_mifare_read_block(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_nfc_req_mifare_read_block *req,
|
||||
struct sg_nfc_resp_mifare_read_block *resp)
|
||||
{
|
||||
@ -271,71 +350,81 @@ static HRESULT sg_nfc_cmd_mifare_read_block(
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
uid = (req->payload.uid[0] << 24) |
|
||||
(req->payload.uid[1] << 16) |
|
||||
(req->payload.uid[2] << 8) |
|
||||
(req->payload.uid[3] ) ;
|
||||
uid = _byteswap_ulong(req->payload.uid);
|
||||
|
||||
sg_nfc_dprintf(nfc, "Read uid %08x block %i\n", uid, req->payload.block_no);
|
||||
|
||||
if (req->payload.block_no > 3) {
|
||||
sg_nfc_dprintf(nfc, "MIFARE block number out of range\n");
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
sg_resp_init(&resp->resp, &req->req, sizeof(resp->block));
|
||||
|
||||
switch (req->payload.block_no) {
|
||||
case 1:
|
||||
return sg_nfc_mifare_read_block_1(nfc, uid, resp->block);
|
||||
|
||||
case 2:
|
||||
return sg_nfc_mifare_read_block_2(nfc, uid, resp->block);
|
||||
|
||||
case 0:
|
||||
case 3:
|
||||
sg_nfc_dprintf(
|
||||
nfc,
|
||||
"Block %i access not implemented\n",
|
||||
req->payload.block_no);
|
||||
|
||||
return E_NOTIMPL;
|
||||
|
||||
default:
|
||||
sg_nfc_dprintf(
|
||||
nfc,
|
||||
"Read from invalid mifare block nr %i\n",
|
||||
req->payload.block_no);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_mifare_read_block_1(
|
||||
const struct sg_nfc *nfc,
|
||||
uint32_t uid,
|
||||
uint8_t *block)
|
||||
{
|
||||
memcpy(block, sg_nfc_block_1, sizeof(sg_nfc_block_1));
|
||||
memcpy( resp->block,
|
||||
nfc->mifare.sectors[0].blocks[req->payload.block_no].bytes,
|
||||
sizeof(resp->block));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_mifare_read_block_2(
|
||||
const struct sg_nfc *nfc,
|
||||
uint32_t uid,
|
||||
uint8_t *block)
|
||||
static HRESULT sg_nfc_cmd_felica_encap(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_nfc_req_felica_encap *req,
|
||||
struct sg_nfc_resp_felica_encap *resp)
|
||||
{
|
||||
struct const_iobuf f_req;
|
||||
struct iobuf f_res;
|
||||
HRESULT hr;
|
||||
|
||||
hr = nfc->ops->mifare_read_luid(nfc->ops_ctx, uid, &block[6], 10);
|
||||
/* First byte of encapsulated request and response is a length byte
|
||||
(inclusive of itself). The FeliCa emulator expects its caller to handle
|
||||
that length byte on its behalf (we adopt the convention that the length
|
||||
byte is part of the FeliCa protocol's framing layer). */
|
||||
|
||||
if (req->req.payload_len != 8 + req->payload[0]) {
|
||||
sg_nfc_dprintf(
|
||||
nfc,
|
||||
"FeliCa encap payload length mismatch: sg %i != felica %i + 8",
|
||||
req->req.payload_len,
|
||||
req->payload[0]);
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
f_req.bytes = req->payload;
|
||||
f_req.nbytes = req->payload[0];
|
||||
f_req.pos = 1;
|
||||
|
||||
f_res.bytes = resp->payload;
|
||||
f_res.nbytes = sizeof(resp->payload);
|
||||
f_res.pos = 1;
|
||||
|
||||
#if 0
|
||||
dprintf("FELICA OUTBOUND:\n");
|
||||
dump_const_iobuf(&f_req);
|
||||
#endif
|
||||
|
||||
hr = felica_transact(&nfc->felica, &f_req, &f_res);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
memset(block, 0, 6);
|
||||
sg_resp_init(&resp->resp, &req->req, f_res.pos);
|
||||
resp->payload[0] = f_res.pos;
|
||||
|
||||
#if 0
|
||||
dprintf("FELICA INBOUND:\n");
|
||||
dump_iobuf(&f_res);
|
||||
#endif
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
const struct sg_nfc *nfc,
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_resp_header *resp)
|
||||
{
|
||||
|
@ -7,19 +7,23 @@
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
#include "iccard/felica.h"
|
||||
#include "iccard/mifare.h"
|
||||
|
||||
struct sg_nfc_ops {
|
||||
HRESULT (*mifare_poll)(void *ctx, uint32_t *uid);
|
||||
HRESULT (*mifare_read_luid)(
|
||||
void *ctx,
|
||||
uint32_t uid,
|
||||
uint8_t *luid,
|
||||
size_t nbytes);
|
||||
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);
|
||||
|
||||
// TODO Banapass, AmuseIC
|
||||
};
|
||||
|
||||
struct sg_nfc {
|
||||
const struct sg_nfc_ops *ops;
|
||||
void *ops_ctx;
|
||||
uint8_t addr;
|
||||
struct felica felica;
|
||||
struct mifare mifare;
|
||||
};
|
||||
|
||||
void sg_nfc_init(
|
||||
|
@ -20,17 +20,18 @@
|
||||
|
||||
static HRESULT sg_reader_handle_irp(struct irp *irp);
|
||||
static HRESULT sg_reader_handle_irp_locked(struct irp *irp);
|
||||
static HRESULT sg_reader_mifare_poll(void *ctx, uint32_t *uid);
|
||||
static HRESULT sg_reader_mifare_read_luid(
|
||||
static HRESULT sg_reader_nfc_poll(void *ctx);
|
||||
static HRESULT sg_reader_nfc_get_aime_id(
|
||||
void *ctx,
|
||||
uint32_t uid,
|
||||
uint8_t *luid,
|
||||
size_t luid_size);
|
||||
static HRESULT sg_reader_nfc_get_felica_id(void *ctx, uint64_t *IDm);
|
||||
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 = {
|
||||
.mifare_poll = sg_reader_mifare_poll,
|
||||
.mifare_read_luid = sg_reader_mifare_read_luid,
|
||||
.poll = sg_reader_nfc_poll,
|
||||
.get_aime_id = sg_reader_nfc_get_aime_id,
|
||||
.get_felica_id = sg_reader_nfc_get_felica_id,
|
||||
};
|
||||
|
||||
static const struct sg_led_ops sg_reader_led_ops = {
|
||||
@ -134,18 +135,22 @@ static HRESULT sg_reader_handle_irp_locked(struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT sg_reader_mifare_poll(void *ctx, uint32_t *uid)
|
||||
static HRESULT sg_reader_nfc_poll(void *ctx)
|
||||
{
|
||||
return aime_io_mifare_poll(0, uid);
|
||||
return aime_io_nfc_poll(0);
|
||||
}
|
||||
|
||||
static HRESULT sg_reader_mifare_read_luid(
|
||||
static HRESULT sg_reader_nfc_get_aime_id(
|
||||
void *ctx,
|
||||
uint32_t uid,
|
||||
uint8_t *luid,
|
||||
size_t luid_size)
|
||||
{
|
||||
return aime_io_mifare_read_luid(0, uid, luid, luid_size);
|
||||
return aime_io_nfc_get_aime_id(0, luid, luid_size);
|
||||
}
|
||||
|
||||
static HRESULT sg_reader_nfc_get_felica_id(void *ctx, uint64_t *IDm)
|
||||
{
|
||||
return aime_io_nfc_get_felica_id(0, IDm);
|
||||
}
|
||||
|
||||
static void sg_reader_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b)
|
||||
|
Reference in New Issue
Block a user