Skip to content

Commit

Permalink
Fix corrupted data caused by CMD_WTX
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wh201906 committed Dec 2, 2023
1 parent f3a9629 commit bb529a9
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 0 additions & 6 deletions armsrc/fpgaloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions client/src/cmdhfmf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion client/src/cmdhw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
33 changes: 23 additions & 10 deletions client/src/cmdlf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions include/pm3_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit bb529a9

Please sign in to comment.