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.
This commit is contained in:
wh201906 2023-12-02 16:52:48 +08:00
commit bb529a9077
No known key found for this signature in database
6 changed files with 32 additions and 19 deletions

View file

@ -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... 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] ## [unreleased][unreleased]
- Fixed the corrupted data in real-time sampling (@wh201906)
- Added a slider in the plot window for navigation (@wh201906) - Added a slider in the plot window for navigation (@wh201906)
- Fixed client build bug with Python 3.12 (@wh201906) - Fixed client build bug with Python 3.12 (@wh201906)
- Fixed `ExchangeAPDUSC()` in `cmdsmartcard.c` to prevent client crash (@wh201906) - Fixed `ExchangeAPDUSC()` in `cmdsmartcard.c` to prevent client crash (@wh201906)

View file

@ -24,12 +24,6 @@
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; #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() 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: Send 16 bit command / data pair to FPGA with the bit format:

View file

@ -4249,7 +4249,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
// ICEMAN: bug. if device has been using ICLASS commands, // ICEMAN: bug. if device has been using ICLASS commands,
// the device needs to load the HF fpga image. It takes 1.5 second. // 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 // use RDV4 spiffs
if (use_spiffs && IfPm3Flash() == false) { if (use_spiffs && IfPm3Flash() == false) {
@ -8006,7 +8006,7 @@ static int CmdHF14AGen4Save(const char *Cmd) {
// ICEMAN: bug. if device has been using ICLASS commands, // ICEMAN: bug. if device has been using ICLASS commands,
// the device needs to load the HF fpga image. It takes 1.5 second. // 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 // validations
if (pwd_len != 4 && pwd_len != 0) { if (pwd_len != 4 && pwd_len != 0) {

View file

@ -1105,7 +1105,7 @@ static int CmdBreak(const char *Cmd) {
} }
int set_fpga_mode(uint8_t mode) { 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; return PM3_EINVARG;
} }
uint8_t d[] = {mode}; uint8_t d[] = {mode};

View file

@ -30,6 +30,7 @@
#include "cliparser.h" // args parsing #include "cliparser.h" // args parsing
#include "graph.h" // for graph data #include "graph.h" // for graph data
#include "cmddata.h" // for `lf search` #include "cmddata.h" // for `lf search`
#include "cmdhw.h" // for setting FPGA image
#include "cmdlfawid.h" // for awid menu #include "cmdlfawid.h" // for awid menu
#include "cmdlfem.h" // for em menu #include "cmdlfem.h" // for em menu
#include "cmdlfem410x.h" // for em4x 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; size_t sample_bytes = samples * bits_per_sample;
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0); 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)); SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
if (is_trigger_threshold_set) { 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 // Wait until a bunch of data arrives
first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false); 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; sample_bytes += first_receive_len;
} else { } 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; samples = sample_bytes * 8 / bits_per_sample;
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes); 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) { 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; CLIParserContext *ctx;
CLIParserInit(&ctx, "lf read", CLIParserInit(&ctx, "lf read",
"Sniff low frequency signal.\n" "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; size_t sample_bytes = samples * bits_per_sample;
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0); 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)); SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
if (is_trigger_threshold_set) { 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 // Wait until a bunch of data arrives
first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false); 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; sample_bytes += first_receive_len;
} else { } 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; samples = sample_bytes * 8 / bits_per_sample;
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes); 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) { 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; CLIParserContext *ctx;
CLIParserInit(&ctx, "lf sniff", CLIParserInit(&ctx, "lf sniff",
"Sniff low frequency signal. You need to configure the LF part on the Proxmark3 device manually.\n" "Sniff low frequency signal. You need to configure the LF part on the Proxmark3 device manually.\n"

View file

@ -847,6 +847,11 @@ typedef struct {
# define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40 # define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40
# define UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS 20 # 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: // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
/* Whether a bootloader that understands the g_common_area is present */ /* Whether a bootloader that understands the g_common_area is present */