mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
Receive raw LF samples on the client
This commit is contained in:
parent
8fdf04fcfb
commit
42ab3ee1e6
4 changed files with 116 additions and 44 deletions
|
@ -1776,36 +1776,45 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_conf
|
||||||
bits_per_sample = sc->bits_per_sample;
|
bits_per_sample = sc->bits_per_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSamplesFromBufEx(got, n, bits_per_sample, verbose);
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getSamplesFromBufEx(uint8_t *data, size_t sample_num, uint8_t bits_per_sample, bool verbose) {
|
||||||
|
|
||||||
|
size_t max_num = MIN(sample_num, MAX_GRAPH_TRACE_LEN);
|
||||||
|
|
||||||
if (bits_per_sample < 8) {
|
if (bits_per_sample < 8) {
|
||||||
|
|
||||||
if (verbose) PrintAndLogEx(INFO, "Unpacking...");
|
if (verbose) PrintAndLogEx(INFO, "Unpacking...");
|
||||||
|
|
||||||
BitstreamOut_t bout = { got, bits_per_sample * n, 0};
|
BitstreamOut_t bout = {data, bits_per_sample * sample_num, 0};
|
||||||
uint32_t j = 0;
|
size_t j = 0;
|
||||||
for (j = 0; j * bits_per_sample < n * 8 && j * bits_per_sample < MAX_GRAPH_TRACE_LEN * 8; j++) {
|
for (j = 0; j < max_num; j++) {
|
||||||
uint8_t sample = getByte(bits_per_sample, &bout);
|
uint8_t sample = getByte(bits_per_sample, &bout);
|
||||||
g_GraphBuffer[j] = ((int) sample) - 127;
|
g_GraphBuffer[j] = ((int) sample) - 127;
|
||||||
}
|
}
|
||||||
g_GraphTraceLen = j;
|
g_GraphTraceLen = j;
|
||||||
|
|
||||||
if (verbose) PrintAndLogEx(INFO, "Unpacked %d samples", j);
|
if (verbose) PrintAndLogEx(INFO, "Unpacked %zu samples", j);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t j = 0; j < n; j++) {
|
for (size_t j = 0; j < max_num; j++) {
|
||||||
g_GraphBuffer[j] = ((int)got[j]) - 127;
|
g_GraphBuffer[j] = ((int)data[j]) - 127;
|
||||||
}
|
}
|
||||||
g_GraphTraceLen = n;
|
g_GraphTraceLen = max_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t bits[g_GraphTraceLen];
|
uint8_t *bits = malloc(g_GraphTraceLen);
|
||||||
size_t size = getFromGraphBuf(bits);
|
size_t size = getFromGraphBuf(bits);
|
||||||
// set signal properties low/high/mean/amplitude and is_noise detection
|
// set signal properties low/high/mean/amplitude and is_noise detection
|
||||||
computeSignalProperties(bits, size);
|
computeSignalProperties(bits, size);
|
||||||
|
free(bits);
|
||||||
|
|
||||||
setClockGrid(0, 0);
|
setClockGrid(0, 0);
|
||||||
g_DemodBufferLen = 0;
|
g_DemodBufferLen = 0;
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdSamples(const char *Cmd) {
|
static int CmdSamples(const char *Cmd) {
|
||||||
|
@ -3584,4 +3593,3 @@ int CmdData(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
return CmdsParse(CommandTable, Cmd);
|
return CmdsParse(CommandTable, Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG
|
||||||
|
|
||||||
int getSamples(uint32_t n, bool verbose);
|
int getSamples(uint32_t n, bool verbose);
|
||||||
int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_config);
|
int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_config);
|
||||||
|
void getSamplesFromBufEx(uint8_t *data, size_t sample_num, uint8_t bits_per_sample, bool verbose);
|
||||||
|
|
||||||
void setClockGrid(uint32_t clk, int offset);
|
void setClockGrid(uint32_t clk, int offset);
|
||||||
int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down);
|
int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down);
|
||||||
|
|
|
@ -696,31 +696,58 @@ int CmdLFConfig(const char *Cmd) {
|
||||||
return lf_config(&config);
|
return lf_config(&config);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lf_read(bool verbose, uint32_t samples) {
|
static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) {
|
||||||
if (!g_session.pm3_present) return PM3_ENOTTY;
|
if (!g_session.pm3_present) return PM3_ENOTTY;
|
||||||
|
|
||||||
lf_sample_payload_t payload;
|
lf_sample_payload_t payload;
|
||||||
|
payload.realtime = realtime;
|
||||||
payload.verbose = verbose;
|
payload.verbose = verbose;
|
||||||
payload.samples = samples;
|
|
||||||
|
|
||||||
|
sample_config current_config;
|
||||||
|
int retval = lf_getconfig(¤t_config);
|
||||||
|
if (retval != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get current device config");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
||||||
PacketResponseNG resp;
|
|
||||||
if (gs_lf_threshold_set) {
|
if (realtime) {
|
||||||
WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp);
|
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
||||||
|
|
||||||
|
size_t sample_bytes = samples * bits_per_sample;
|
||||||
|
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
||||||
|
|
||||||
|
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000, true);
|
||||||
|
samples = sample_bytes * 8 / bits_per_sample;
|
||||||
|
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
||||||
|
|
||||||
|
free(realtimeBuf);
|
||||||
} else {
|
} else {
|
||||||
if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) {
|
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
||||||
PrintAndLogEx(WARNING, "(lf_read) command execution time out");
|
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
return PM3_ETIMEOUT;
|
PacketResponseNG resp;
|
||||||
|
if (gs_lf_threshold_set) {
|
||||||
|
WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp);
|
||||||
|
} else {
|
||||||
|
if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) {
|
||||||
|
PrintAndLogEx(WARNING, "(lf_read) command execution time out");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// response is number of bits read
|
||||||
|
uint32_t size = (resp.data.asDwords[0] / bits_per_sample);
|
||||||
|
getSamples(size, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
// response is number of bits read
|
|
||||||
uint32_t size = (resp.data.asDwords[0] / 8);
|
|
||||||
getSamples(size, verbose);
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lf_read(bool verbose, uint64_t samples) {
|
||||||
|
return lf_read_internal(false, verbose, samples);
|
||||||
|
}
|
||||||
|
|
||||||
int CmdLFRead(const char *Cmd) {
|
int CmdLFRead(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf read",
|
CLIParserInit(&ctx, "lf read",
|
||||||
|
@ -729,6 +756,7 @@ int CmdLFRead(const char *Cmd) {
|
||||||
_CYAN_(" - use ") _YELLOW_("`data plot`") _CYAN_(" to look at it"),
|
_CYAN_(" - use ") _YELLOW_("`data plot`") _CYAN_(" to look at it"),
|
||||||
"lf read -v -s 12000 --> collect 12000 samples\n"
|
"lf read -v -s 12000 --> collect 12000 samples\n"
|
||||||
"lf read -s 3000 -@ --> oscilloscope style \n"
|
"lf read -s 3000 -@ --> oscilloscope style \n"
|
||||||
|
"lf read -r --> use real-time mode \n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -736,50 +764,78 @@ int CmdLFRead(const char *Cmd) {
|
||||||
arg_u64_0("s", "samples", "<dec>", "number of samples to collect"),
|
arg_u64_0("s", "samples", "<dec>", "number of samples to collect"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0("@", NULL, "continuous reading mode"),
|
arg_lit0("@", NULL, "continuous reading mode"),
|
||||||
|
arg_lit0("r", "realtime", "real-time reading mode"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
uint32_t samples = arg_get_u32_def(ctx, 1, 0);
|
uint64_t samples = arg_get_u64_def(ctx, 1, 0);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool cm = arg_get_lit(ctx, 3);
|
bool cm = arg_get_lit(ctx, 3);
|
||||||
|
bool realtime = arg_get_lit(ctx, 4);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (g_session.pm3_present == false)
|
if (g_session.pm3_present == false)
|
||||||
return PM3_ENOTTY;
|
return PM3_ENOTTY;
|
||||||
|
|
||||||
if (cm) {
|
if (realtime && samples == 0) {
|
||||||
|
samples = MAX_GRAPH_TRACE_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cm || realtime) {
|
||||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||||
}
|
}
|
||||||
int ret = PM3_SUCCESS;
|
int ret = PM3_SUCCESS;
|
||||||
do {
|
do {
|
||||||
ret = lf_read(verbose, samples);
|
ret = lf_read_internal(realtime, verbose, samples);
|
||||||
} while (cm && kbd_enter_pressed() == false);
|
} while (cm && kbd_enter_pressed() == false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lf_sniff(bool verbose, uint32_t samples) {
|
int lf_sniff(bool realtime, bool verbose, uint64_t samples) {
|
||||||
if (!g_session.pm3_present) return PM3_ENOTTY;
|
if (!g_session.pm3_present) return PM3_ENOTTY;
|
||||||
|
|
||||||
lf_sample_payload_t payload;
|
lf_sample_payload_t payload;
|
||||||
|
payload.realtime = realtime;
|
||||||
payload.samples = (samples & 0xFFFF);
|
|
||||||
payload.verbose = verbose;
|
payload.verbose = verbose;
|
||||||
|
|
||||||
|
sample_config current_config;
|
||||||
|
int retval = lf_getconfig(¤t_config);
|
||||||
|
if (retval != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get current device config");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
const uint8_t bits_per_sample = current_config.bits_per_sample;
|
||||||
PacketResponseNG resp;
|
|
||||||
if (gs_lf_threshold_set) {
|
if (realtime) {
|
||||||
WaitForResponse(CMD_LF_SNIFF_RAW_ADC, &resp);
|
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
|
||||||
|
|
||||||
|
size_t sample_bytes = samples * bits_per_sample;
|
||||||
|
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
|
||||||
|
|
||||||
|
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000, true);
|
||||||
|
samples = sample_bytes * 8 / bits_per_sample;
|
||||||
|
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
|
||||||
|
|
||||||
|
free(realtimeBuf);
|
||||||
} else {
|
} else {
|
||||||
if (WaitForResponseTimeout(CMD_LF_SNIFF_RAW_ADC, &resp, 2500) == false) {
|
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
|
||||||
PrintAndLogEx(WARNING, "(lf_read) command execution time out");
|
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
|
||||||
return PM3_ETIMEOUT;
|
PacketResponseNG resp;
|
||||||
|
if (gs_lf_threshold_set) {
|
||||||
|
WaitForResponse(CMD_LF_SNIFF_RAW_ADC, &resp);
|
||||||
|
} else {
|
||||||
|
if (WaitForResponseTimeout(CMD_LF_SNIFF_RAW_ADC, &resp, 2500) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "(lf_read) command execution time out");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// response is number of bits read
|
||||||
|
uint32_t size = (resp.data.asDwords[0] / bits_per_sample);
|
||||||
|
getSamples(size, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
// response is number of bits read
|
|
||||||
uint32_t size = (resp.data.asDwords[0] / 8);
|
|
||||||
getSamples(size, verbose);
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,6 +850,7 @@ int CmdLFSniff(const char *Cmd) {
|
||||||
_CYAN_(" - use ") _YELLOW_("`lf search -1`") _CYAN_(" to see if signal can be automatic decoded\n"),
|
_CYAN_(" - use ") _YELLOW_("`lf search -1`") _CYAN_(" to see if signal can be automatic decoded\n"),
|
||||||
"lf sniff -v\n"
|
"lf sniff -v\n"
|
||||||
"lf sniff -s 3000 -@ --> oscilloscope style \n"
|
"lf sniff -s 3000 -@ --> oscilloscope style \n"
|
||||||
|
"lf sniff -r --> use real-time mode \n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -801,24 +858,30 @@ int CmdLFSniff(const char *Cmd) {
|
||||||
arg_u64_0("s", "samples", "<dec>", "number of samples to collect"),
|
arg_u64_0("s", "samples", "<dec>", "number of samples to collect"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0("@", NULL, "continuous sniffing mode"),
|
arg_lit0("@", NULL, "continuous sniffing mode"),
|
||||||
|
arg_lit0("r", "realtime", "real-time sniffing mode"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
uint32_t samples = (arg_get_u32_def(ctx, 1, 0) & 0xFFFF);
|
uint64_t samples = arg_get_u64_def(ctx, 1, 0);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool cm = arg_get_lit(ctx, 3);
|
bool cm = arg_get_lit(ctx, 3);
|
||||||
|
bool realtime = arg_get_lit(ctx, 4);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (g_session.pm3_present == false)
|
if (g_session.pm3_present == false)
|
||||||
return PM3_ENOTTY;
|
return PM3_ENOTTY;
|
||||||
|
|
||||||
if (cm) {
|
if (realtime && samples == 0) {
|
||||||
|
samples = MAX_GRAPH_TRACE_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cm || realtime) {
|
||||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||||
}
|
}
|
||||||
int ret = PM3_SUCCESS;
|
int ret = PM3_SUCCESS;
|
||||||
do {
|
do {
|
||||||
ret = lf_sniff(verbose, samples);
|
ret = lf_sniff(realtime, verbose, samples);
|
||||||
} while (cm && !kbd_enter_pressed());
|
} while (cm && kbd_enter_pressed() == false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ int CmdLFSniff(const char *Cmd);
|
||||||
int CmdVchDemod(const char *Cmd);
|
int CmdVchDemod(const char *Cmd);
|
||||||
int CmdLFfind(const char *Cmd);
|
int CmdLFfind(const char *Cmd);
|
||||||
|
|
||||||
int lf_read(bool verbose, uint32_t samples);
|
int lf_read(bool verbose, uint64_t samples);
|
||||||
int lf_sniff(bool verbose, uint32_t samples);
|
int lf_sniff(bool realtime, bool verbose, uint64_t samples);
|
||||||
int lf_config(sample_config *config);
|
int lf_config(sample_config *config);
|
||||||
int lf_getconfig(sample_config *config);
|
int lf_getconfig(sample_config *config);
|
||||||
int lfsim_upload_gb(void);
|
int lfsim_upload_gb(void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue