From feeb32b13fdf0cd86520b6d773170d1b23c9e8a5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Dec 2020 01:45:03 +0100 Subject: [PATCH] lf tune - added possiblity to get bar / mix / value (defaul) output of measurements. Also set in preferences --- client/src/cmdlf.c | 121 ++++++++++++++++++++---------------- client/src/comms.h | 5 +- client/src/preferences.c | 128 ++++++++++++++++++++++++++++++++++++--- client/src/ui.c | 65 ++++++++++++++++++++ client/src/ui.h | 4 ++ client/src/util.h | 1 + 6 files changed, 261 insertions(+), 63 deletions(-) diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 89483bf00..4cc303f19 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -230,59 +230,61 @@ static int usage_lf_find(void) { PrintAndLogEx(NORMAL, _YELLOW_(" lf search 1 u") " - use data from GraphBuffer & search for known and unknown tags"); return PM3_SUCCESS; } -static int usage_lf_tune(void) { - PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); - PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); - PrintAndLogEx(NORMAL, "Usage: lf tune [h] [n ] [q | f ]"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " n - number of iterations (default: 0=infinite)"); - PrintAndLogEx(NORMAL, " q - Frequency divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); - PrintAndLogEx(NORMAL, " f - Frequency in kHz"); - return PM3_SUCCESS; -} static int CmdLFTune(const char *Cmd) { - int iter = 0; - uint8_t divisor = LF_DIVISOR_125;//Frequency divisor - bool errors = false; - uint8_t cmdp = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (param_getchar(Cmd, cmdp)) { - case 'h': - return usage_lf_tune(); - case 'q': - errors |= param_getdec(Cmd, cmdp + 1, &divisor); - cmdp += 2; - if (divisor < 19) { - PrintAndLogEx(ERR, "divisor must be between 19 and 255"); - return PM3_EINVARG; - } - break; - case 'f': { - float freq = param_getfloat(Cmd, cmdp + 1, 125); - if ((freq < 47) || (freq > 600)) { - PrintAndLogEx(ERR, "freq must be between 47 and 600"); - return PM3_EINVARG; - } - divisor = LF_FREQ2DIV(freq); - cmdp += 2; - break; - } - case 'n': - iter = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = 1; - break; - } + + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf tune", + "Continuously measure LF antenna tuning.\n" + "Press button or to interrupt.", + "lf tune" + ); + + char q_str[60]; + snprintf(q_str, sizeof(q_str), "Frequency divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); + void *argtable[] = { + arg_param_begin, + arg_u64_0("n", "iteration", "", "number of iterations (default: 0=infinite)"), + arg_u64_0("q", "divisor", "", q_str), + arg_dbl0("f", "freq", "", "Frequency in kHz"), + arg_lit0(NULL, "bar", "bar style"), + arg_lit0(NULL, "mix", "mixed style"), + arg_lit0(NULL, "value", "values style"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + uint32_t iter = arg_get_u32_def(ctx, 1, 0); + uint8_t divisor = arg_get_u32_def(ctx, 2, LF_DIVISOR_125); + double freq = arg_get_dbl_def(ctx, 3, 125); + + bool is_bar = arg_get_lit(ctx, 4); + bool is_mix = arg_get_lit(ctx, 5); + bool is_value = arg_get_lit(ctx, 6); + CLIParserFree(ctx); + + if (divisor < 19) { + PrintAndLogEx(ERR, "divisor must be between 19 and 255"); + return PM3_EINVARG; } - //Validations - if (errors) return usage_lf_tune(); + if ((freq < 47) || (freq > 600)) { + PrintAndLogEx(ERR, "freq must be between 47 and 600"); + return PM3_EINVARG; + } + divisor = LF_FREQ2DIV(freq); + + if ((is_bar + is_mix + is_value) > 1) { + PrintAndLogEx(ERR, "Select only one output style"); + return PM3_EINVARG; + } + + barMode_t style = session.bar_mode; + if (is_bar) + style = STYLE_BAR; + if (is_mix) + style = STYLE_MIXED; + if (is_value) + style = STYLE_VALUE; PrintAndLogEx(INFO, "Measuring LF antenna at " _YELLOW_("%.2f") " kHz, click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit", LF_DIV2FREQ(divisor)); @@ -298,6 +300,13 @@ static int CmdLFTune(const char *Cmd) { } params[0] = 2; + + #define MAX_ADC_LF_VOLTAGE 140800 + uint32_t max = 71000; + bool first = true; + + print_progress(0, max, style); + // loop forever (till button pressed) if iter = 0 (default) for (uint8_t i = 0; iter == 0 || i < iter; i++) { if (kbd_enter_pressed()) { @@ -308,15 +317,23 @@ static int CmdLFTune(const char *Cmd) { if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF measure, aborting"); - return PM3_ETIMEOUT; + break; } if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) { + PrintAndLogEx(NORMAL, ""); break; } uint32_t volt = resp.data.asDwords[0]; - PrintAndLogEx(INPLACE, " %u mV / %3u V", volt, (uint32_t)(volt / 1000)); + if (first) { + max = (volt * 1.03); + first = false; + } + if ( volt > max) { + max = (volt * 1.03); + } + print_progress(volt, max, style); } params[0] = 3; @@ -325,7 +342,7 @@ static int CmdLFTune(const char *Cmd) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF shutdown, aborting"); return PM3_ETIMEOUT; } - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "\x1b%c[2K\r", 30); PrintAndLogEx(INFO, "Done."); return PM3_SUCCESS; } diff --git a/client/src/comms.h b/client/src/comms.h index 3ee691a30..80ce543da 100644 --- a/client/src/comms.h +++ b/client/src/comms.h @@ -21,9 +21,7 @@ extern "C" { #endif #ifndef DropField -#define DropField() { \ - clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ - } +#define DropField() { clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); } #endif #ifndef DropFieldEx @@ -48,7 +46,6 @@ typedef enum { FPGA_MEM, } DeviceMemType_t; - typedef struct { bool run; // If TRUE, continue running the uart_communication thread bool block_after_ACK; // if true, block after receiving an ACK package diff --git a/client/src/preferences.c b/client/src/preferences.c index 9f507b969..b6b1eddd3 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -55,6 +55,7 @@ int preferences_load(void) { session.overlay_sliders = true; session.show_hints = true; + session.bar_mode = STYLE_VALUE; // setDefaultPath (spDefault, ""); // setDefaultPath (spDump, ""); // setDefaultPath (spTrace, ""); @@ -210,6 +211,20 @@ void preferences_save_callback(json_t *root) { default: JsonSaveStr(root, "logging.level", "NORMAL"); } + + switch (session.bar_mode) { + case STYLE_BAR: + JsonSaveStr(root, "show.bar.mode", "bar"); + break; + case STYLE_MIXED: + JsonSaveStr(root, "show.bar.mode", "mixed"); + break; + case STYLE_VALUE: + JsonSaveStr(root, "show.bar.mode", "value"); + break; + default: + JsonSaveStr(root, "show.bar.mode", "value"); + } /* switch (session.device_debug_level) { case ddbOFF: @@ -298,6 +313,16 @@ void preferences_load_callback(json_t *root) { if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0) session.supports_colors = (bool)b1; + + // bar mode + if (json_unpack_ex(root, &up_error, 0, "{s:s}", "show.bar.mode", &s1) == 0) { + strncpy(tempStr, s1, sizeof(tempStr) - 1); + str_lower(tempStr); + if (strncmp(tempStr, "bar", 5) == 0) session.bar_mode = STYLE_BAR; + if (strncmp(tempStr, "mixed", 5) == 0) session.bar_mode = STYLE_MIXED; + if (strncmp(tempStr, "value", 7) == 0) session.bar_mode = STYLE_VALUE; + } + /* // Logging Level if (json_unpack_ex(root, &up_error, 0, "{s:s}", "device.debug.level", &s1) == 0) { @@ -343,6 +368,17 @@ static int usage_set_debug(void) { PrintAndLogEx(NORMAL, " "_GREEN_("full")" - full debug messages"); return PM3_SUCCESS; } + +static int usage_set_bar_mode(void) { + PrintAndLogEx(NORMAL, "Usage: pref set barmode "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); + PrintAndLogEx(NORMAL, " "_GREEN_("bar")" - measured values as bar only"); + PrintAndLogEx(NORMAL, " "_GREEN_("mixed")" - measured values as numbers and bar"); + PrintAndLogEx(NORMAL, " "_GREEN_("value")" - measured values"); + return PM3_SUCCESS; +} + /* static int usage_set_devicedebug(void) { PrintAndLogEx(NORMAL, "Usage: pref set devicedebug "); @@ -521,6 +557,23 @@ static void showPlotSliderState(prefShowOpt_t opt) { PrintAndLogEx(INFO, " %s show plot sliders...... "_WHITE_("off"), prefShowMsg(opt)); } +static void showBarModeState(prefShowOpt_t opt) { + + switch (session.bar_mode) { + case STYLE_BAR: + PrintAndLogEx(INFO, " %s mode................... "_GREEN_("bar"), prefShowMsg(opt)); + break; + case STYLE_MIXED: + PrintAndLogEx(INFO, " %s mode................... "_GREEN_("mixed"), prefShowMsg(opt)); + break; + case STYLE_VALUE: + PrintAndLogEx(INFO, " %s mode................... "_GREEN_("value"), prefShowMsg(opt)); + break; + default: + PrintAndLogEx(INFO, " %s mode.................. "_RED_("unknown"), prefShowMsg(opt)); + } +} + static int setCmdEmoji(const char *Cmd) { uint8_t cmdp = 0; @@ -921,6 +974,57 @@ static int getCmdHelp(const char *Cmd) { } */ +static int setCmdBarMode(const char *Cmd) { + uint8_t cmdp = 0; + bool errors = false; + bool validValue = false; + char strOpt[50]; + barMode_t newValue = session.bar_mode; + + if (param_getchar(Cmd, cmdp) == 0x00) + return usage_set_bar_mode(); + + while ((param_getchar(Cmd, cmdp) != 0x00) && !errors) { + + if (param_getstr(Cmd, cmdp++, strOpt, sizeof(strOpt)) != 0) { + str_lower(strOpt); // convert to lowercase + + if (strncmp(strOpt, "help", 4) == 0) + return usage_set_bar_mode(); + + if (strncmp(strOpt, "bar", 3) == 0) { + validValue = true; + newValue = STYLE_BAR; + } + if (strncmp(strOpt, "mixed", 5) == 0) { + validValue = true; + newValue = STYLE_MIXED; + } + if (strncmp(strOpt, "value", 5) == 0) { + validValue = true; + newValue = STYLE_VALUE; + } + + if (validValue) { + if (session.bar_mode != newValue) {// changed + showBarModeState(prefShowOLD); + session.bar_mode = newValue; + showBarModeState(prefShowNEW); + preferences_save(); + } else { + PrintAndLogEx(INFO, "nothing changed"); + showBarModeState(prefShowNone); + } + } else { + PrintAndLogEx(ERR, "invalid option"); + return usage_set_bar_mode(); + } + } + } + + return PM3_SUCCESS; +} + static int getCmdEmoji(const char *Cmd) { showEmojiState(prefShowNone); return PM3_SUCCESS; @@ -946,27 +1050,35 @@ static int getCmdPlotSlider(const char *Cmd) { return PM3_SUCCESS; } +static int getCmdBarMode(const char *Cmd) { + showBarModeState(prefShowNone); + return PM3_SUCCESS; +} + + static command_t getCommandTable[] = { // {"help", getCmdHelp, AlwaysAvailable, "This help"}, - {"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"}, - {"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"}, + {"barmode", getCmdBarMode, AlwaysAvailable, "Get bar mode preference"}, + {"clientdebug", getCmdDebug, AlwaysAvailable, "Get client debug level preference"}, {"color", getCmdColor, AlwaysAvailable, "Get color support preference"}, // {"defaultsavepaths", getCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "}, - {"clientdebug", getCmdDebug, AlwaysAvailable, "Get client debug level preference"}, - {"plotsliders", getCmdPlotSlider, AlwaysAvailable, "Get plot slider display preference"}, // {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"}, + {"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"}, + {"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"}, + {"plotsliders", getCmdPlotSlider, AlwaysAvailable, "Get plot slider display preference"}, {NULL, NULL, NULL, NULL} }; static command_t setCommandTable[] = { {"help", setCmdHelp, AlwaysAvailable, "This help"}, + {"barmode", setCmdBarMode, AlwaysAvailable, "Set bar mode"}, + {"clientdebug", setCmdDebug, AlwaysAvailable, "Set client debug level"}, + {"color", setCmdColor, AlwaysAvailable, "Set color support"}, {"emoji", setCmdEmoji, AlwaysAvailable, "Set emoji display"}, {"hints", setCmdHint, AlwaysAvailable, "Set hint display"}, - {"color", setCmdColor, AlwaysAvailable, "Set color support"}, // {"defaultsavepaths", setCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "}, - {"clientdebug", setCmdDebug, AlwaysAvailable, "Set client debug level"}, - {"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"}, // {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"}, + {"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"}, {NULL, NULL, NULL, NULL} }; @@ -1009,6 +1121,8 @@ static int CmdPrefShow(const char *Cmd) { showClientDebugState(prefShowNone); showPlotSliderState(prefShowNone); // showDeviceDebugState(prefShowNone); + + showBarModeState(prefShowNone); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/src/ui.c b/client/src/ui.c index 6e8c73c27..03ff304b2 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -624,4 +624,69 @@ void iceSimple_Filter(int *data, const size_t len, uint8_t k) { } } +void print_progress(size_t count, uint64_t max, barMode_t style) { + #define PERCENTAGE(V, T) (100 - (((T - V) * 100) / T)) + +/* + typedef struct smooth_s { + const char *bar; + } smooth_t; + + static smooth_t smoothtable[] = { + {"\xe2\x96\x8F"}, + {"\xe2\x96\x8E"}, + {"\xe2\x96\x8D"}, + {"\xe2\x96\x8C"}, + {"\xe2\x96\x8B"}, + {"\xe2\x96\x8A"}, + {"\xe2\x96\x89"}, + {"\xe2\x96\x88"}, + }; +*/ + + // +1 for \0 + char *bar = calloc(100 + 1, sizeof(uint8_t)); + + uint8_t value = PERCENTAGE(count, max); + + // prefix is added already. + memset(bar + strlen(bar), 0x23, value); + + // add spaces + memset(bar + strlen(bar), 0x2E, 100 - value); + + // color buffer + uint8_t collen = 100 + 1 + 40; + char *cbar = calloc(collen, sizeof(uint8_t)); + + // Add colors + snprintf(cbar, collen, _GREEN_("%.*s"), 60, bar); + snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), 20, bar + 60); + snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), 20, bar + 80); + + uint8_t len = collen + 1 + 1 + 30; + char *buffer = calloc(len, sizeof(uint8_t)); + + switch(style) { + case STYLE_BAR: { + sprintf(buffer, "%s", cbar); + printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, buffer); + break; + } + case STYLE_MIXED: { + sprintf(buffer, "%s [ %zu mV / %3u V ]", cbar, count, (uint32_t)(count / 1000)); + printf("\b%c[2K\r[" _YELLOW_("=")"] %s ", 27, buffer); + break; + } + case STYLE_VALUE: { + printf("[" _YELLOW_("=")"] %zu mV / %3u V \r", count, (uint32_t)(count / 1000)); + break; + } + } + + fflush(stdout); + free(buffer); + free(bar); + free(cbar); +} diff --git a/client/src/ui.h b/client/src/ui.h index 1a8a14028..30d055b16 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -22,6 +22,7 @@ extern "C" { #define _USE_MATH_DEFINES +typedef enum {STYLE_BAR, STYLE_MIXED, STYLE_VALUE} barMode_t; typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; typedef enum emojiMode {ALIAS, EMOJI, ALTTEXT, ERASE} emojiMode_t; typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t; @@ -45,6 +46,7 @@ typedef struct { bool incognito; // char *defaultPaths[spItemCount]; // Array should allow loop searching for files clientdebugLevel_t client_debug_level; + barMode_t bar_mode; // uint8_t device_debug_level; char *history_path; pm3_device *current_device; @@ -69,6 +71,8 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam extern pthread_mutex_t print_lock; +void print_progress(size_t count, uint64_t max, barMode_t style); + void iceIIR_Butterworth(int *data, const size_t len); void iceSimple_Filter(int *data, const size_t len, uint8_t k); #ifdef __cplusplus diff --git a/client/src/util.h b/client/src/util.h index 66b72491f..573997d61 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -108,4 +108,5 @@ uint32_t bitcount32(uint32_t a); uint64_t bitcount64(uint64_t a); uint32_t leadingzeros32(uint32_t a); uint64_t leadingzeros64(uint64_t a); + #endif