diff --git a/common/aimeio/aimeio.c b/common/aimeio/aimeio.c index 7efffb5..fbb694e 100644 --- a/common/aimeio/aimeio.c +++ b/common/aimeio/aimeio.c @@ -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) {} diff --git a/common/aimeio/aimeio.h b/common/aimeio/aimeio.h index bb851cd..96dd241 100644 --- a/common/aimeio/aimeio.h +++ b/common/aimeio/aimeio.h @@ -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 diff --git a/common/board/aime-dll.c b/common/board/aime-dll.c index 7c00dfd..94b380c 100644 --- a/common/board/aime-dll.c +++ b/common/board/aime-dll.c @@ -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), }, }; diff --git a/common/board/aime-dll.h b/common/board/aime-dll.h index 7113cc1..00a5368 100644 --- a/common/board/aime-dll.h +++ b/common/board/aime-dll.h @@ -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, diff --git a/common/board/sg-nfc.c b/common/board/sg-nfc.c index b103336..82a01a6 100644 --- a/common/board/sg-nfc.c +++ b/common/board/sg-nfc.c @@ -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; } diff --git a/common/board/sg-nfc.h b/common/board/sg-nfc.h index 092b3e3..855d8cf 100644 --- a/common/board/sg-nfc.h +++ b/common/board/sg-nfc.h @@ -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 }; diff --git a/common/board/sg-reader.c b/common/board/sg-reader.c index 2dc3c3d..c1935dd 100644 --- a/common/board/sg-reader.c +++ b/common/board/sg-reader.c @@ -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); diff --git a/games/apm3hook/apm3hook.def b/games/apm3hook/apm3hook.def index c965fb8..776de48 100644 --- a/games/apm3hook/apm3hook.def +++ b/games/apm3hook/apm3hook.def @@ -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 diff --git a/games/carolhook/carolhook.def b/games/carolhook/carolhook.def index 1a8312d..a1dccdb 100644 --- a/games/carolhook/carolhook.def +++ b/games/carolhook/carolhook.def @@ -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 diff --git a/games/chunihook/chunihook.def b/games/chunihook/chunihook.def index 4128451..1961d46 100644 --- a/games/chunihook/chunihook.def +++ b/games/chunihook/chunihook.def @@ -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 diff --git a/games/chusanhook/chusanhook.def b/games/chusanhook/chusanhook.def index 8786d4e..c471207 100644 --- a/games/chusanhook/chusanhook.def +++ b/games/chusanhook/chusanhook.def @@ -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 diff --git a/games/cmhook/cmhook.def b/games/cmhook/cmhook.def index 526442d..5727411 100644 --- a/games/cmhook/cmhook.def +++ b/games/cmhook/cmhook.def @@ -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 diff --git a/games/cxbhook/cxbhook.def b/games/cxbhook/cxbhook.def index 8466898..7f9b190 100644 --- a/games/cxbhook/cxbhook.def +++ b/games/cxbhook/cxbhook.def @@ -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 diff --git a/games/divahook/divahook.def b/games/divahook/divahook.def index a92e61d..e9e430d 100644 --- a/games/divahook/divahook.def +++ b/games/divahook/divahook.def @@ -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 diff --git a/games/fgohook/fgohook.def b/games/fgohook/fgohook.def index a2088b9..b341a65 100644 --- a/games/fgohook/fgohook.def +++ b/games/fgohook/fgohook.def @@ -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 diff --git a/games/idachook/idachook.def b/games/idachook/idachook.def index 4ef2b98..325a286 100644 --- a/games/idachook/idachook.def +++ b/games/idachook/idachook.def @@ -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 diff --git a/games/idzhook/idzhook.def b/games/idzhook/idzhook.def index b13642b..52d42a8 100644 --- a/games/idzhook/idzhook.def +++ b/games/idzhook/idzhook.def @@ -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 diff --git a/games/kemonohook/kemonohook.def b/games/kemonohook/kemonohook.def index 4db5e98..fdb8251 100644 --- a/games/kemonohook/kemonohook.def +++ b/games/kemonohook/kemonohook.def @@ -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 diff --git a/games/mai2hook/mai2hook.def b/games/mai2hook/mai2hook.def index cf1ed65..31bce4d 100644 --- a/games/mai2hook/mai2hook.def +++ b/games/mai2hook/mai2hook.def @@ -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 diff --git a/games/mercuryhook/mercuryhook.def b/games/mercuryhook/mercuryhook.def index 4d3c8ec..d1fa0d1 100644 --- a/games/mercuryhook/mercuryhook.def +++ b/games/mercuryhook/mercuryhook.def @@ -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 diff --git a/games/mu3hook/mu3hook.def b/games/mu3hook/mu3hook.def index ab34a0f..392310a 100644 --- a/games/mu3hook/mu3hook.def +++ b/games/mu3hook/mu3hook.def @@ -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 diff --git a/games/swdchook/swdchook.def b/games/swdchook/swdchook.def index 09c40a9..eda115e 100644 --- a/games/swdchook/swdchook.def +++ b/games/swdchook/swdchook.def @@ -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 diff --git a/games/tokyohook/tokyohook.def b/games/tokyohook/tokyohook.def index 8b30d5f..6a88879 100644 --- a/games/tokyohook/tokyohook.def +++ b/games/tokyohook/tokyohook.def @@ -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