mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 22:55:37 -07:00
Add support for trigger threshold
This commit is contained in:
parent
ab9f49f86e
commit
835b7a9150
2 changed files with 44 additions and 17 deletions
|
@ -66,8 +66,6 @@
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "pm3_cmd.h" // for LF_CMDREAD_MAX_EXTRA_SYMBOLS
|
#include "pm3_cmd.h" // for LF_CMDREAD_MAX_EXTRA_SYMBOLS
|
||||||
|
|
||||||
static bool gs_lf_threshold_set = false;
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
// Informative user function.
|
// Informative user function.
|
||||||
|
@ -646,7 +644,6 @@ int CmdLFConfig(const char *Cmd) {
|
||||||
config.divisor = LF_DIVISOR_125;
|
config.divisor = LF_DIVISOR_125;
|
||||||
config.samples_to_skip = 0;
|
config.samples_to_skip = 0;
|
||||||
config.trigger_threshold = 0;
|
config.trigger_threshold = 0;
|
||||||
gs_lf_threshold_set = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_125)
|
if (use_125)
|
||||||
|
@ -691,7 +688,6 @@ int CmdLFConfig(const char *Cmd) {
|
||||||
|
|
||||||
if (trigg > -1) {
|
if (trigg > -1) {
|
||||||
config.trigger_threshold = trigg;
|
config.trigger_threshold = trigg;
|
||||||
gs_lf_threshold_set = (config.trigger_threshold > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.samples_to_skip = skip;
|
config.samples_to_skip = skip;
|
||||||
|
@ -713,6 +709,7 @@ static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) {
|
||||||
}
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
||||||
|
const bool is_trigger_threshold_set = (current_config.trigger_threshold > 0);
|
||||||
|
|
||||||
if (realtime) {
|
if (realtime) {
|
||||||
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
||||||
|
@ -721,16 +718,27 @@ static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) {
|
||||||
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
||||||
|
|
||||||
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
|
if (is_trigger_threshold_set) {
|
||||||
|
size_t first_receive_len = 32; // larger than the response of CMD_WTX
|
||||||
|
// 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 += first_receive_len;
|
||||||
|
} else {
|
||||||
|
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
|
||||||
|
}
|
||||||
samples = sample_bytes * 8 / bits_per_sample;
|
samples = sample_bytes * 8 / bits_per_sample;
|
||||||
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes);
|
||||||
|
if (samples != 0) {
|
||||||
|
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
free(realtimeBuf);
|
free(realtimeBuf);
|
||||||
} else {
|
} else {
|
||||||
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
||||||
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (gs_lf_threshold_set) {
|
if (is_trigger_threshold_set) {
|
||||||
WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp);
|
WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp);
|
||||||
} else {
|
} else {
|
||||||
if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) {
|
if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) {
|
||||||
|
@ -809,6 +817,7 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) {
|
||||||
}
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
||||||
|
const bool is_trigger_threshold_set = (current_config.trigger_threshold > 0);
|
||||||
|
|
||||||
if (realtime) {
|
if (realtime) {
|
||||||
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
||||||
|
@ -817,16 +826,27 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) {
|
||||||
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
||||||
|
|
||||||
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
|
if (is_trigger_threshold_set) {
|
||||||
|
size_t first_receive_len = 32; // larger than the response of CMD_WTX
|
||||||
|
// 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 += first_receive_len;
|
||||||
|
} else {
|
||||||
|
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
|
||||||
|
}
|
||||||
samples = sample_bytes * 8 / bits_per_sample;
|
samples = sample_bytes * 8 / bits_per_sample;
|
||||||
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes);
|
||||||
|
if (samples != 0) {
|
||||||
|
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
free(realtimeBuf);
|
free(realtimeBuf);
|
||||||
} else {
|
} else {
|
||||||
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
||||||
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (gs_lf_threshold_set) {
|
if (is_trigger_threshold_set) {
|
||||||
WaitForResponse(CMD_LF_SNIFF_RAW_ADC, &resp);
|
WaitForResponse(CMD_LF_SNIFF_RAW_ADC, &resp);
|
||||||
} else {
|
} else {
|
||||||
if (WaitForResponseTimeout(CMD_LF_SNIFF_RAW_ADC, &resp, 2500) == false) {
|
if (WaitForResponseTimeout(CMD_LF_SNIFF_RAW_ADC, &resp, 2500) == false) {
|
||||||
|
|
|
@ -402,10 +402,6 @@ __attribute__((force_align_arg_pointer))
|
||||||
uint8_t dummyData[64];
|
uint8_t dummyData[64];
|
||||||
uint32_t dummyLen;
|
uint32_t dummyLen;
|
||||||
uart_receive(sp, dummyData, sizeof(dummyData), &dummyLen);
|
uart_receive(sp, dummyData, sizeof(dummyData), &dummyLen);
|
||||||
|
|
||||||
// set the buffer as undefined
|
|
||||||
// comm_raw_data == NULL is used in SetCommunicationReceiveMode()
|
|
||||||
__atomic_store_n(&comm_raw_data, NULL, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_receiving_raw_last) {
|
if (is_receiving_raw_last) {
|
||||||
|
@ -856,6 +852,12 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
|
||||||
// send anything to stop the transfer
|
// send anything to stop the transfer
|
||||||
PrintAndLogEx(INFO, "Stopping");
|
PrintAndLogEx(INFO, "Stopping");
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
|
|
||||||
|
// for ms_timeout == -1, pos < len might always be true
|
||||||
|
// so user need a spectial way to break this loop
|
||||||
|
if (ms_timeout == (size_t) - 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
|
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
|
||||||
|
@ -863,7 +865,8 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
|
||||||
// check the timeout if pos is not updated
|
// check the timeout if pos is not updated
|
||||||
if (last_pos == pos) {
|
if (last_pos == pos) {
|
||||||
uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST);
|
uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST);
|
||||||
if ((msclock() - tmp_clk > ms_timeout)) {
|
// if ms_timeout == -1, the loop can only be breaked by pressing Enter or receiving enough data
|
||||||
|
if ((ms_timeout != (size_t) - 1) && (msclock() - tmp_clk > ms_timeout)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -877,13 +880,17 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
|
||||||
last_pos = pos;
|
last_pos = pos;
|
||||||
msleep(10);
|
msleep(10);
|
||||||
}
|
}
|
||||||
if (pos == len) {
|
if (pos == len && (ms_timeout != (size_t) - 1)) {
|
||||||
|
// if ms_timeout != -1, when the desired data is received, tell the arm side
|
||||||
|
// to stop the current process, and wait for some time to make sure the process
|
||||||
|
// has been stopped
|
||||||
|
// if ms_timeout == -1, the user might not want to break the existing process
|
||||||
|
// on the arm side
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
msleep(ms_timeout);
|
msleep(ms_timeout);
|
||||||
}
|
}
|
||||||
SetCommunicationReceiveMode(false);
|
SetCommunicationReceiveMode(false);
|
||||||
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
|
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
|
||||||
PrintAndLogEx(INFO, "Done: [%zu/%zu]", pos, len);
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue