1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
5 //-----------------------------------------------------------------------------
6 // Preferences Functions
7 //-----------------------------------------------------------------------------
9 // To add a new setting
10 // Add the new setting to the session_arg_t; in ui.h
11 // Add the default value for the setting in the settings_load page below
12 // Update the preferences_load_callback to load your setting into the stucture
13 // Update the preferences_save_callback to ensure your setting gets saved when needed.
14 // use the preference as needed : session.<preference name>
15 // Can use (session.preferences_loaded) to check if json settings file was used
16 //-----------------------------------------------------------------------------
18 #include "preferences.h"
20 #include "emv/emvjson.h"
22 #include "cmdparser.h"
25 #include <proxmark3.h>
26 #include "cliparser.h"
28 static int CmdHelp(const char *Cmd
);
29 static int setCmdHelp(const char *Cmd
);
31 static char *prefGetFilename(void) {
34 if (searchHomeFilePath(&path
, NULL
, preferencesFilename
, false) == PM3_SUCCESS
)
37 return strdup(preferencesFilename
);
40 int preferences_load(void) {
43 session
.client_debug_level
= cdbOFF
;
44 // session.device_debug_level = ddbOFF;
45 session
.window_changed
= false;
50 session
.overlay
.x
= session
.plot
.x
;
51 session
.overlay
.y
= 60 + session
.plot
.y
+ session
.plot
.h
;
52 session
.overlay
.h
= 200;
53 session
.overlay
.w
= session
.plot
.w
;
54 session
.overlay_sliders
= true;
55 session
.show_hints
= true;
57 session
.bar_mode
= STYLE_VALUE
;
58 setDefaultPath(spDefault
, "");
59 setDefaultPath(spDump
, "");
60 setDefaultPath(spTrace
, "");
63 if (get_my_user_directory() != NULL
) // should return path to .proxmark3 folder
64 setDefaultPath(spDefault
, get_my_user_directory());
66 setDefaultPath(spDefault
, ".");
69 if (get_my_user_directory() != NULL
) // should return path to .proxmark3 folder
70 setDefaultPath(spDump
, get_my_user_directory());
72 setDefaultPath(spDump
, ".");
75 if (get_my_user_directory() != NULL
) // should return path to .proxmark3 folder
76 setDefaultPath(spTrace
, get_my_user_directory());
78 setDefaultPath(spTrace
, ".");
80 if (session
.incognito
) {
81 PrintAndLogEx(INFO
, "No preferences file will be loaded");
85 // loadFileJson wants these, so pass in place holder values, though not used
87 uint8_t dummyData
= 0x00;
88 size_t dummyDL
= 0x00;
90 // to better control json cant find file error msg.
91 char *fn
= prefGetFilename();
93 if (loadFileJSON(fn
, &dummyData
, sizeof(dummyData
), &dummyDL
, &preferences_load_callback
) == PM3_SUCCESS
) {
94 session
.preferences_loaded
= true;
98 // Note, if session.settings_loaded == false then the settings_save
99 // will be called in main () to save settings as set in defaults and main() checks.
104 // Save all settings from memory (struct) to file
105 int preferences_save(void) {
106 // Note sure if backup has value ?
107 if (session
.incognito
) {
108 PrintAndLogEx(INFO
, "No preferences file will be saved");
111 PrintAndLogEx(INFO
, "Saving preferences...");
113 char *fn
= prefGetFilename();
114 int fnLen
= strlen(fn
) + 5; // .bak\0
116 // [FILENAME_MAX+sizeof(preferencesFilename)+10]
117 char *backupFilename
= (char *)calloc(fnLen
, sizeof(uint8_t));
118 if (backupFilename
== NULL
) {
119 PrintAndLogEx(ERR
, "failed to allocate memory");
123 snprintf(backupFilename
, fnLen
, "%s.bak", fn
);
125 if (fileExists(backupFilename
)) {
126 if (remove(backupFilename
) != 0) {
127 PrintAndLogEx(FAILED
, "Error - could not delete old settings backup file \"%s\"", backupFilename
);
129 free(backupFilename
);
134 if (fileExists(fn
)) {
135 if (rename(fn
, backupFilename
) != 0) {
136 PrintAndLogEx(FAILED
, "Error - could not backup settings file \"%s\" to \"%s\"", fn
, backupFilename
);
138 free(backupFilename
);
143 uint8_t dummyData
= 0x00;
144 size_t dummyDL
= 0x00;
146 if (saveFileJSON(fn
, jsfCustom
, &dummyData
, dummyDL
, &preferences_save_callback
) != PM3_SUCCESS
)
147 PrintAndLogEx(ERR
, "Error saving preferences to \"%s\"", fn
);
150 free(backupFilename
);
154 void preferences_save_callback(json_t
*root
) {
156 JsonSaveStr(root
, "FileType", "settings");
159 switch (session
.emoji_mode
) {
161 JsonSaveStr(root
, "show.emoji", "alias");
164 JsonSaveStr(root
, "show.emoji", "emoji");
167 JsonSaveStr(root
, "show.emoji", "alttext");
170 JsonSaveStr(root
, "show.emoji", "none");
173 JsonSaveStr(root
, "show.emoji", "ALIAS");
176 JsonSaveBoolean(root
, "show.hints", session
.show_hints
);
178 JsonSaveBoolean(root
, "os.supports.colors", session
.supports_colors
);
180 JsonSaveStr(root
, "file.default.savepath", session
.defaultPaths
[spDefault
]);
181 JsonSaveStr(root
, "file.default.dumppath", session
.defaultPaths
[spDump
]);
182 JsonSaveStr(root
, "file.default.tracepath", session
.defaultPaths
[spTrace
]);
185 JsonSaveInt(root
, "window.plot.xpos", session
.plot
.x
);
186 JsonSaveInt(root
, "window.plot.ypos", session
.plot
.y
);
187 JsonSaveInt(root
, "window.plot.hsize", session
.plot
.h
);
188 JsonSaveInt(root
, "window.plot.wsize", session
.plot
.w
);
190 // Overlay/Slider window
191 JsonSaveInt(root
, "window.overlay.xpos", session
.overlay
.x
);
192 JsonSaveInt(root
, "window.overlay.ypos", session
.overlay
.y
);
193 JsonSaveInt(root
, "window.overlay.hsize", session
.overlay
.h
);
194 JsonSaveInt(root
, "window.overlay.wsize", session
.overlay
.w
);
195 JsonSaveBoolean(root
, "window.overlay.sliders", session
.overlay_sliders
);
197 // Log level, convert to text
198 switch (session
.client_debug_level
) {
200 JsonSaveStr(root
, "client.debug.level", "off");
203 JsonSaveStr(root
, "client.debug.level", "simple");
206 JsonSaveStr(root
, "client.debug.level", "full");
209 JsonSaveStr(root
, "logging.level", "NORMAL");
212 switch (session
.bar_mode
) {
214 JsonSaveStr(root
, "show.bar.mode", "bar");
217 JsonSaveStr(root
, "show.bar.mode", "mixed");
220 JsonSaveStr(root
, "show.bar.mode", "value");
223 JsonSaveStr(root
, "show.bar.mode", "value");
226 switch (session.device_debug_level) {
228 JsonSaveStr(root, "device.debug.level", "off");
231 JsonSaveStr(root, "device.debug.level", "error");
234 JsonSaveStr(root, "device.debug.level", "info");
237 JsonSaveStr(root, "device.debug.level", "debug");
240 JsonSaveStr(root, "device.debug.level", "extended");
243 JsonSaveStr(root, "logging.level", "NORMAL");
247 void preferences_load_callback(json_t
*root
) {
248 json_error_t up_error
= {0};
252 char tempStr
[500]; // to use str_lower() since json unpack uses const char *
255 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "client.debug.level", &s1
) == 0) {
256 strncpy(tempStr
, s1
, sizeof(tempStr
) - 1);
258 if (strncmp(tempStr
, "off", 3) == 0) session
.client_debug_level
= cdbOFF
;
259 if (strncmp(tempStr
, "simple", 6) == 0) session
.client_debug_level
= cdbSIMPLE
;
260 if (strncmp(tempStr
, "full", 4) == 0) session
.client_debug_level
= cdbFULL
;
264 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "file.default.savepath", &s1
) == 0)
265 setDefaultPath(spDefault
, s1
);
268 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "file.default.dumppath", &s1
) == 0)
269 setDefaultPath(spDump
, s1
);
271 // default trace path
272 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "file.default.tracepath", &s1
) == 0)
273 setDefaultPath(spTrace
, s1
);
276 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.plot.xpos", &i1
) == 0)
278 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.plot.ypos", &i1
) == 0)
280 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.plot.hsize", &i1
) == 0)
282 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.plot.wsize", &i1
) == 0)
285 // overlay/slider plot
286 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.overlay.xpos", &i1
) == 0)
287 session
.overlay
.x
= i1
;
288 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.overlay.ypos", &i1
) == 0)
289 session
.overlay
.y
= i1
;
290 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.overlay.hsize", &i1
) == 0)
291 session
.overlay
.h
= i1
;
292 if (json_unpack_ex(root
, &up_error
, 0, "{s:i}", "window.overlay.wsize", &i1
) == 0)
293 session
.overlay
.w
= i1
;
294 if (json_unpack_ex(root
, &up_error
, 0, "{s:b}", "window.overlay.sliders", &b1
) == 0)
295 session
.overlay_sliders
= (bool)b1
;
298 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "show.emoji", &s1
) == 0) {
299 strncpy(tempStr
, s1
, sizeof(tempStr
) - 1);
301 if (strncmp(tempStr
, "alias", 5) == 0) session
.emoji_mode
= EMO_ALIAS
;
302 if (strncmp(tempStr
, "emoji", 5) == 0) session
.emoji_mode
= EMO_EMOJI
;
303 if (strncmp(tempStr
, "alttext", 7) == 0) session
.emoji_mode
= EMO_ALTTEXT
;
304 if (strncmp(tempStr
, "none", 4) == 0) session
.emoji_mode
= EMO_NONE
;
307 if (json_unpack_ex(root
, &up_error
, 0, "{s:b}", "show.hints", &b1
) == 0)
308 session
.show_hints
= (bool)b1
;
310 if (json_unpack_ex(root
, &up_error
, 0, "{s:b}", "os.supports.colors", &b1
) == 0)
311 session
.supports_colors
= (bool)b1
;
314 if (json_unpack_ex(root
, &up_error
, 0, "{s:s}", "show.bar.mode", &s1
) == 0) {
315 strncpy(tempStr
, s1
, sizeof(tempStr
) - 1);
317 if (strncmp(tempStr
, "bar", 5) == 0) session
.bar_mode
= STYLE_BAR
;
318 if (strncmp(tempStr
, "mixed", 5) == 0) session
.bar_mode
= STYLE_MIXED
;
319 if (strncmp(tempStr
, "value", 7) == 0) session
.bar_mode
= STYLE_VALUE
;
324 if (json_unpack_ex(root, &up_error, 0, "{s:s}", "device.debug.level", &s1) == 0) {
325 strncpy(tempStr, s1, sizeof(tempStr) - 1);
327 if (strncmp(tempStr, "off", 3) == 0) session.device_debug_level = ddbOFF;
328 if (strncmp(tempStr, "error", 5) == 0) session.device_debug_level = ddbERROR;
329 if (strncmp(tempStr, "info", 4) == 0) session.device_debug_level = ddbINFO;
330 if (strncmp(tempStr, "debug", 5) == 0) session.device_debug_level = ddbDEBUG;
331 if (strncmp(tempStr, "extended", 8) == 0) session.device_debug_level = ddbEXTENDED;
338 // Preference Processing Functions
339 // typedef enum preferenceId {prefNONE,prefHELP,prefEMOJI,prefCOLOR,prefPLOT,prefOVERLAY,prefHINTS,prefCLIENTDEBUG} preferenceId_t;
340 typedef enum prefShowOpt
{prefShowNone
, prefShowOLD
, prefShowNEW
} prefShowOpt_t
;
342 static const char *prefShowMsg(prefShowOpt_t Opt
) {
345 return "( " _YELLOW_("old") " )";
347 return "( " _GREEN_("new") " )";
354 static void showEmojiState(prefShowOpt_t opt
) {
356 switch (session
.emoji_mode
) {
358 PrintAndLogEx(INFO
, " %s emoji.................. "_GREEN_("alias"), prefShowMsg(opt
));
361 PrintAndLogEx(INFO
, " %s emoji.................. "_GREEN_("emoji"), prefShowMsg(opt
));
364 PrintAndLogEx(INFO
, " %s emoji.................. "_GREEN_("alttext"), prefShowMsg(opt
));
367 PrintAndLogEx(INFO
, " %s emoji.................. "_GREEN_("none"), prefShowMsg(opt
));
370 PrintAndLogEx(INFO
, " %s emoji.................. "_RED_("unknown"), prefShowMsg(opt
));
374 static void showColorState(prefShowOpt_t opt
) {
376 if (session
.supports_colors
)
377 PrintAndLogEx(INFO
, " %s color.................. "_GREEN_("ansi"), prefShowMsg(opt
));
379 PrintAndLogEx(INFO
, " %s color.................. "_WHITE_("off"), prefShowMsg(opt
));
382 static void showClientDebugState(prefShowOpt_t opt
) {
384 switch (session
.client_debug_level
) {
386 PrintAndLogEx(INFO
, " %s client debug........... "_WHITE_("off"), prefShowMsg(opt
));
389 PrintAndLogEx(INFO
, " %s client debug........... "_GREEN_("simple"), prefShowMsg(opt
));
392 PrintAndLogEx(INFO
, " %s client debug........... "_GREEN_("full"), prefShowMsg(opt
));
395 PrintAndLogEx(INFO
, " %s client debug........... "_RED_("unknown"), prefShowMsg(opt
));
399 static void showDeviceDebugState(prefShowOpt_t opt) {
400 switch (session.device_debug_level) {
402 PrintAndLogEx(INFO, " %s device debug........... "_WHITE_("off"), prefShowMsg(opt));
405 PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("error"), prefShowMsg(opt));
408 PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("info"), prefShowMsg(opt));
411 PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("debug"), prefShowMsg(opt));
414 PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("extended"), prefShowMsg(opt));
417 PrintAndLogEx(INFO, " %s device debug........... "_RED_("unknown"), prefShowMsg(opt));
422 static void showSavePathState(savePaths_t path_index
, prefShowOpt_t opt
) {
425 switch (path_index
) {
427 strcpy(s
, "default save path......");
430 strcpy(s
, "dump save path.........");
433 strcpy(s
, "trace save path........");
437 strcpy(s
, _RED_("unknown")" save path......");
440 if (path_index
< spItemCount
) {
441 if ((session
.defaultPaths
[path_index
] == NULL
) || (strcmp(session
.defaultPaths
[path_index
], "") == 0)) {
442 PrintAndLogEx(INFO
, " %s %s "_WHITE_("not set"),
447 PrintAndLogEx(INFO
, " %s %s "_GREEN_("%s"),
450 session
.defaultPaths
[path_index
]
456 static void showPlotPosState(void) {
457 PrintAndLogEx(INFO
, " Plot window............ X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"),
465 static void showOverlayPosState(void) {
466 PrintAndLogEx(INFO
, " Slider/Overlay window.. X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"),
474 static void showHintsState(prefShowOpt_t opt
) {
475 if (session
.show_hints
)
476 PrintAndLogEx(INFO
, " %s hints.................. "_GREEN_("on"), prefShowMsg(opt
));
478 PrintAndLogEx(INFO
, " %s hints.................. "_WHITE_("off"), prefShowMsg(opt
));
481 static void showPlotSliderState(prefShowOpt_t opt
) {
482 if (session
.overlay_sliders
)
483 PrintAndLogEx(INFO
, " %s show plot sliders...... "_GREEN_("on"), prefShowMsg(opt
));
485 PrintAndLogEx(INFO
, " %s show plot sliders...... "_WHITE_("off"), prefShowMsg(opt
));
488 static void showBarModeState(prefShowOpt_t opt
) {
490 switch (session
.bar_mode
) {
492 PrintAndLogEx(INFO
, " %s barmode................ "_GREEN_("bar"), prefShowMsg(opt
));
495 PrintAndLogEx(INFO
, " %s barmode................ "_GREEN_("mixed"), prefShowMsg(opt
));
498 PrintAndLogEx(INFO
, " %s barmode................ "_GREEN_("value"), prefShowMsg(opt
));
501 PrintAndLogEx(INFO
, " %s barmode............... "_RED_("unknown"), prefShowMsg(opt
));
505 static int setCmdEmoji(const char *Cmd
) {
506 CLIParserContext
*ctx
;
507 CLIParserInit(&ctx
, "prefs set emoji ",
508 "Set presistent preference of using emojis in the client",
509 "prefs set emoji --alias"
514 arg_lit0(NULL
, "alias", "show alias for emoji"),
515 arg_lit0(NULL
, "emoji", "show emoji"),
516 arg_lit0(NULL
, "alttext", "show alt text for emoji"),
517 arg_lit0(NULL
, "none", "don't show emoji or text"),
520 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
521 bool show_a
= arg_get_lit(ctx
, 1);
522 bool show_e
= arg_get_lit(ctx
, 2);
523 bool show_alt
= arg_get_lit(ctx
, 3);
524 bool show_none
= arg_get_lit(ctx
, 4);
527 if ((show_a
+ show_e
+ show_alt
+ show_none
) > 1) {
528 PrintAndLogEx(FAILED
, "Can only set one option");
532 emojiMode_t new_value
= session
.emoji_mode
;
535 new_value
= EMO_ALIAS
;
538 new_value
= EMO_EMOJI
;
541 new_value
= EMO_ALTTEXT
;
544 new_value
= EMO_NONE
;
547 if (session
.emoji_mode
!= new_value
) {// changed
548 showEmojiState(prefShowOLD
);
549 session
.emoji_mode
= new_value
;
550 showEmojiState(prefShowNEW
);
553 showEmojiState(prefShowNone
);
559 static int setCmdColor(const char *Cmd
) {
560 CLIParserContext
*ctx
;
561 CLIParserInit(&ctx
, "prefs set color ",
562 "Set presistent preference of using colors in the client",
563 "prefs set color --ansi"
568 arg_lit0(NULL
, "ansi", "use ANSI colors"),
569 arg_lit0(NULL
, "off", "don't use colors"),
572 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
573 bool use_c
= arg_get_lit(ctx
, 1);
574 bool use_n
= arg_get_lit(ctx
, 2);
577 if ((use_c
+ use_n
) > 1) {
578 PrintAndLogEx(FAILED
, "Can only set one option");
582 bool new_value
= session
.supports_colors
;
591 if (session
.supports_colors
!= new_value
) {
592 showColorState(prefShowOLD
);
593 session
.supports_colors
= new_value
;
594 showColorState(prefShowNEW
);
597 showColorState(prefShowNone
);
603 static int setCmdDebug(const char *Cmd
) {
604 CLIParserContext
*ctx
;
605 CLIParserInit(&ctx
, "prefs set clientdebug ",
606 "Set presistent preference of using clientside debug level",
607 "prefs set clientdebug --simple"
612 arg_lit0(NULL
, "off", "no debug messages"),
613 arg_lit0(NULL
, "simple", "simple debug messages"),
614 arg_lit0(NULL
, "full", "full debug messages"),
617 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
618 bool use_off
= arg_get_lit(ctx
, 1);
619 bool use_simple
= arg_get_lit(ctx
, 2);
620 bool use_full
= arg_get_lit(ctx
, 3);
623 if ((use_off
+ use_simple
+ use_full
) > 1) {
624 PrintAndLogEx(FAILED
, "Can only set one option");
628 clientdebugLevel_t new_value
= session
.client_debug_level
;
634 new_value
= cdbSIMPLE
;
640 if (session
.client_debug_level
!= new_value
) {
641 showClientDebugState(prefShowOLD
);
642 session
.client_debug_level
= new_value
;
643 g_debugMode
= new_value
;
644 showClientDebugState(prefShowNEW
);
647 showClientDebugState(prefShowNone
);
653 static int setCmdDeviceDebug (const char *Cmd)
655 CLIParserContext *ctx;
656 CLIParserInit(&ctx, "prefs set devicedebug ",
657 "Set presistent preference of device side debug level",
658 "prefs set devicedebug --on"
663 arg_lit0(NULL, "off", "no debug messages"),
664 arg_lit0(NULL, "error", "error messages"),
665 arg_lit0(NULL, "info", "info messages"),
666 arg_lit0(NULL, "dbg", "debug messages"),
667 arg_lit0(NULL, "ext", "extended debug messages"),
670 CLIExecWithReturn(ctx, Cmd, argtable, true);
671 bool use_off = arg_get_lit(ctx, 1);
672 bool use_err = arg_get_lit(ctx, 2);
673 bool use_info = arg_get_lit(ctx, 3);
674 bool use_dbg = arg_get_lit(ctx, 4);
675 bool use_ext = arg_get_lit(ctx, 5);
678 if ( (use_off + use_err + use_info + use_dbg + use_ext) > 1) {
679 PrintAndLogEx(FAILED, "Can only set one option");
683 devicedebugLevel_t new_value = session.device_debug_level;
689 new_value = ddbERROR;
695 new_value = ddbDEBUG;
698 new_value = ddbEXTENDED;
701 if (session.device_debug_level != new_value) {// changed
702 showDeviceDebugState (prefShowOLD);
703 session.device_debug_level = new_value;
704 showDeviceDebugState (prefShowNEW);
707 showDeviceDebugState (prefShowNone);
710 if (session.pm3_present) {
711 PrintAndLogEx (INFO,"setting device debug loglevel");
712 SendCommandNG(CMD_SET_DBGMODE, &session.device_debug_level, 1);
713 PacketResponseNG resp;
714 if (WaitForResponseTimeout(CMD_SET_DBGMODE, &resp, 2000) == false)
715 PrintAndLogEx (WARNING,"failed to set device debug loglevel");
721 static int setCmdHint(const char *Cmd
) {
722 CLIParserContext
*ctx
;
723 CLIParserInit(&ctx
, "prefs set hints ",
724 "Set presistent preference of showing hint messages in the client",
725 "prefs set hints --on"
730 arg_lit0(NULL
, "off", "hide hints"),
731 arg_lit0(NULL
, "on", "show hints"),
734 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
735 bool use_off
= arg_get_lit(ctx
, 1);
736 bool use_on
= arg_get_lit(ctx
, 2);
739 if ((use_off
+ use_on
) > 1) {
740 PrintAndLogEx(FAILED
, "Can only set one option");
744 bool new_value
= session
.show_hints
;
752 if (session
.show_hints
!= new_value
) {
753 showHintsState(prefShowOLD
);
754 session
.show_hints
= new_value
;
755 showHintsState(prefShowNEW
);
758 showHintsState(prefShowNone
);
764 static int setCmdPlotSliders(const char *Cmd
) {
765 CLIParserContext
*ctx
;
766 CLIParserInit(&ctx
, "prefs set plotsliders",
767 "Set presistent preference of showing the plotslider control in the client",
768 "prefs set plotsliders --on"
773 arg_lit0(NULL
, "off", "hide plot slider controls"),
774 arg_lit0(NULL
, "on", "show plot slider controls"),
777 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
778 bool use_off
= arg_get_lit(ctx
, 1);
779 bool use_on
= arg_get_lit(ctx
, 2);
782 if ((use_off
+ use_on
) > 1) {
783 PrintAndLogEx(FAILED
, "Can only set one option");
787 bool new_value
= session
.overlay_sliders
;
795 if (session
.overlay_sliders
!= new_value
) {
796 showPlotSliderState(prefShowOLD
);
797 session
.overlay_sliders
= new_value
;
798 showPlotSliderState(prefShowNEW
);
801 showPlotSliderState(prefShowNone
);
806 static int setCmdSavePaths(const char *Cmd
) {
807 CLIParserContext
*ctx
;
808 CLIParserInit(&ctx
, "prefs set savepaths",
809 "Set presistent preference of file paths in the client",
810 "prefs set savepaths --dump /home/mydumpfolder -> all dump files will be saved into this folder\n"
811 "prefs set savepaths --def /home/myfolder -c -> create if needed, all files will be saved into this folder"
816 arg_lit0("c", "create", "create directory if it does not exist"),
817 arg_str0(NULL
, "def", "<path>", "default path"),
818 arg_str0(NULL
, "dump", "<path>", "dump file path"),
819 arg_str0(NULL
, "trace", "<path>", "trace path"),
822 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
823 bool create_dir
= arg_get_lit(ctx
, 1);
826 char def_path
[FILE_PATH_SIZE
] = {0};
827 CLIParamStrToBuf(arg_get_str(ctx
, 2), (uint8_t *)def_path
, FILE_PATH_SIZE
, &deflen
);
830 char dump_path
[FILE_PATH_SIZE
] = {0};
831 CLIParamStrToBuf(arg_get_str(ctx
, 3), (uint8_t *)dump_path
, FILE_PATH_SIZE
, &dulen
);
834 char trace_path
[FILE_PATH_SIZE
] = {0};
835 CLIParamStrToBuf(arg_get_str(ctx
, 4), (uint8_t *)trace_path
, FILE_PATH_SIZE
, &tlen
);
838 if (deflen
== 0 && dulen
== 0 && tlen
== 0) {
839 PrintAndLogEx(FAILED
, "Must give at least one path");
843 savePaths_t path_item
= spItemCount
;
846 path_item
= spDefault
;
858 // remove trailing slash.
859 size_t nplen
= strlen(path
);
860 if ((path
[nplen
- 1] == '/') || (path
[nplen
- 1] == '\\')) {
861 path
[nplen
- 1] = 0x00;
865 if (fileExists(path
) == false && create_dir
== false) {
866 PrintAndLogEx(ERR
, "path does not exist... "_RED_("%s"), path
);
869 // do we need to create it
870 // if (!fileExists(newValue))
871 // create_path (newValue); //mkdir (newValue,0x777);
873 if (path_item
< spItemCount
) {
874 if (strcmp(path
, session
.defaultPaths
[path_item
]) != 0) {
875 showSavePathState(path_item
, prefShowOLD
);
876 setDefaultPath(path_item
, path
);
877 showSavePathState(path_item
, prefShowNEW
);
880 showSavePathState(path_item
, prefShowNone
);
887 static int setCmdBarMode(const char *Cmd
) {
888 CLIParserContext
*ctx
;
889 CLIParserInit(&ctx
, "prefs set barmode",
890 "Set presistent preference of HF/LF tune command styled output in the client",
891 "prefs set barmode --mix"
896 arg_lit0(NULL
, "bar", "measured values as bar only"),
897 arg_lit0(NULL
, "mix", "measured values as numbers and bar"),
898 arg_lit0(NULL
, "val", "measured values only"),
901 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
902 bool show_bar
= arg_get_lit(ctx
, 1);
903 bool show_mix
= arg_get_lit(ctx
, 2);
904 bool show_val
= arg_get_lit(ctx
, 3);
907 if ((show_bar
+ show_mix
+ show_val
) > 1) {
908 PrintAndLogEx(FAILED
, "Can only set one option");
912 barMode_t new_value
= session
.bar_mode
;
914 new_value
= STYLE_BAR
;
917 new_value
= STYLE_MIXED
;
920 new_value
= STYLE_VALUE
;
923 if (session
.bar_mode
!= new_value
) {
924 showBarModeState(prefShowOLD
);
925 session
.bar_mode
= new_value
;
926 showBarModeState(prefShowNEW
);
929 showBarModeState(prefShowNone
);
934 static int getCmdEmoji(const char *Cmd
) {
935 CLIParserContext
*ctx
;
936 CLIParserInit(&ctx
, "prefs get emoji",
937 "Get preference of using emojis in the client",
944 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
946 showEmojiState(prefShowNone
);
950 static int getCmdHint(const char *Cmd
) {
951 CLIParserContext
*ctx
;
952 CLIParserInit(&ctx
, "prefs get hints",
953 "Get preference of showing hint messages in the client",
960 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
962 showHintsState(prefShowNone
);
966 static int getCmdColor(const char *Cmd
) {
967 CLIParserContext
*ctx
;
968 CLIParserInit(&ctx
, "prefs get color",
969 "Get preference of using colors in the client",
976 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
978 showColorState(prefShowNone
);
982 static int getCmdDebug(const char *Cmd
) {
983 CLIParserContext
*ctx
;
984 CLIParserInit(&ctx
, "prefs get clientdebug",
985 "Get preference of using clientside debug level",
986 "prefs get clientdebug"
992 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
994 showClientDebugState(prefShowNone
);
998 static int getCmdPlotSlider(const char *Cmd
) {
999 CLIParserContext
*ctx
;
1000 CLIParserInit(&ctx
, "prefs get plotsliders",
1001 "Get preference of showing the plotslider control in the client",
1002 "prefs get plotsliders"
1004 void *argtable
[] = {
1008 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1010 showPlotSliderState(prefShowNone
);
1014 static int getCmdBarMode(const char *Cmd
) {
1015 CLIParserContext
*ctx
;
1016 CLIParserInit(&ctx
, "prefs get barmode",
1017 "Get preference of HF/LF tune command styled output in the client",
1020 void *argtable
[] = {
1024 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1026 showBarModeState(prefShowNone
);
1030 static int getCmdSavePaths(const char *Cmd
) {
1031 CLIParserContext
*ctx
;
1032 CLIParserInit(&ctx
, "prefs get savepaths",
1033 "Get preference of file paths in the client",
1034 "prefs get savepaths"
1036 void *argtable
[] = {
1040 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1042 showSavePathState(spDefault
, prefShowNone
);
1043 showSavePathState(spDump
, prefShowNone
);
1044 showSavePathState(spTrace
, prefShowNone
);
1048 static command_t CommandTableGet
[] = {
1049 {"barmode", getCmdBarMode
, AlwaysAvailable
, "Get bar mode preference"},
1050 {"clientdebug", getCmdDebug
, AlwaysAvailable
, "Get client debug level preference"},
1051 {"color", getCmdColor
, AlwaysAvailable
, "Get color support preference"},
1052 {"savepaths", getCmdSavePaths
, AlwaysAvailable
, "Get file folder "},
1053 // {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"},
1054 {"emoji", getCmdEmoji
, AlwaysAvailable
, "Get emoji display preference"},
1055 {"hints", getCmdHint
, AlwaysAvailable
, "Get hint display preference"},
1056 {"plotsliders", getCmdPlotSlider
, AlwaysAvailable
, "Get plot slider display preference"},
1057 {NULL
, NULL
, NULL
, NULL
}
1060 static command_t CommandTableSet
[] = {
1061 {"help", setCmdHelp
, AlwaysAvailable
, "This help"},
1062 {"barmode", setCmdBarMode
, AlwaysAvailable
, "Set bar mode"},
1063 {"clientdebug", setCmdDebug
, AlwaysAvailable
, "Set client debug level"},
1064 {"color", setCmdColor
, AlwaysAvailable
, "Set color support"},
1065 {"emoji", setCmdEmoji
, AlwaysAvailable
, "Set emoji display"},
1066 {"hints", setCmdHint
, AlwaysAvailable
, "Set hint display"},
1067 {"savepaths", setCmdSavePaths
, AlwaysAvailable
, "... to be adjusted next ... "},
1068 // {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"},
1069 {"plotsliders", setCmdPlotSliders
, AlwaysAvailable
, "Set plot slider display"},
1070 {NULL
, NULL
, NULL
, NULL
}
1073 static int setCmdHelp(const char *Cmd
) {
1074 (void)Cmd
; // Cmd is not used so far
1075 CmdsHelp(CommandTableSet
);
1079 static int CmdPrefGet(const char *Cmd
) {
1080 clearCommandBuffer();
1081 return CmdsParse(CommandTableGet
, Cmd
);
1084 static int CmdPrefSet(const char *Cmd
) {
1085 clearCommandBuffer();
1086 return CmdsParse(CommandTableSet
, Cmd
);
1089 static int CmdPrefShow(const char *Cmd
) {
1090 CLIParserContext
*ctx
;
1091 CLIParserInit(&ctx
, "prefs show",
1092 "Show all persistent preferences",
1095 void *argtable
[] = {
1099 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1102 if (session
.preferences_loaded
) {
1103 char *fn
= prefGetFilename();
1104 PrintAndLogEx(NORMAL
, "");
1105 PrintAndLogEx(INFO
, "Using "_YELLOW_("%s"), fn
);
1108 PrintAndLogEx(WARNING
, "Preferences file not loaded");
1111 PrintAndLogEx(INFO
, "Current settings");
1112 showEmojiState(prefShowNone
);
1113 showHintsState(prefShowNone
);
1114 showColorState(prefShowNone
);
1116 showOverlayPosState();
1117 showSavePathState(spDefault
, prefShowNone
);
1118 showSavePathState(spDump
, prefShowNone
);
1119 showSavePathState(spTrace
, prefShowNone
);
1120 showClientDebugState(prefShowNone
);
1121 showPlotSliderState(prefShowNone
);
1122 // showDeviceDebugState(prefShowNone);
1124 showBarModeState(prefShowNone
);
1125 PrintAndLogEx(NORMAL
, "");
1129 static int CmdPrefSave (const char *Cmd) {
1134 static command_t CommandTable
[] = {
1135 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
1136 {"get", CmdPrefGet
, AlwaysAvailable
, "{ Get a preference }"},
1137 {"set", CmdPrefSet
, AlwaysAvailable
, "{ Set a preference }"},
1138 {"show", CmdPrefShow
, AlwaysAvailable
, "Show all preferences"},
1139 {NULL
, NULL
, NULL
, NULL
}
1142 static int CmdHelp(const char *Cmd
) {
1143 (void)Cmd
; // Cmd is not used so far
1144 CmdsHelp(CommandTable
);
1148 int CmdPreferences(const char *Cmd
) {
1149 clearCommandBuffer();
1150 return CmdsParse(CommandTable
, Cmd
);