mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
changed to 50 polls, not sure if its good. Maybe looking at timeout 1060ms value instead? also cleaned out debug statements
This commit is contained in:
parent
5396524dc4
commit
eac3774189
1 changed files with 47 additions and 57 deletions
104
armsrc/felica.c
104
armsrc/felica.c
|
@ -236,9 +236,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||||
// 0x00 = timeslot
|
// 0x00 = timeslot
|
||||||
// 0x09 0x21 = crc
|
// 0x09 0x21 = crc
|
||||||
static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21};
|
static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21};
|
||||||
int len = 10;
|
|
||||||
|
|
||||||
// We try 10 times, or if answer was received.
|
// We try 10 times, or if answer was received.
|
||||||
|
int len = 50;
|
||||||
do {
|
do {
|
||||||
// end-of-reception response packet data, wait approx. 501μs
|
// end-of-reception response packet data, wait approx. 501μs
|
||||||
// end-of-transmission command packet data, wait approx. 197μs
|
// end-of-transmission command packet data, wait approx. 197μs
|
||||||
|
@ -246,45 +247,40 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||||
TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0);
|
TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0);
|
||||||
|
|
||||||
// polling card, break if success
|
// polling card, break if success
|
||||||
if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK)
|
if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
} while (--len);
|
} while (--len);
|
||||||
|
|
||||||
// timed-out
|
// 1. timed-out
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
if (g_dbglevel >= DBG_DEBUG)
|
|
||||||
Dbprintf("Error: Time out card selection!");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrong answer
|
// 2. wrong answer
|
||||||
if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) {
|
if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) {
|
||||||
if (g_dbglevel >= DBG_DEBUG)
|
|
||||||
Dbprintf("Error: Wrong answer selecting card!");
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VALIDATE CRC residue is 0, hence if crc is a value it failed.
|
// 3. wrong crc. residue is 0, hence if crc is a value it failed.
|
||||||
if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) {
|
if (check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2) == false) {
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
Dbprintf("Error: CRC check failed!");
|
Dbprintf("Error: CRC check failed!");
|
||||||
Dbprintf("CRC check was done on Frame: ");
|
|
||||||
Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0);
|
Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0);
|
||||||
}
|
}
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG)
|
|
||||||
Dbprintf("Card selection successful!");
|
|
||||||
// copy UID
|
// copy UID
|
||||||
// idm 8
|
// idm 8
|
||||||
if (card) {
|
if (card) {
|
||||||
memcpy(card->IDm, FelicaFrame.framebytes + 4, 8);
|
memcpy(card->IDm, FelicaFrame.framebytes + 4, 8);
|
||||||
memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8);
|
memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8);
|
||||||
//memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2);
|
// memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2);
|
||||||
memcpy(card->code, card->IDm, 2);
|
memcpy(card->code, card->IDm, 2);
|
||||||
memcpy(card->uid, card->IDm + 2, 6);
|
memcpy(card->uid, card->IDm + 2, 6);
|
||||||
memcpy(card->iccode, card->PMm, 2);
|
memcpy(card->iccode, card->PMm, 2);
|
||||||
|
@ -294,7 +290,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||||
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// more status bytes?
|
// 0. OK
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,8 +307,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||||
// 8-byte IDm, number of blocks, blocks numbers
|
// 8-byte IDm, number of blocks, blocks numbers
|
||||||
// number of blocks limited to 4 for FelicaLite(S)
|
// number of blocks limited to 4 for FelicaLite(S)
|
||||||
static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) {
|
static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) {
|
||||||
if (blocknum > 4 || blocknum == 0)
|
|
||||||
|
if (blocknum > 4 || blocknum == 0) {
|
||||||
Dbprintf("Invalid number of blocks, %d != 4", blocknum);
|
Dbprintf("Invalid number of blocks, %d != 4", blocknum);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t c = 0, i = 0;
|
uint8_t c = 0, i = 0;
|
||||||
|
|
||||||
|
@ -320,11 +318,11 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t
|
||||||
frameSpace[c++] = 0xb2;
|
frameSpace[c++] = 0xb2;
|
||||||
frameSpace[c++] = 0x4d;
|
frameSpace[c++] = 0x4d;
|
||||||
|
|
||||||
c++; //set length later
|
c++; // set length later
|
||||||
|
|
||||||
frameSpace[c++] = FELICA_RDBLK_REQ; //command number
|
frameSpace[c++] = FELICA_RDBLK_REQ; // command number
|
||||||
|
|
||||||
//card IDm, from poll
|
// card IDm, from poll
|
||||||
frameSpace[c++] = idm[0];
|
frameSpace[c++] = idm[0];
|
||||||
frameSpace[c++] = idm[1];
|
frameSpace[c++] = idm[1];
|
||||||
frameSpace[c++] = idm[2];
|
frameSpace[c++] = idm[2];
|
||||||
|
@ -334,22 +332,22 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t
|
||||||
frameSpace[c++] = idm[6];
|
frameSpace[c++] = idm[6];
|
||||||
frameSpace[c++] = idm[7];
|
frameSpace[c++] = idm[7];
|
||||||
|
|
||||||
//number of services
|
// number of services
|
||||||
frameSpace[c++] = 0x01;
|
frameSpace[c++] = 0x01;
|
||||||
|
|
||||||
//service code
|
// service code
|
||||||
frameSpace[c++] = (SERVICE_FELICA_LITE_READONLY >> 8);
|
frameSpace[c++] = (SERVICE_FELICA_LITE_READONLY >> 8);
|
||||||
frameSpace[c++] = SERVICE_FELICA_LITE_READONLY & 0xFF;
|
frameSpace[c++] = SERVICE_FELICA_LITE_READONLY & 0xFF;
|
||||||
|
|
||||||
//number of blocks
|
// number of blocks
|
||||||
frameSpace[c++] = blocknum;
|
frameSpace[c++] = blocknum;
|
||||||
|
|
||||||
for (i = 0; i < blocknum; i++) {
|
for (i = 0; i < blocknum; i++) {
|
||||||
|
|
||||||
//3-byte block
|
// 3-byte block
|
||||||
if (blocks[i] >= 256) {
|
if (blocks[i] >= 256) {
|
||||||
frameSpace[c++] = 0x00;
|
frameSpace[c++] = 0x00;
|
||||||
frameSpace[c++] = (blocks[i] >> 8); //block number, little endian....
|
frameSpace[c++] = (blocks[i] >> 8); // block number, little endian....
|
||||||
frameSpace[c++] = (blocks[i] & 0xff);
|
frameSpace[c++] = (blocks[i] & 0xff);
|
||||||
} else {
|
} else {
|
||||||
frameSpace[c++] = 0x80;
|
frameSpace[c++] = 0x80;
|
||||||
|
@ -357,16 +355,16 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set length
|
// set length
|
||||||
frameSpace[2] = c - 2;
|
frameSpace[2] = c - 2;
|
||||||
//Add CRC
|
// Add CRC
|
||||||
AddCrc(frameSpace + 2, c - 2);
|
AddCrc(frameSpace + 2, c - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const uint32_t *NYI_timing_NYI, uint8_t power, uint8_t highspeed) {
|
static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const uint32_t *NYI_timing_NYI, uint8_t power, uint8_t highspeed) {
|
||||||
|
|
||||||
if (NYI_timing_NYI != NULL) {
|
if (NYI_timing_NYI != NULL) {
|
||||||
Dbprintf("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI");
|
DbpString("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,10 +398,6 @@ static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const
|
||||||
}
|
}
|
||||||
// sending data with sync bytes
|
// sending data with sync bytes
|
||||||
c = 0;
|
c = 0;
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
|
||||||
Dbprintf("Sending frame:");
|
|
||||||
Dbhexdump(len, frame, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (c < len) {
|
while (c < len) {
|
||||||
// Put byte into tx holding register as soon as it is ready
|
// Put byte into tx holding register as soon as it is ready
|
||||||
|
@ -438,9 +432,7 @@ static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const
|
||||||
// or return TRUE when command is captured
|
// or return TRUE when command is captured
|
||||||
bool WaitForFelicaReply(uint16_t maxbytes) {
|
bool WaitForFelicaReply(uint16_t maxbytes) {
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
// if (g_dbglevel >= DBG_DEBUG) { Dbprintf("WaitForFelicaReply Start"); }
|
||||||
Dbprintf("WaitForFelicaReply Start");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
|
@ -478,14 +470,11 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
|
||||||
NULL,
|
NULL,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) {
|
} else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) {
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD");
|
// if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -496,7 +485,6 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
|
||||||
// Set up FeliCa communication (similar to iso14443a_setup)
|
// Set up FeliCa communication (similar to iso14443a_setup)
|
||||||
// field is setup for "Sending as Reader"
|
// field is setup for "Sending as Reader"
|
||||||
static void iso18092_setup(uint8_t fpga_minor_mode) {
|
static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Start iso18092_setup");
|
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
#if defined XC3
|
#if defined XC3
|
||||||
|
@ -510,7 +498,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||||
|
|
||||||
// Initialize Demod and Uart structs
|
// Initialize Demod and Uart structs
|
||||||
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||||
FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE));
|
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE));
|
||||||
|
|
||||||
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
|
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
|
||||||
// iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card
|
// iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card
|
||||||
|
@ -553,7 +541,6 @@ static void felica_reset_frame_mode(void) {
|
||||||
// arg1 len of commandbytes
|
// arg1 len of commandbytes
|
||||||
// d.asBytes command bytes to send
|
// d.asBytes command bytes to send
|
||||||
void felica_sendraw(const PacketCommandNG *c) {
|
void felica_sendraw(const PacketCommandNG *c) {
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("FeliCa_sendraw Enter");
|
|
||||||
|
|
||||||
felica_command_t param = c->oldarg[0];
|
felica_command_t param = c->oldarg[0];
|
||||||
size_t len = c->oldarg[1] & 0xffff;
|
size_t len = c->oldarg[1] & 0xffff;
|
||||||
|
@ -562,33 +549,33 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||||
|
|
||||||
felica_card_select_t card;
|
felica_card_select_t card;
|
||||||
|
|
||||||
if ((param & FELICA_CONNECT))
|
if ((param & FELICA_CONNECT) == FELICA_CONNECT) {
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Clear trace");
|
clear_trace();
|
||||||
clear_trace();
|
}
|
||||||
|
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||||
|
|
||||||
if ((param & FELICA_CONNECT)) {
|
if ((param & FELICA_CONNECT) == FELICA_CONNECT) {
|
||||||
|
|
||||||
// notify client selecting status.
|
// notify client selecting status.
|
||||||
// if failed selecting, turn off antenna and quite.
|
// if failed selecting, turn off antenna and quite.
|
||||||
if (!(param & FELICA_NO_SELECT)) {
|
if ((param & FELICA_NO_SELECT) != FELICA_NO_SELECT) {
|
||||||
|
|
||||||
arg0 = felica_select_card(&card);
|
arg0 = felica_select_card(&card);
|
||||||
reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
|
reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
|
||||||
if (arg0 > 0) {
|
if (arg0) {
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Failed selecting card! ");
|
|
||||||
felica_reset_frame_mode();
|
felica_reset_frame_mode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("No card selection");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & FELICA_RAW)) {
|
if ((param & FELICA_RAW) == FELICA_RAW) {
|
||||||
|
|
||||||
// 2 sync, 1 len, 2crc == 5
|
// 2 sync, 1 len, 2crc == 5
|
||||||
uint8_t *buf = BigBuf_malloc(len + 5);
|
uint8_t *buf = BigBuf_calloc(len + 5);
|
||||||
// add sync bits
|
// add sync bits
|
||||||
buf[0] = 0xb2;
|
buf[0] = 0xb2;
|
||||||
buf[1] = 0x4d;
|
buf[1] = 0x4d;
|
||||||
|
@ -597,19 +584,22 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||||
// copy command
|
// copy command
|
||||||
memcpy(buf + 2, cmd, len);
|
memcpy(buf + 2, cmd, len);
|
||||||
|
|
||||||
if ((param & FELICA_APPEND_CRC)) {
|
if ((param & FELICA_APPEND_CRC) == FELICA_APPEND_CRC) {
|
||||||
// Don't append crc on empty bytearray...
|
// Don't append crc on empty bytearray...
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
AddCrc(buf + 2, len);
|
AddCrc(buf + 2, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
Dbprintf("Transmit Frame (no CRC shown):");
|
Dbprintf("Transmit Frame (no CRC shown):");
|
||||||
Dbhexdump(len, buf, 0);
|
Dbhexdump(len, buf, 0);
|
||||||
Dbprintf("Buffer Length: %i", buf[2] + 4);
|
Dbprintf("Buffer Length: %i", buf[2] + 4);
|
||||||
};
|
};
|
||||||
|
|
||||||
TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0);
|
TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0);
|
||||||
arg0 = WaitForFelicaReply(1024);
|
arg0 = WaitForFelicaReply(1024);
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
Dbprintf("Received Frame Code: %d", arg0);
|
Dbprintf("Received Frame Code: %d", arg0);
|
||||||
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
||||||
|
@ -620,11 +610,11 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||||
Dbprintf("Reply to Client Error Code: %i", result);
|
Dbprintf("Reply to Client Error Code: %i", result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((param & FELICA_NO_DISCONNECT)) {
|
|
||||||
Dbprintf("Disconnect");
|
if ((param & FELICA_NO_DISCONNECT) == FELICA_NO_DISCONNECT) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (g_dbglevel >= DBG_DEBUG)
|
|
||||||
Dbprintf("FeliCa_sendraw Exit");
|
|
||||||
felica_reset_frame_mode();
|
felica_reset_frame_mode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue