lf cmdread - now uses cliparser. Had to change the "extra" param structure to fit.\n lf config - now has a reset param

This commit is contained in:
iceman1001 2021-02-04 22:01:23 +01:00
commit 2a17cb5545

View file

@ -64,36 +64,6 @@ static bool g_lf_threshold_set = false;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static int usage_lf_cmdread(void) {
PrintAndLogEx(NORMAL, "Usage: lf cmdread d <delay duration> z <zero duration> o <one duration> [e <symbol> <duration>] c <cmd symbols> [q] [s #samples] [@]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " d <duration> delay OFF period, (0 for bitbang mode)");
PrintAndLogEx(NORMAL, " z <duration> ZERO time period");
PrintAndLogEx(NORMAL, " o <duration> ONE time period");
PrintAndLogEx(NORMAL, " e <symbol> <duration> Extra symbol definition and duration (up to %i)", LF_CMDREAD_MAX_EXTRA_SYMBOLS);
PrintAndLogEx(NORMAL, " b <duration> B period");
PrintAndLogEx(NORMAL, " c <cmd> Command symbols (0/1/...)");
PrintAndLogEx(NORMAL, " q silent (optional)");
PrintAndLogEx(NORMAL, " s #samples number of samples to collect (optional)");
PrintAndLogEx(NORMAL, " @ run continuously until a key is pressed (optional)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in decimal and in microseconds (us)"));
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 1/Hitag S") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W00110"));
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 2") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W11000"));
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 2, oscilloscope style") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" data plot"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W11000 q s 2000 @"));
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag (us)") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 48 z 112 o 176 e W 3000 e S 240 e E 336 c W0S00000010000E"));
PrintAndLogEx(NORMAL, "Extras:");
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
return PM3_SUCCESS;
}
// Informative user function. // Informative user function.
// loop and wait for either keyboard press or pm3 button to exit // loop and wait for either keyboard press or pm3 button to exit
// if key event, send break loop cmd to Pm3 // if key event, send break loop cmd to Pm3
@ -239,14 +209,51 @@ static int CmdLFTune(const char *Cmd) {
/* send a LF command before reading */ /* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd) { int CmdLFCommandRead(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf cmdread",
"Modulate LF reader field to send command before read. All periods in microseconds.\n"
" - use " _YELLOW_("`lf config`") _CYAN_(" to set parameters"),
"lf cmdread -d 50 -z 116 -o 166 -e W3000 -c W00110 --> probing for Hitag 1/S\n"
"lf cmdread -d 50 -z 116 -o 166 -e W3000 -c W11000 --> probing for Hitag 2\n"
"lf cmdread -d 50 -z 116 -o 166 -e W3000 -c W11000 -q -s 2000 -@ --> probing for Hitag 2, oscilloscope style\n"
"lf cmdread -d 48 -z 112 -o 176 -e W3000 -e S240 -e E336 -c W0S00000010000E --> probing for Hitag (us)\n"
);
if (!session.pm3_present) return PM3_ENOTTY; char div_str[70] = {0};
sprintf(div_str, "Extra symbol definition and duration (up to %i)", LF_CMDREAD_MAX_EXTRA_SYMBOLS);
bool errors = false; void *argtable[] = {
bool verbose = true; arg_param_begin,
bool continuous = false; arg_u64_0("d", "duration", "<us>", "delay OFF period, (0 for bitbang mode)"),
uint32_t samples = 0; arg_str0("c", "cmd", "<0|1|...>", "command symbols"),
uint16_t datalen = 0; arg_strx0("e", "extra", "<us>", div_str),
arg_u64_0("o", "one", "<us>", "ONE time period"),
arg_u64_0("z", "zero", "<us>", "ZERO time period"),
arg_u64_0("s", "samples", "<dec>", "number of samples to collect"),
arg_lit0("v", "verbose", "verbose output"),
arg_lit0("@", NULL, "continuous mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
uint32_t delay = arg_get_u32_def(ctx, 1, 0);
int cmd_len = 128;
char cmd[128] = {0};
CLIGetStrWithReturn(ctx, 2, (uint8_t*)cmd, &cmd_len);
int extra_arg_len = 250;
char extra_arg[250] = {0};
CLIGetStrWithReturn(ctx, 3, (uint8_t*)extra_arg, &extra_arg_len);
uint16_t period_1 = arg_get_u32_def(ctx, 4, 0);
uint16_t period_0 = arg_get_u32_def(ctx, 5, 0);
uint32_t samples = arg_get_u32_def(ctx, 6, 0);
bool verbose = arg_get_lit(ctx, 7);
bool cm = arg_get_lit(ctx, 8);
CLIParserFree(ctx);
if (session.pm3_present == false)
return PM3_ENOTTY;
const uint8_t payload_header_size = 12 + (3 * LF_CMDREAD_MAX_EXTRA_SYMBOLS); const uint8_t payload_header_size = 12 + (3 * LF_CMDREAD_MAX_EXTRA_SYMBOLS);
struct p { struct p {
@ -259,76 +266,57 @@ int CmdLFCommandRead(const char *Cmd) {
bool verbose : 1; bool verbose : 1;
uint8_t data[PM3_CMD_DATA_SIZE - payload_header_size]; uint8_t data[PM3_CMD_DATA_SIZE - payload_header_size];
} PACKED payload; } PACKED payload;
payload.delay = delay;
payload.period_1 = period_1;
payload.period_0 = period_0;
payload.samples = samples; payload.samples = samples;
payload.verbose = verbose; payload.verbose = verbose;
uint8_t index_extra = 0; memcpy(payload.data, cmd, cmd_len);
// extra symbol definition
uint8_t index_extra = 0;
int i = 0;
for (; i < extra_arg_len; ) {
uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_cmdread();
case 'c': // cmd bytes 1010
datalen = param_getstr(Cmd, cmdp + 1, (char *)&payload.data, sizeof(payload.data));
cmdp += 2;
break;
case 'd': // delay
payload.delay = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'z': // zero
payload.period_0 = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
cmdp += 2;
break;
case 'o': // ones
payload.period_1 = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
cmdp += 2;
break;
case 'e': // extra symbol definition
if (index_extra < LF_CMDREAD_MAX_EXTRA_SYMBOLS - 1) { if (index_extra < LF_CMDREAD_MAX_EXTRA_SYMBOLS - 1) {
payload.symbol_extra[index_extra] = param_getchar(Cmd, cmdp + 1); payload.symbol_extra[index_extra] = extra_arg[i];
payload.period_extra[index_extra] = param_get32ex(Cmd, cmdp + 2, 0, 10) & 0xFFFF; int tmp = atoi(extra_arg + (i + 1));
payload.period_extra[index_extra] = tmp;
index_extra++; index_extra++;
cmdp += 3; i++;
while (extra_arg[i] >= 0x30 && extra_arg[i] <= 0x39)
i++;
} else { } else {
PrintAndLogEx(WARNING, "Too many extra symbols, please define up to %i symbols", LF_CMDREAD_MAX_EXTRA_SYMBOLS); PrintAndLogEx(WARNING, "Too many extra symbols, please define up to %i symbols", LF_CMDREAD_MAX_EXTRA_SYMBOLS);
errors = true;
}
break;
case 's':
samples = param_get32ex(Cmd, cmdp + 1, 0, 10);
payload.samples = samples;
cmdp += 2;
break;
case 'q':
verbose = false;
payload.verbose = verbose;
cmdp++;
break;
case '@':
continuous = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
} }
} }
// bitbang mode // bitbang mode
if (payload.delay == 0) { if (payload.delay == 0) {
if (payload.period_0 < 7 || payload.period_1 < 7) { if (payload.period_0 < 7 || payload.period_1 < 7) {
PrintAndLogEx(WARNING, "warning periods cannot be less than 7us in bit bang mode"); PrintAndLogEx(WARNING, "periods cannot be less than 7us in bit bang mode");
return PM3_EINVARG; return PM3_EINVARG;
} }
} }
//Validations PrintAndLogEx(DEBUG, "Cmd read - settings");
if (errors || cmdp == 0) return usage_lf_cmdread(); PrintAndLogEx(DEBUG, "-------------------");
if (continuous) { PrintAndLogEx(DEBUG, "delay: %u , zero %u , one %u , samples %u", payload.delay, payload.period_0, payload.period_1, payload.samples);
PrintAndLogEx(INFO, "Press " _GREEN_("Enter") " to exit"); PrintAndLogEx(DEBUG, "Extra symbols");
PrintAndLogEx(DEBUG, "-------------");
for (i = 0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
if (payload.symbol_extra[i] == 0x00)
continue;
PrintAndLogEx(DEBUG, " %c - %u", payload.symbol_extra[i], payload.period_extra[i]);
} }
PrintAndLogEx(DEBUG, "data: %s", payload.data);
if (cm) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
}
if (verbose) { if (verbose) {
PrintAndLogEx(SUCCESS, "Sending command..."); PrintAndLogEx(SUCCESS, "Sending command...");
} }
@ -336,11 +324,11 @@ int CmdLFCommandRead(const char *Cmd) {
int ret = PM3_SUCCESS; int ret = PM3_SUCCESS;
do { do {
clearCommandBuffer(); clearCommandBuffer();
SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, payload_header_size + datalen); SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, payload_header_size + cmd_len);
PacketResponseNG resp; PacketResponseNG resp;
uint8_t i = 10; i = 10;
// 20sec wait loop // 20sec wait loop
while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, &resp, 2000) && i != 0) { while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, &resp, 2000) && i != 0) {
if (verbose) { if (verbose) {
@ -351,7 +339,11 @@ int CmdLFCommandRead(const char *Cmd) {
if (verbose) { if (verbose) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
} }
if (resp.status == PM3_SUCCESS) { if (resp.status != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "command failed.");
return PM3_ESOFT;
}
if (i) { if (i) {
if (verbose) { if (verbose) {
PrintAndLogEx(SUCCESS, "downloading response signal data"); PrintAndLogEx(SUCCESS, "downloading response signal data");
@ -362,14 +354,8 @@ int CmdLFCommandRead(const char *Cmd) {
PrintAndLogEx(WARNING, "timeout while waiting for reply."); PrintAndLogEx(WARNING, "timeout while waiting for reply.");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
} else {
PrintAndLogEx(WARNING, "command failed."); } while (cm && kbd_enter_pressed() == false);
return PM3_ESOFT;
}
if (kbd_enter_pressed()) {
break;
}
} while (continuous);
return ret; return ret;
} }
@ -487,7 +473,7 @@ int CmdLFConfig(const char *Cmd) {
_CYAN_(" - use ") _YELLOW_("`lf sniff`") _CYAN_(" performs a sniff (no active field)"), _CYAN_(" - use ") _YELLOW_("`lf sniff`") _CYAN_(" performs a sniff (no active field)"),
"lf config --> shows current config\n" "lf config --> shows current config\n"
"lf config -b 8 --125 --> samples at 125 kHz, 8 bps\n" "lf config -b 8 --125 --> samples at 125 kHz, 8 bps\n"
"lf config -b 4 --134 --dec 3 --> samples at 134 kHz, averages three samples into one, stored with a resolution of 4 bits per sample" "lf config -b 4 --134 --dec 3 --> samples at 134 kHz, averages three samples into one, stored with a resolution of 4 bits per sample\n"
"lf config --trig 20 -s 10000 --> trigger sampling when above 20, skip 10 000 first samples after triggered\n" "lf config --trig 20 -s 10000 --> trigger sampling when above 20, skip 10 000 first samples after triggered\n"
); );
@ -503,6 +489,7 @@ int CmdLFConfig(const char *Cmd) {
arg_int0(NULL, "dec", "<1-8>", "sets decimation. A value of N saves only 1 in N samples (default 1)"), arg_int0(NULL, "dec", "<1-8>", "sets decimation. A value of N saves only 1 in N samples (default 1)"),
arg_int0(NULL, "divisor", "<19-255>", div_str), arg_int0(NULL, "divisor", "<19-255>", div_str),
arg_int0("f", "freq", "<47-600>", "manually set frequency in kHz"), arg_int0("f", "freq", "<47-600>", "manually set frequency in kHz"),
arg_lit0("r", "reset", "reset values to defaults"),
arg_int0("s", "skip", "<dec>", "sets a number of samples to skip before capture (default 0)"), arg_int0("s", "skip", "<dec>", "sets a number of samples to skip before capture (default 0)"),
arg_int0("t", "trig", "<0-128>", "sets trigger threshold. 0 means no threshold"), arg_int0("t", "trig", "<0-128>", "sets trigger threshold. 0 means no threshold"),
arg_param_end arg_param_end
@ -515,8 +502,9 @@ int CmdLFConfig(const char *Cmd) {
int8_t dec = arg_get_int_def(ctx, 5, -1); int8_t dec = arg_get_int_def(ctx, 5, -1);
int16_t div = arg_get_int_def(ctx, 6, -1); int16_t div = arg_get_int_def(ctx, 6, -1);
int16_t freq = arg_get_int_def(ctx, 7, -1); int16_t freq = arg_get_int_def(ctx, 7, -1);
int32_t skip = arg_get_int_def(ctx, 8, -1); bool reset = arg_get_lit(ctx, 8);
int16_t trigg = arg_get_int_def(ctx, 9, -1); int32_t skip = arg_get_int_def(ctx, 9, -1);
int16_t trigg = arg_get_int_def(ctx, 10, -1);
CLIParserFree(ctx); CLIParserFree(ctx);
if (session.pm3_present == false) if (session.pm3_present == false)
@ -542,12 +530,16 @@ int CmdLFConfig(const char *Cmd) {
.verbose = true .verbose = true
}; };
/* if (reset) {
int8_t bps = arg_get_int_def(ctx, 4, 8); config.decimation = 1;
int8_t dec = arg_get_int_def(ctx, 5, 1); config.bits_per_sample = 8;
int16_t div = arg_get_int_def(ctx, 6, 95); config.averaging = 1,
int16_t freq = arg_get_int_def(ctx, 7, 125); config.divisor = LF_DIVISOR_125;
*/ config.samples_to_skip = 0;
config.trigger_threshold = 0;
g_lf_threshold_set = false;
}
if (use_125) if (use_125)
config.divisor = LF_DIVISOR_125; config.divisor = LF_DIVISOR_125;
@ -657,7 +649,7 @@ int CmdLFRead(const char *Cmd) {
int ret = PM3_SUCCESS; int ret = PM3_SUCCESS;
do { do {
ret = lf_read(verbose, samples); ret = lf_read(verbose, samples);
} while (cm && !kbd_enter_pressed()); } while (cm && kbd_enter_pressed() == false);
return ret; return ret;
} }
@ -1524,7 +1516,7 @@ static command_t CommandTable[] = {
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
{"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"},
{"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read"},
{"read", CmdLFRead, IfPm3Lf, "Read LF tag"}, {"read", CmdLFRead, IfPm3Lf, "Read LF tag"},
{"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag"}, {"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag"},
{"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer"}, {"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer"},