From bb529a9077ab15235f72b7a0e4a0d7fab84e5216 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 2 Dec 2023 16:52:48 +0800 Subject: [PATCH] Fix corrupted data caused by CMD_WTX No need to wait for 2.5s (1s + FPGA_LOAD_WAIT_TIME) if the real-time sampling stops. Make sure the LF bitstream is loaded before real-time sampling so the response of CMD_WTX won't appear. --- CHANGELOG.md | 1 + armsrc/fpgaloader.h | 6 ------ client/src/cmdhfmf.c | 4 ++-- client/src/cmdhw.c | 2 +- client/src/cmdlf.c | 33 +++++++++++++++++++++++---------- include/pm3_cmd.h | 5 +++++ 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5054a1da08..bf4fcc2402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fixed the corrupted data in real-time sampling (@wh201906) - Added a slider in the plot window for navigation (@wh201906) - Fixed client build bug with Python 3.12 (@wh201906) - Fixed `ExchangeAPDUSC()` in `cmdsmartcard.c` to prevent client crash (@wh201906) diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index b345e34f21..27455507df 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -24,12 +24,6 @@ #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; -// definitions for multiple FPGA config files support -#define FPGA_BITSTREAM_LF 1 -#define FPGA_BITSTREAM_HF 2 -#define FPGA_BITSTREAM_HF_FELICA 3 -#define FPGA_BITSTREAM_HF_15 4 - /* Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() Send 16 bit command / data pair to FPGA with the bit format: diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index c1ccadb39f..935d1cb822 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -4249,7 +4249,7 @@ int CmdHF14AMfELoad(const char *Cmd) { // ICEMAN: bug. if device has been using ICLASS commands, // the device needs to load the HF fpga image. It takes 1.5 second. - set_fpga_mode(2); + set_fpga_mode(FPGA_BITSTREAM_HF); // use RDV4 spiffs if (use_spiffs && IfPm3Flash() == false) { @@ -8006,7 +8006,7 @@ static int CmdHF14AGen4Save(const char *Cmd) { // ICEMAN: bug. if device has been using ICLASS commands, // the device needs to load the HF fpga image. It takes 1.5 second. - set_fpga_mode(2); + set_fpga_mode(FPGA_BITSTREAM_HF); // validations if (pwd_len != 4 && pwd_len != 0) { diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index d0a7102cf2..b355e66cba 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1105,7 +1105,7 @@ static int CmdBreak(const char *Cmd) { } int set_fpga_mode(uint8_t mode) { - if (mode < 1 || mode > 4) { + if (mode < FPGA_BITSTREAM_LF || mode > FPGA_BITSTREAM_HF_15) { return PM3_EINVARG; } uint8_t d[] = {mode}; diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index c9f6935732..8533e7ac8d 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -30,6 +30,7 @@ #include "cliparser.h" // args parsing #include "graph.h" // for graph data #include "cmddata.h" // for `lf search` +#include "cmdhw.h" // for setting FPGA image #include "cmdlfawid.h" // for awid menu #include "cmdlfem.h" // for em menu #include "cmdlfem410x.h" // for em4x menu @@ -725,15 +726,23 @@ static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) { size_t sample_bytes = samples * bits_per_sample; sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0); + // In real-time mode, the LF bitstream should be loaded before receiving raw data. + // Otherwise, the first batch of raw data might contain the response of CMD_WTX. + int result = set_fpga_mode(FPGA_BITSTREAM_LF); + if (result != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "failed to load LF bitstream to FPGA"); + return result; + } + SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload)); if (is_trigger_threshold_set) { - size_t first_receive_len = 32; // larger than the response of CMD_WTX + size_t first_receive_len = 32; // Wait until a bunch of data arrives first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false); - sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000 + FPGA_LOAD_WAIT_TIME, true); + sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000, true); sample_bytes += first_receive_len; } else { - sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true); + sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000, true); } samples = sample_bytes * 8 / bits_per_sample; PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes); @@ -767,8 +776,6 @@ int lf_read(bool verbose, uint64_t samples) { } int CmdLFRead(const char *Cmd) { - // In real-time mode, the first few bytes might be the response of CMD_WTX - // rather than the real samples if the LF FPGA image is not ready. CLIParserContext *ctx; CLIParserInit(&ctx, "lf read", "Sniff low frequency signal.\n" @@ -837,15 +844,23 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) { size_t sample_bytes = samples * bits_per_sample; sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0); + // In real-time mode, the LF bitstream should be loaded before receiving raw data. + // Otherwise, the first batch of raw data might contain the response of CMD_WTX. + int result = set_fpga_mode(FPGA_BITSTREAM_LF); + if (result != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "failed to load LF bitstream to FPGA"); + return result; + } + SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload)); if (is_trigger_threshold_set) { - size_t first_receive_len = 32; // larger than the response of CMD_WTX + size_t first_receive_len = 32; // Wait until a bunch of data arrives first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false); - sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000 + FPGA_LOAD_WAIT_TIME, true); + sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000, true); sample_bytes += first_receive_len; } else { - sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true); + sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000, true); } samples = sample_bytes * 8 / bits_per_sample; PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes); @@ -875,8 +890,6 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) { } int CmdLFSniff(const char *Cmd) { - // In real-time mode, the first few bytes might be the response of CMD_WTX - // rather than the real samples if the LF FPGA image is not ready. CLIParserContext *ctx; CLIParserInit(&ctx, "lf sniff", "Sniff low frequency signal. You need to configure the LF part on the Proxmark3 device manually.\n" diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index dcb33bb172..9189704e46 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -847,6 +847,11 @@ typedef struct { # define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40 # define UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS 20 +// definitions for multiple FPGA config files support +#define FPGA_BITSTREAM_LF 1 +#define FPGA_BITSTREAM_HF 2 +#define FPGA_BITSTREAM_HF_FELICA 3 +#define FPGA_BITSTREAM_HF_15 4 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: /* Whether a bootloader that understands the g_common_area is present */