diff --git a/armsrc/felica.c b/armsrc/felica.c index 322d11327..0dfad3a61 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -14,17 +14,17 @@ // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles #ifndef FELICA_REQUEST_GUARD_TIME -# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) +# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) // 426 #endif // FRAME DELAY TIME 2672 carrier cycles #ifndef FELICA_FRAME_DELAY_TIME -# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) +# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) // 168 #endif #ifndef DELAY_AIR2ARM_AS_READER -#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) +#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) // 27 + 128 + 64 - 128 = 91 #endif #ifndef DELAY_ARM2AIR_AS_READER -#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) +#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // 64 + 128 + 17 = 209 #endif // CRC skips two first sync bits in data buffer @@ -111,7 +111,7 @@ static void shiftInByte(uint8_t bt) { static void Process18092Byte(uint8_t bt) { switch (FelicaFrame.state) { case STATE_UNSYNCD: { - //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case + //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case if (bt > 0) { FelicaFrame.shiftReg = reflect8(bt); FelicaFrame.state = STATE_TRYING_SYNC; @@ -175,13 +175,11 @@ static void Process18092Byte(uint8_t bt) { } case STATE_GET_CRC: { shiftInByte(bt); - if (FelicaFrame.rem_len <= 0) { + FelicaFrame.rem_len = 0; // skip sync 2bytes. IF ok, residue should be 0x0000 FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2); FelicaFrame.state = STATE_FULL; - FelicaFrame.rem_len = 0; - if (DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No"); } break; } @@ -194,6 +192,7 @@ static void Process18092Byte(uint8_t bt) { /* Perform FeliCa polling card * Currently does NOT do any collision handling. * It expects 0-1 cards in the device's range. + * return 0 if selection was successful */ static uint8_t felica_select_card(felica_card_select_t *card) { @@ -201,17 +200,16 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 0xB2 0x4B = sync code // 0x06 = len // 0x00 = rfu - // 0xff = system service - // 0xff = system service - // 0x00 = - // b7 = automatic switching of data rate - // b6-b2 = reserved - // b1 = fc/32 (414kbps) - // b0 = fc/64 (212kbps) + // 0xff = system code service + // 0xff = system code service + // 0x00 = request code + // b7 = automatic switching of data rate + // b6-b2 = reserved + // b1 = fc/32 (414kbps) + // b0 = fc/64 (212kbps) // 0x00 = timeslot // 0x09 0x21 = crc static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21}; - int len = 20; // We try 20 times, or if answer was received. @@ -222,7 +220,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); // polling card, break if success - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) + if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) break; WDT_HIT(); @@ -230,17 +228,31 @@ static uint8_t felica_select_card(felica_card_select_t *card) { } while (--len); // timed-out - if (len == 0) + if (len == 0){ + if (DBGLEVEL > 3) + Dbprintf("Error: Time out card selection!"); return 1; + } // wrong answer - if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) + if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK){ + if (DBGLEVEL > 3) + Dbprintf("Error: Wrong answer selecting card!"); return 2; + } // VALIDATE 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)){ + if (DBGLEVEL > 3){ + Dbprintf("Error: CRC check failed!"); + Dbprintf("CRC check was done on Frame: "); + Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0); + } return 3; + } + if (DBGLEVEL > 3) + Dbprintf("Card selection successful!"); // copy UID // idm 8 if (card) { @@ -251,7 +263,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) { memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); memcpy(card->mrt, card->PMm + 2, 6); - + if (DBGLEVEL > 3){ + Dbprintf("Received Frame: "); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); + } } // more status bytes? return 0; @@ -349,10 +364,13 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, c++; } } - // sending sync code - - // sending data + // sending data with sync bytes c = 0; + if (DBGLEVEL > 3){ + Dbprintf("Sending frame:"); + Dbhexdump(len, frame, 0); + } + while (c < len) { // Put byte into tx holding register as soon as it is ready @@ -386,22 +404,21 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, // stop when button is pressed // or return TRUE when command is captured bool WaitForFelicaReply(uint16_t maxbytes) { - + if (DBGLEVEL > 3) + Dbprintf("WaitForFelicaReply Start"); uint32_t c = 0; - // power, no modulation FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - FelicaFrameReset(); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - (void)b; - uint32_t timeout = iso18092_get_timeout(); + if (DBGLEVEL > 3) + Dbprintf("timeout set: %i", timeout); + //TODO FIX THIS METHOD - Race Condition or something: TIMING/MEMORY ISSUES for (;;) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(b); @@ -410,8 +427,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { MAX( felica_nexttransfertime, (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME - ) - ; + ); LogTrace( FelicaFrame.framebytes, @@ -421,22 +437,20 @@ bool WaitForFelicaReply(uint16_t maxbytes) { NULL, false ); + if (DBGLEVEL > 3) Dbprintf("All bytes received! STATE_FULL"); return true; } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { + if (DBGLEVEL > 3) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; - } else if (FelicaFrame.state == STATE_GET_CRC) { - Dbprintf(" Frame: "); - Dbhexdump(16, FelicaFrame.framebytes, 0); - //return false; - } + } // If you add content here, timing problems appear?! } } - return false; } // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" static void iso18092_setup(uint8_t fpga_minor_mode) { + if (DBGLEVEL > 3) Dbprintf("Start iso18092_setup"); LEDsoff(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -481,7 +495,6 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { // arg1 len of commandbytes // d.asBytes command bytes to send void felica_sendraw(PacketCommandNG *c) { - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); felica_command_t param = c->oldarg[0]; @@ -492,21 +505,25 @@ void felica_sendraw(PacketCommandNG *c) { felica_card_select_t card; if ((param & FELICA_CONNECT)) + if (DBGLEVEL > 3) Dbprintf("Clear trace"); clear_trace(); set_tracing(true); + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); if ((param & FELICA_CONNECT)) { - iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - // notify client selecting status. // if failed selecting, turn off antenna and quite. if (!(param & FELICA_NO_SELECT)) { arg0 = felica_select_card(&card); reply_old(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); - if (arg0 > 0) - goto OUT; + if (arg0 > 0){ + Dbprintf("Error: Failed selecting card! "); + } + goto OUT; } + }else{ + if (DBGLEVEL > 3) Dbprintf("No card selection"); } if ((param & FELICA_RAW)) { @@ -527,22 +544,32 @@ void felica_sendraw(PacketCommandNG *c) { AddCrc(buf, len); } } - + if (DBGLEVEL > 3) { + Dbprintf("Transmit Frame (no CRC shown):"); + Dbhexdump(len, buf, 0); + Dbprintf("Buffer Length: %i", buf[2] + 4); + }; TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0); - arg0 = !WaitForFelicaReply(1024); + arg0 = WaitForFelicaReply(1024); + if (DBGLEVEL > 3) { + Dbprintf("Received Frame: %d", arg0); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); + }; reply_old(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes + 2, FelicaFrame.len - 2); + FelicaFrameReset(); } if ((param & FELICA_NO_DISCONNECT)) + Dbprintf("Disconnect"); return; -OUT: - switch_off(); + OUT: + switch_off(); - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + //Resetting Frame mode (First set in fpgaloader.c) + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); + if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { @@ -722,8 +749,98 @@ void felica_sim_lite(uint64_t uid) { DbpString("Felica Lite-S sim end"); } -void felica_dump_lite_s() { +void felica_dump(){ + uint8_t ndef[8]; + uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921 + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + while (!BUTTON_PRESS() && !data_available()) { + WDT_HIT(); + TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { + memcpy(ndef, FelicaFrame.framebytes + 4, 8); + uint8_t *request_service = felica_create_request_service_frame(0x01, ndef); + felica_send_request_service(request_service); + } + } +} + +void felica_send_request_service(uint8_t *request_service){ + uint8_t len = sizeof(request_service) / sizeof((request_service)[0]); + Dbprintf("Send Service Request - len: d%", len); + TransmitFor18092_AsReader(request_service, len, NULL, 1, 0); + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) { + Dbprintf("Got Service Response!"); + } +} + +/* Create Request Service Frame +// Use this command to verify the existence of Area and Service, and to acquire Key Version. +// When the specified Area or Service exists, the card returns Key Version. +// When the specified Area or Service does not exist, the card returns FFFFh as Key Version. +*/ +uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm){ + if(nodeNumber < 1 && nodeNumber > 32){ + Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1"); + nodeNumber = 1; + } + // Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List + uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t)*11); + //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; + request_service[0] = 0xb2; //Sync + request_service[1] = 0x4d; //Sync + request_service[2] = 0x0B; // Length + request_service[3] = FELICA_REQSRV_REQ; // CMD + request_service[4] = idm[0]; + request_service[5] = idm[1]; + request_service[6] = idm[2]; + request_service[7] = idm[3]; + request_service[8] = idm[4]; + request_service[9] = idm[5]; + request_service[9] = idm[6]; + request_service[9] = idm[7]; + request_service[10] = nodeNumber; // Node we like to ask for services + request_service[11] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE + return request_service; +} + +// Create Frame for authentication1 CMD +void felica_create_authentication1_frame(){ + +} + +// Create Frame for authentication2 CMD +void felica_create_authentication2_frame(){ + +} + +// Create a Frame for Read without encryption CMD as Payload +void felica_create_read_block_frame(uint16_t blockNr){ + if(blockNr < 1 || blockNr > 567){ + Dbprintf("Block number out of range!"); + return; + } + uint8_t c = 0; + // First Byte of SYNC + frameSpace[c++] = 0xb2; + frameSpace[c++] = 0x4d; + // skip Length of Frame + c++; + // Payload + frameSpace[c++] = FELICA_RDBLK_REQ; //command number + + // Set frame length + + // CRC +} + +void felica_read_block(uint8_t *idm, uint16_t blockNr){ + + +} + +void felica_dump_lite_s() { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0}; diff --git a/armsrc/felica.h b/armsrc/felica.h index ef34dc108..f160a0edf 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -18,5 +18,11 @@ void felica_sendraw(PacketCommandNG *c); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sim_lite(uint64_t uid); void felica_dump_lite_s(); +void felica_dump(); +void felica_create_read_block_frame(uint16_t blockNr); +void felica_create_authentication1_frame(); +void felica_create_authentication2_frame(); +void felica_send_request_service(uint8_t *request_service); +uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 333498f37..8a8d08ec0 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -39,6 +39,7 @@ static int usage_hf_felica_sim(void) { return 0; } */ + static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); @@ -80,6 +81,12 @@ static int usage_hf_felica_raw(void) { return 0; } +static int usage_hf_felica_dump(void) { + PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); + PrintAndLogEx(NORMAL, " -h this help"); + return 0; +} + static int CmdHFFelicaList(const char *Cmd) { (void)Cmd; // Cmd is not used so far //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); @@ -93,6 +100,12 @@ static int CmdHFFelicaReader(const char *Cmd) { return 0; } +static int CmdHFFelicaDump(const char *Cmd) { + if (strlen(Cmd) < 1) return usage_hf_felica_dump(); + dump(*Cmd); + return 0; +} + // simulate iso18092 / FeliCa tag // Commented, there is no counterpart in ARM at the moment /* @@ -351,7 +364,7 @@ static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t trac PrintAndLogEx(NORMAL, "Authenticated: %s", trace[3] ? "yes" : "no"); break; case 0xa0: - PrintAndLogEx(NORMAL, "CRC of all bloacks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes"); + PrintAndLogEx(NORMAL, "CRC of all blocks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes"); break; default: PrintAndLogEx(WARNING, "INVALID %d: %s", blocknum, line); @@ -393,8 +406,10 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { } uint32_t tracelen = resp.oldarg[1]; - if (tracelen == 0) + if (tracelen == 0){ + PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?"); return 1; + } uint8_t *trace = calloc(tracelen, sizeof(uint8_t)); if (trace == NULL) { @@ -408,7 +423,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 0; } - PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen); + PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); print_hex_break(trace, tracelen, 32); printSep(); @@ -427,7 +442,7 @@ static void waitCmdFelica(uint8_t iSelect) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); + uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); PrintAndLogEx(NORMAL, "received %i octets", len); if (!len) return; @@ -435,6 +450,7 @@ static void waitCmdFelica(uint8_t iSelect) { } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } + } static int CmdHFFelicaCmdRaw(const char *Cmd) { @@ -516,8 +532,8 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (crc && datalen > 0 && datalen < sizeof(data) - 2) { uint8_t b1, b2; compute_crc(CRC_FELICA, data, datalen, &b1, &b2); - data[datalen++] = b1; data[datalen++] = b2; + data[datalen++] = b1; } uint8_t flags = 0; @@ -543,6 +559,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (reply) { if (active_select) + PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); waitCmdFelica(1); if (datalen > 0) waitCmdFelica(0); @@ -550,30 +567,6 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { return 0; } -static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, - {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, -// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, - {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, - {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - - {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, - {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, - {NULL, NULL, NULL, NULL} -}; - -static int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; -} - -int CmdHFFelica(const char *Cmd) { - clearCommandBuffer(); - return CmdsParse(CommandTable, Cmd); -} - int readFelicaUid(bool verbose) { clearCommandBuffer(); @@ -587,6 +580,7 @@ int readFelicaUid(bool verbose) { felica_card_select_t card; memcpy(&card, (felica_card_select_t *)resp.data.asBytes, sizeof(felica_card_select_t)); + PrintAndLogEx(NORMAL, "Received bytes: \n%s", sprint_hex(resp.data.asBytes, sizeof(resp.data.asBytes))); uint64_t status = resp.oldarg[0]; switch (status) { @@ -622,3 +616,61 @@ int readFelicaUid(bool verbose) { } return status; } + +// TODO FINISH THIS METHOD +int dump(const char *Cmd){ + clearCommandBuffer(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_hf_felica_dumplite(); + + PrintAndLogEx(SUCCESS, "FeliCa - dump started"); + clearCommandBuffer(); + SendCommandNG(CMD_HF_FELICALITE_DUMP, NULL, 0); + PacketResponseNG resp; + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + timeout++; + printf("."); + fflush(stdout); + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); + DropField(); + return 1; + } + if (timeout > 100) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + DropField(); + return 1; + } + } + if (resp.oldarg[0] == 0) { + PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); + return 1; + } + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, + {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, +// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, + {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, + {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, + {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"}, + {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, + {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + +int CmdHFFelica(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index 4193235f5..abbbd42a4 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -16,4 +16,6 @@ int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); + +int dump(); #endif