1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2025-02-22 13:10:39 +01:00

PN5180 major bug fixed

This commit is contained in:
whowechina 2024-01-14 19:44:18 +08:00
parent 32d9b819a6
commit 7c99f98fc0
4 changed files with 115 additions and 101 deletions

Binary file not shown.

View File

@ -2,7 +2,7 @@
* AIME Reader * AIME Reader
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
* *
* Use PN532 to read AIME * Use NFC Module to read AIME
*/ */
#include <stdint.h> #include <stdint.h>
@ -12,7 +12,7 @@
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "pn532.h" #include "nfc.h"
#include "aime.h" #include "aime.h"
#define FRAME_TIMEOUT 200000 #define FRAME_TIMEOUT 200000
@ -100,7 +100,6 @@ void aime_set_virtual_aic(bool enable)
void aime_init(aime_putc_func putc_func) void aime_init(aime_putc_func putc_func)
{ {
aime_putc = putc_func; aime_putc = putc_func;
pn532_config_sam();
} }
static uint8_t mifare_keys[2][6]; // 'KeyA' and 'KeyB' static uint8_t mifare_keys[2][6]; // 'KeyA' and 'KeyB'
@ -189,8 +188,7 @@ static void send_simple_response(uint8_t status)
static void cmd_to_normal_mode() static void cmd_to_normal_mode()
{ {
send_simple_response(pn532_firmware_ver() ? STATUS_NFCRW_FIRMWARE_UP_TO_DATE send_simple_response(STATUS_NFCRW_FIRMWARE_UP_TO_DATE);
: STATUS_NFCRW_INIT_ERROR);
} }
static void cmd_fake_version(const char *version[]) static void cmd_fake_version(const char *version[])
@ -209,7 +207,7 @@ static void cmd_key_set(uint8_t key[6])
static void cmd_set_polling(bool enabled) static void cmd_set_polling(bool enabled)
{ {
pn532_set_rf_field(0, enabled ? 1 : 0); //pn532_set_rf_field(0, enabled ? 1 : 0);
send_simple_response(STATUS_OK); send_simple_response(STATUS_OK);
} }
@ -239,7 +237,7 @@ static void handle_mifare_card(const uint8_t *uid, int len)
memcpy(card->uid, uid, len); memcpy(card->uid, uid, len);
} }
static void handle_felica_card(const uint8_t felica_ids[18]) static void handle_felica_card(const uint8_t idm[8], const uint8_t pmm[8])
{ {
build_response(19); build_response(19);
card_info_t *card = (card_info_t *) response.payload; card_info_t *card = (card_info_t *) response.payload;
@ -247,8 +245,8 @@ static void handle_felica_card(const uint8_t felica_ids[18])
card->count = 1; card->count = 1;
card->type = 0x20; card->type = 0x20;
card->id_len = 16; card->id_len = 16;
memcpy(card->idm, felica_ids, 8); memcpy(card->idm, idm, 8);
memcpy(card->pmm, felica_ids + 8, 8); memcpy(card->pmm, pmm, 8);
} }
static void fake_felica_card() static void fake_felica_card()
@ -272,49 +270,49 @@ static void handle_no_card()
response.status = STATUS_OK; response.status = STATUS_OK;
} }
static void printf_hex(const uint8_t *hex, int len, const char *tail)
{
for (int i = 0; i < len; i ++) {
printf(" %02x", hex[i]);
}
printf("%s", tail);
}
static void cmd_detect_card() static void cmd_detect_card()
{ {
uint8_t buf[18]; nfc_card_t card = nfc_detect_card();
virtual_aic.active = false;
int len = sizeof(buf);
if (pn532_poll_mifare(buf, &len)) {
printf("Detected Mifare - ");
printf_hex(buf, len, "\n");
switch (card.card_type) {
case NFC_CARD_MIFARE:
if (virtual_aic.enabled) { if (virtual_aic.enabled) {
printf("\nVirtual FeliCa from MIFARE.");
virtual_aic.active = true; virtual_aic.active = true;
memset(virtual_aic.idm, 0, 8);
memcpy(virtual_aic.idm, "\x01\x01", 2); memcpy(virtual_aic.idm, "\x01\x01", 2);
memcpy(virtual_aic.idm + 2, buf, len); if (card.len == 4) {
memcpy(virtual_aic.idm + 2, card.uid, 4);
printf("Virtual AIC -"); memcpy(virtual_aic.idm + 6, card.uid, 2);
printf_hex(virtual_aic.idm, 8, ","); } else if (card.len == 7) {
printf_hex(virtual_aic.pmm, 8, ","); memcpy(virtual_aic.idm + 2, card.uid, 6);
printf_hex(virtual_aic.syscode, 2, "\n"); }
fake_felica_card(); fake_felica_card();
} else { } else {
handle_mifare_card(buf, len); handle_mifare_card(card.uid, card.len);
} }
} else if (pn532_poll_felica(buf, buf + 8, buf + 16, false)) { break;
printf("Detected Felica -"); case NFC_CARD_FELICA:
printf_hex(buf, 8, ","); if (virtual_aic.enabled) {
printf_hex(buf + 8, 8, ","); printf("\nVirtual FeliCa from FeliCa.");
printf_hex(buf + 16, 2, "\n"); virtual_aic.active = true;
memcpy(virtual_aic.idm, card.uid, 8);
handle_felica_card(buf); fake_felica_card();
} else { } else {
handle_felica_card(card.uid, card.pmm);
}
break;
case NFC_CARD_VICINITY:
if (virtual_aic.enabled) {
printf("\nVirtual FeliCa from 15693.");
virtual_aic.active = true;
memcpy(virtual_aic.idm, "\x01\x01", 2);
memcpy(virtual_aic.idm + 2, card.uid, 6);
fake_felica_card();
}
break;
default:
handle_no_card(); handle_no_card();
break;
} }
send_response(); send_response();
@ -329,7 +327,7 @@ static void cmd_card_select()
static void cmd_mifare_auth(int type) static void cmd_mifare_auth(int type)
{ {
printf("MIFARE AUTH\n"); printf("MIFARE AUTH\n");
pn532_mifare_auth(request.mifare.uid, request.mifare.block_id, type, mifare_keys[type]); nfc_mifare_auth(request.mifare.uid, request.mifare.block_id, type, mifare_keys[type]);
send_simple_response(STATUS_OK); send_simple_response(STATUS_OK);
} }
@ -340,7 +338,7 @@ static void cmd_mifare_read()
request.mifare.uid[3]); request.mifare.uid[3]);
build_response(16); build_response(16);
memset(response.payload, 0, 16); memset(response.payload, 0, 16);
pn532_mifare_read(request.mifare.block_id, response.payload); nfc_mifare_read(request.mifare.block_id, response.payload);
send_response(); send_response();
} }
@ -357,21 +355,13 @@ typedef struct __attribute__((packed)) {
uint8_t data[0]; uint8_t data[0];
} felica_resp_t; } felica_resp_t;
typedef struct __attribute__((packed)) { static int cmd_felica_poll(const nfc_card_t *card)
uint8_t idm[8];
uint8_t pmm[8];
uint8_t syscode[2];
} card_id_t;
static int cmd_felica_poll(const card_id_t *card)
{ {
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint8_t pmm[8]; uint8_t pmm[8];
uint8_t syscode[2]; uint8_t syscode[2];
} felica_poll_resp_t; } felica_poll_resp_t;
printf("FELICA POLL\n");
felica_resp_t *felica_resp = (felica_resp_t *) response.payload; felica_resp_t *felica_resp = (felica_resp_t *) response.payload;
felica_poll_resp_t *poll_resp = (felica_poll_resp_t *) felica_resp->data; felica_poll_resp_t *poll_resp = (felica_poll_resp_t *) felica_resp->data;
@ -386,9 +376,8 @@ static int cmd_felica_poll(const card_id_t *card)
return sizeof(*poll_resp); return sizeof(*poll_resp);
} }
static int cmd_felica_get_syscode(const card_id_t *card) static int cmd_felica_get_syscode(const nfc_card_t *card)
{ {
printf("FELICA GET_SYSTEM_CODE\n");
felica_resp_t *felica_resp = (felica_resp_t *) response.payload; felica_resp_t *felica_resp = (felica_resp_t *) response.payload;
felica_resp->data[0] = 0x01; felica_resp->data[0] = 0x01;
if (virtual_aic.active) { if (virtual_aic.active) {
@ -402,7 +391,6 @@ static int cmd_felica_get_syscode(const card_id_t *card)
static int cmd_felica_read() static int cmd_felica_read()
{ {
printf("FELICA READ\n");
uint8_t *req_data = request.felica.data; uint8_t *req_data = request.felica.data;
if (req_data[8] != 1) { if (req_data[8] != 1) {
@ -432,7 +420,7 @@ static int cmd_felica_read()
memcpy(read_resp->block_data[i], felica_resp->idm, 8); memcpy(read_resp->block_data[i], felica_resp->idm, 8);
} }
if (!virtual_aic.active) { if (!virtual_aic.active) {
pn532_felica_read_wo_encrypt(svc_code, block_id, read_resp->block_data[i]); nfc_felica_read_wo_encrypt(svc_code, block_id, read_resp->block_data[i]);
} }
} }
@ -445,7 +433,6 @@ static int cmd_felica_read()
static int cmd_felica_write() static int cmd_felica_write()
{ {
printf("FELICA WRITE\n");
uint8_t *req_data = request.felica.data; uint8_t *req_data = request.felica.data;
if (req_data[8] != 1) { if (req_data[8] != 1) {
@ -453,39 +440,15 @@ static int cmd_felica_write()
return -1; return -1;
} }
uint16_t svc_code = req_data[9] | (req_data[10] << 8); /* No, we don't actually write */
uint8_t *block = req_data + 11;
uint8_t block_num = block[0];
felica_resp_t *felica_resp = (felica_resp_t *) response.payload; felica_resp_t *felica_resp = (felica_resp_t *) response.payload;
uint8_t *rw_status = felica_resp->data; uint8_t *rw_status = felica_resp->data;
printf("svc code: %04x\n", svc_code);
printf("blocks:");
for (int i = 0; i < block_num; i++) {
uint16_t block_id = (block[i * 2 + 1] << 8) | block[i * 2 + 2];
printf(" %04x", block_id);
}
printf("\n");
uint8_t *block_data = block + 1 + block_num * 2;
rw_status[0] = 0x00; rw_status[0] = 0x00;
rw_status[1] = 0x00; rw_status[1] = 0x00;
for (int i = 0; i < block_num; i++) {
printf("writing %02x %02x\n", block_data[i * 16], block_data[i * 16 + 15]);
// uint16_t block_id = (block[i * 2 + 1] << 8) | block[i * 2 + 2];
// int result = pn532_felica_write_wo_encrypt(svc_code, block_id, block_data + i * 16);
int result = 0;
if (result < 0) {
rw_status[0] = 0x01;
rw_status[1] = 0x01;
}
}
return 2; return 2;
} }
#if 0 #if 0
@ -503,18 +466,22 @@ static int cmd_felica_write()
static void cmd_felica() static void cmd_felica()
{ {
card_id_t card; nfc_card_t card = nfc_detect_card();
if (!pn532_poll_felica(card.idm, card.pmm, card.syscode, true)) { if (!virtual_aic.active) {
if (card.card_type != NFC_CARD_FELICA) {
send_simple_response(STATUS_FELICA_ERROR); send_simple_response(STATUS_FELICA_ERROR);
return;
}
} }
uint8_t felica_code = request.felica.code; uint8_t felica_code = request.felica.code;
/*
printf("Felica (%02x):", felica_code); printf("Felica (%02x):", felica_code);
for (int i = 0; i < request.payload_len; i++) { for (int i = 0; i < request.payload_len; i++) {
printf(" %02x", request.payload[i]); printf(" %02x", request.payload[i]);
} }
printf("\n"); printf("\n");
*/
int datalen = -1; int datalen = -1;
switch (felica_code) { switch (felica_code) {
case CMD_FELICA_OP_GET_SYSTEM_CODE: case CMD_FELICA_OP_GET_SYSTEM_CODE:
@ -551,11 +518,13 @@ static void cmd_felica()
send_response(); send_response();
/*
printf("Felica Response:"); printf("Felica Response:");
for (int i = 0; i < felica_resp->len - 10; i++) { for (int i = 0; i < felica_resp->len - 10; i++) {
printf(" %02x", felica_resp->data[i]); printf(" %02x", felica_resp->data[i]);
} }
printf("\n"); printf("\n");
*/
} }
static uint32_t led_color; static uint32_t led_color;
@ -574,19 +543,15 @@ static void aime_handle_frame()
cmd_to_normal_mode(); cmd_to_normal_mode();
break; break;
case CMD_GET_FW_VERSION: case CMD_GET_FW_VERSION:
printf("CMD_GET_FW_VERSION\n");
cmd_fake_version(fw_version); cmd_fake_version(fw_version);
break; break;
case CMD_GET_HW_VERSION: case CMD_GET_HW_VERSION:
printf("CMD_GET_HW_VERSION\n");
cmd_fake_version(hw_version); cmd_fake_version(hw_version);
break; break;
case CMD_MIFARE_KEY_SET_A: case CMD_MIFARE_KEY_SET_A:
printf("CMD_MIFARE_KEY_SET_A\n");
cmd_key_set(mifare_keys[0]); cmd_key_set(mifare_keys[0]);
break; break;
case CMD_MIFARE_KEY_SET_B: case CMD_MIFARE_KEY_SET_B:
printf("CMD_MIFARE_KEY_SET_B\n");
cmd_key_set(mifare_keys[1]); cmd_key_set(mifare_keys[1]);
break; break;

View File

@ -126,3 +126,43 @@ nfc_card_t nfc_detect_card()
return card; return card;
} }
bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key)
{
if (nfc_module == NFC_MODULE_PN532) {
return pn532_mifare_auth(uid, block_id, key_id, key);
} else if (nfc_module == NFC_MODULE_PN5180) {
return false;//pn5180_mifare_auth(uid, block_id, key_id, key);
}
return false;
}
bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16])
{
if (nfc_module == NFC_MODULE_PN532) {
return pn532_mifare_read(block_id, block_data);
} else if (nfc_module == NFC_MODULE_PN5180) {
return false; // pn5180_mifare_read(block_id, block_data);
}
return false;
}
bool nfc_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16])
{
if (nfc_module == NFC_MODULE_PN532) {
return pn532_felica_read_wo_encrypt(svc_code, block_id, block_data);
} else if (nfc_module == NFC_MODULE_PN5180) {
return false; //pn5180_felica_read_wo_encrypt(svc_code, block_id, block_data);
}
return false;
}
bool nfc_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16])
{
if (nfc_module == NFC_MODULE_PN532) {
return pn532_felica_write_wo_encrypt(svc_code, block_id, block_data);
} else if (nfc_module == NFC_MODULE_PN5180) {
return false; //pn5180_felica_write_wo_encrypt(svc_code, block_id, block_data);
}
return false;
}

View File

@ -20,7 +20,10 @@ typedef void (*nfc_wait_loop_t)();
typedef struct { typedef struct {
nfc_card_type card_type; nfc_card_type card_type;
uint16_t len; uint16_t len;
union {
uint8_t uid[8]; uint8_t uid[8];
uint8_t idm[8];
};
uint8_t pmm[8]; uint8_t pmm[8];
uint8_t syscode[2]; uint8_t syscode[2];
} nfc_card_t; } nfc_card_t;
@ -28,4 +31,10 @@ typedef struct {
void nfc_init(nfc_wait_loop_t loop); void nfc_init(nfc_wait_loop_t loop);
nfc_card_t nfc_detect_card(); nfc_card_t nfc_detect_card();
bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key);
bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16]);
bool nfc_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]);
bool nfc_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]);
#endif #endif