diff --git a/applications/plugins/totp/application.fam b/applications/plugins/totp/application.fam index 5b0266493..fbd21ddf7 100644 --- a/applications/plugins/totp/application.fam +++ b/applications/plugins/totp/application.fam @@ -16,5 +16,22 @@ App( order=20, fap_category="Misc", fap_icon_assets="images", - fap_icon="totp_10px.png" + fap_icon="totp_10px.png", + fap_private_libs=[ + Lib( + name="base32", + ), + Lib( + name="list", + ), + Lib( + name="timezone_utils", + ), + Lib( + name="polyfills", + ), + Lib( + name="roll_value", + ), + ], ) diff --git a/applications/plugins/totp/services/cli/cli.c b/applications/plugins/totp/cli/cli.c similarity index 88% rename from applications/plugins/totp/services/cli/cli.c rename to applications/plugins/totp/cli/cli.c index 2cfae3f15..e61c67206 100644 --- a/applications/plugins/totp/services/cli/cli.c +++ b/applications/plugins/totp/cli/cli.c @@ -9,6 +9,8 @@ #include "commands/timezone/timezone.h" #include "commands/help/help.h" #include "commands/move/move.h" +#include "commands/pin/pin.h" +#include "commands/notification/notification.h" static void totp_cli_print_unknown_command(const FuriString* unknown_command) { TOTP_CLI_PRINTF( @@ -49,6 +51,10 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) { furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE) == 0 || furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE_ALT) == 0) { totp_cli_command_move_handle(plugin_state, args, cli); + } else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_PIN) == 0) { + totp_cli_command_pin_handle(plugin_state, args, cli); + } else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_NOTIFICATION) == 0) { + totp_cli_command_notification_handle(plugin_state, args, cli); } else { totp_cli_print_unknown_command(cmd); } diff --git a/applications/plugins/totp/services/cli/cli.h b/applications/plugins/totp/cli/cli.h similarity index 79% rename from applications/plugins/totp/services/cli/cli.h rename to applications/plugins/totp/cli/cli.h index 5297dd61b..3eb18172c 100644 --- a/applications/plugins/totp/services/cli/cli.h +++ b/applications/plugins/totp/cli/cli.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../types/plugin_state.h" +#include "../types/plugin_state.h" void totp_cli_register_command_handler(PluginState* plugin_state); void totp_cli_unregister_command_handler(); \ No newline at end of file diff --git a/applications/plugins/totp/services/cli/cli_helpers.c b/applications/plugins/totp/cli/cli_helpers.c similarity index 100% rename from applications/plugins/totp/services/cli/cli_helpers.c rename to applications/plugins/totp/cli/cli_helpers.c diff --git a/applications/plugins/totp/services/cli/cli_helpers.h b/applications/plugins/totp/cli/cli_helpers.h similarity index 76% rename from applications/plugins/totp/services/cli/cli_helpers.h rename to applications/plugins/totp/cli/cli_helpers.h index 9b19f926b..075822cd6 100644 --- a/applications/plugins/totp/services/cli/cli_helpers.h +++ b/applications/plugins/totp/cli/cli_helpers.h @@ -1,11 +1,12 @@ #pragma once #include -#include "../../types/plugin_state.h" +#include "../types/plugin_state.h" #define TOTP_CLI_COMMAND_NAME "totp" #define DOCOPT_ARGUMENT(arg) "<" arg ">" +#define DOCOPT_MULTIPLE(arg) arg "..." #define DOCOPT_OPTIONAL(param) "[" param "]" #define DOCOPT_REQUIRED(param) "(" param ")" #define DOCOPT_OPTION(option, value) option " " value @@ -37,4 +38,11 @@ TOTP_CLI_PRINTF( \ "Invalid command arguments. use \"help\" command to get list of available commands") +/** + * @brief Checks whether user is authenticated and entered correct PIN. + * If user is not authenticated it prompts user to enter correct PIN to authenticate. + * @param plugin_state application state + * @param cli reference to the firmware CLI subsystem + * @return \c true if user is already authenticated or successfully authenticated; \c false otherwise + */ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli); diff --git a/applications/plugins/totp/services/cli/commands/add/add.c b/applications/plugins/totp/cli/commands/add/add.c similarity index 92% rename from applications/plugins/totp/services/cli/commands/add/add.c rename to applications/plugins/totp/cli/commands/add/add.c index 4b7aaf327..90cc0f420 100644 --- a/applications/plugins/totp/services/cli/commands/add/add.c +++ b/applications/plugins/totp/cli/commands/add/add.c @@ -1,11 +1,12 @@ #include "add.h" #include #include -#include "../../../list/list.h" -#include "../../../../types/token_info.h" -#include "../../../config/config.h" +#include "../../../lib/list/list.h" +#include "../../../types/token_info.h" +#include "../../../services/config/config.h" +#include "../../../services/convert/convert.h" #include "../../cli_helpers.h" -#include "../../../../scenes/scene_director.h" +#include "../../../ui/scene_director.h" #define TOTP_CLI_COMMAND_ADD_ARG_NAME "name" #define TOTP_CLI_COMMAND_ADD_ARG_ALGO "algo" @@ -14,21 +15,6 @@ #define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d" #define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u" -static bool token_info_set_digits_from_str(TokenInfo* token_info, const FuriString* str) { - switch(furi_string_get_char(str, 0)) { - case '6': - token_info->digits = TOTP_6_DIGITS; - return true; - case '8': - token_info->digits = TOTP_8_DIGITS; - return true; - default: - break; - } - - return false; -} - static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) { if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) { token_info->algo = SHA1; @@ -73,6 +59,7 @@ void totp_cli_command_add_docopt_options() { DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_ALGO)) " Token hashing algorithm.\r\n"); TOTP_CLI_PRINTF( " Could be one of: sha1, sha256, sha512 " DOCOPT_DEFAULT("sha1") "\r\n"); + cli_nl(); TOTP_CLI_PRINTF(" " DOCOPT_OPTION( TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT( @@ -94,7 +81,7 @@ static bool totp_cli_read_secret(Cli* cli, FuriString* out_str, bool mask_user_i while(cli_read(cli, &c, 1) == 1) { if(c == CliSymbolAsciiEsc) { // Some keys generating escape-sequences - // We need to ignore them as we case about alpha-numerics only + // We need to ignore them as we care about alpha-numerics only uint8_t c2; cli_read_timeout(cli, &c2, 1, 0); cli_read_timeout(cli, &c2, 1, 0); @@ -164,7 +151,8 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl TOTP_CLI_PRINTF( "Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n"); - } else if(!token_info_set_digits_from_str(token_info, temp_str)) { + } else if(!token_info_set_digits_from_int( + token_info, CONVERT_CHAR_TO_DIGIT(furi_string_get_char(temp_str, 0)))) { TOTP_CLI_PRINTF( "\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n", diff --git a/applications/plugins/totp/services/cli/commands/add/add.h b/applications/plugins/totp/cli/commands/add/add.h similarity index 90% rename from applications/plugins/totp/services/cli/commands/add/add.h rename to applications/plugins/totp/cli/commands/add/add.h index 7b1138e5b..001dc9e80 100644 --- a/applications/plugins/totp/services/cli/commands/add/add.h +++ b/applications/plugins/totp/cli/commands/add/add.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../../../types/plugin_state.h" +#include "../../../types/plugin_state.h" #define TOTP_CLI_COMMAND_ADD "add" #define TOTP_CLI_COMMAND_ADD_ALT "mk" diff --git a/applications/plugins/totp/services/cli/commands/delete/delete.c b/applications/plugins/totp/cli/commands/delete/delete.c similarity index 96% rename from applications/plugins/totp/services/cli/commands/delete/delete.c rename to applications/plugins/totp/cli/commands/delete/delete.c index bbeb6ec4d..7eddb96bd 100644 --- a/applications/plugins/totp/services/cli/commands/delete/delete.c +++ b/applications/plugins/totp/cli/commands/delete/delete.c @@ -3,10 +3,10 @@ #include #include #include -#include "../../../list/list.h" -#include "../../../config/config.h" +#include "../../../lib/list/list.h" +#include "../../../services/config/config.h" #include "../../cli_helpers.h" -#include "../../../../scenes/scene_director.h" +#include "../../../ui/scene_director.h" #define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "index" #define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f" diff --git a/applications/plugins/totp/services/cli/commands/delete/delete.h b/applications/plugins/totp/cli/commands/delete/delete.h similarity index 90% rename from applications/plugins/totp/services/cli/commands/delete/delete.h rename to applications/plugins/totp/cli/commands/delete/delete.h index 0b60932e3..deb7f74fe 100644 --- a/applications/plugins/totp/services/cli/commands/delete/delete.h +++ b/applications/plugins/totp/cli/commands/delete/delete.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../../../types/plugin_state.h" +#include "../../../types/plugin_state.h" #define TOTP_CLI_COMMAND_DELETE "delete" #define TOTP_CLI_COMMAND_DELETE_ALT "rm" diff --git a/applications/plugins/totp/services/cli/commands/help/help.c b/applications/plugins/totp/cli/commands/help/help.c similarity index 84% rename from applications/plugins/totp/services/cli/commands/help/help.c rename to applications/plugins/totp/cli/commands/help/help.c index 432f0ab71..419964880 100644 --- a/applications/plugins/totp/services/cli/commands/help/help.c +++ b/applications/plugins/totp/cli/commands/help/help.c @@ -5,6 +5,8 @@ #include "../list/list.h" #include "../timezone/timezone.h" #include "../move/move.h" +#include "../pin/pin.h" +#include "../notification/notification.h" void totp_cli_command_help_docopt_commands() { TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT @@ -25,6 +27,8 @@ void totp_cli_command_help_handle() { totp_cli_command_delete_docopt_usage(); totp_cli_command_timezone_docopt_usage(); totp_cli_command_move_docopt_usage(); + totp_cli_command_pin_docopt_usage(); + totp_cli_command_notification_docopt_usage(); cli_nl(); TOTP_CLI_PRINTF("Commands:\r\n"); totp_cli_command_help_docopt_commands(); @@ -33,11 +37,14 @@ void totp_cli_command_help_handle() { totp_cli_command_delete_docopt_commands(); totp_cli_command_timezone_docopt_commands(); totp_cli_command_move_docopt_commands(); + totp_cli_command_pin_docopt_commands(); + totp_cli_command_notification_docopt_commands(); cli_nl(); TOTP_CLI_PRINTF("Arguments:\r\n"); totp_cli_command_add_docopt_arguments(); totp_cli_command_delete_docopt_arguments(); totp_cli_command_timezone_docopt_arguments(); + totp_cli_command_notification_docopt_arguments(); cli_nl(); TOTP_CLI_PRINTF("Options:\r\n"); totp_cli_command_add_docopt_options(); diff --git a/applications/plugins/totp/services/cli/commands/help/help.h b/applications/plugins/totp/cli/commands/help/help.h similarity index 100% rename from applications/plugins/totp/services/cli/commands/help/help.h rename to applications/plugins/totp/cli/commands/help/help.h diff --git a/applications/plugins/totp/services/cli/commands/list/list.c b/applications/plugins/totp/cli/commands/list/list.c similarity index 75% rename from applications/plugins/totp/services/cli/commands/list/list.c rename to applications/plugins/totp/cli/commands/list/list.c index 9f6bf2d0f..739a0de40 100644 --- a/applications/plugins/totp/services/cli/commands/list/list.c +++ b/applications/plugins/totp/cli/commands/list/list.c @@ -1,8 +1,8 @@ #include "list.h" #include -#include "../../../list/list.h" -#include "../../../../types/token_info.h" -#include "../../../config/constants.h" +#include "../../../lib/list/list.h" +#include "../../../types/token_info.h" +#include "../../../services/config/constants.h" #include "../../cli_helpers.h" static char* get_algo_as_cstr(TokenHashAlgo algo) { @@ -20,19 +20,6 @@ static char* get_algo_as_cstr(TokenHashAlgo algo) { return "UNKNOWN"; } -static uint8_t get_digits_as_int(TokenDigitsCount digits) { - switch(digits) { - case TOTP_6_DIGITS: - return 6; - case TOTP_8_DIGITS: - return 8; - default: - break; - } - - return 6; -} - void totp_cli_command_list_docopt_commands() { TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_LIST ", " TOTP_CLI_COMMAND_LIST_ALT " List all available tokens\r\n"); @@ -53,23 +40,19 @@ void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) { return; } - ListNode* node = plugin_state->tokens_list; - TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); TOTP_CLI_PRINTF("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits"); TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); uint16_t index = 1; - while(node != NULL) { + TOTP_LIST_FOREACH(plugin_state->tokens_list, node, { TokenInfo* token_info = (TokenInfo*)node->data; - token_info_get_digits_count(token_info); TOTP_CLI_PRINTF( "| %-3" PRIu16 " | %-27.27s | %-6s | %-6" PRIu8 " |\r\n", index, token_info->name, get_algo_as_cstr(token_info->algo), - get_digits_as_int(token_info->digits)); - node = node->next; + token_info->digits); index++; - } + }); TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); } \ No newline at end of file diff --git a/applications/plugins/totp/services/cli/commands/list/list.h b/applications/plugins/totp/cli/commands/list/list.h similarity index 86% rename from applications/plugins/totp/services/cli/commands/list/list.h rename to applications/plugins/totp/cli/commands/list/list.h index d8c3cb127..7d6de5874 100644 --- a/applications/plugins/totp/services/cli/commands/list/list.h +++ b/applications/plugins/totp/cli/commands/list/list.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../../../types/plugin_state.h" +#include "../../../types/plugin_state.h" #define TOTP_CLI_COMMAND_LIST "list" #define TOTP_CLI_COMMAND_LIST_ALT "ls" diff --git a/applications/plugins/totp/services/cli/commands/move/move.c b/applications/plugins/totp/cli/commands/move/move.c similarity index 97% rename from applications/plugins/totp/services/cli/commands/move/move.c rename to applications/plugins/totp/cli/commands/move/move.c index 9ed0a604a..95cb8dcac 100644 --- a/applications/plugins/totp/services/cli/commands/move/move.c +++ b/applications/plugins/totp/cli/commands/move/move.c @@ -2,11 +2,11 @@ #include #include -#include "../../../list/list.h" -#include "../../../../types/token_info.h" -#include "../../../config/config.h" +#include "../../../lib/list/list.h" +#include "../../../types/token_info.h" +#include "../../../services/config/config.h" #include "../../cli_helpers.h" -#include "../../../../scenes/scene_director.h" +#include "../../../ui/scene_director.h" #define TOTP_CLI_COMMAND_MOVE_ARG_INDEX "index" diff --git a/applications/plugins/totp/services/cli/commands/move/move.h b/applications/plugins/totp/cli/commands/move/move.h similarity index 88% rename from applications/plugins/totp/services/cli/commands/move/move.h rename to applications/plugins/totp/cli/commands/move/move.h index b06a71679..9eaad5319 100644 --- a/applications/plugins/totp/services/cli/commands/move/move.h +++ b/applications/plugins/totp/cli/commands/move/move.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../../../types/plugin_state.h" +#include "../../../types/plugin_state.h" #define TOTP_CLI_COMMAND_MOVE "move" #define TOTP_CLI_COMMAND_MOVE_ALT "mv" diff --git a/applications/plugins/totp/cli/commands/notification/notification.c b/applications/plugins/totp/cli/commands/notification/notification.c new file mode 100644 index 000000000..91dd44d4f --- /dev/null +++ b/applications/plugins/totp/cli/commands/notification/notification.c @@ -0,0 +1,106 @@ +#include "notification.h" +#include +#include "../../../services/config/config.h" +#include "../../../ui/scene_director.h" +#include "../../cli_helpers.h" + +#define TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD "method" +#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE "none" +#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "sound" +#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "vibro" + +void totp_cli_command_notification_docopt_commands() { + TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NOTIFICATION + " Get or set notification method\r\n"); +} + +void totp_cli_command_notification_docopt_usage() { + TOTP_CLI_PRINTF( + " " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_NOTIFICATION " " DOCOPT_OPTIONAL( + DOCOPT_MULTIPLE(DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD))) "\r\n"); +} + +void totp_cli_command_notification_docopt_arguments() { + TOTP_CLI_PRINTF( + " " TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD + " Notification method to be set. Must be one of [" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE + ", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND + ", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "]\r\n"); +} + +static void totp_cli_command_notification_print_method(NotificationMethod method) { + bool has_previous_method = false; + if(method & NotificationMethodSound) { + TOTP_CLI_PRINTF("\"" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "\""); + has_previous_method = true; + } + if(method & NotificationMethodVibro) { + if(has_previous_method) { + TOTP_CLI_PRINTF(" and "); + } + + TOTP_CLI_PRINTF("\"" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "\""); + } + if(method == NotificationMethodNone) { + TOTP_CLI_PRINTF("\"" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE "\""); + } +} + +void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { + if(!totp_cli_ensure_authenticated(plugin_state, cli)) { + return; + } + + FuriString* temp_str = furi_string_alloc(); + bool new_method_provided = false; + NotificationMethod new_method = NotificationMethodNone; + bool args_valid = true; + while(args_read_string_and_trim(args, temp_str)) { + if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE) == 0) { + new_method_provided = true; + new_method = NotificationMethodNone; + } else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND) == 0) { + new_method_provided = true; + new_method |= NotificationMethodSound; + } else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO) == 0) { + new_method_provided = true; + new_method |= NotificationMethodVibro; + } else { + args_valid = false; + break; + } + } + + do { + if(!args_valid) { + TOTP_CLI_PRINT_INVALID_ARGUMENTS(); + break; + } + + if(new_method_provided) { + Scene previous_scene = TotpSceneNone; + if(plugin_state->current_scene == TotpSceneGenerateToken || + plugin_state->current_scene == TotpSceneAppSettings) { + previous_scene = plugin_state->current_scene; + totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL); + } + + plugin_state->notification_method = new_method; + totp_config_file_update_notification_method(new_method); + + if(previous_scene != TotpSceneNone) { + totp_scene_director_activate_scene(plugin_state, previous_scene, NULL); + } + + TOTP_CLI_PRINTF("Notification method is set to "); + totp_cli_command_notification_print_method(new_method); + cli_nl(); + } else { + TOTP_CLI_PRINTF("Current notification method is "); + totp_cli_command_notification_print_method(plugin_state->notification_method); + cli_nl(); + } + } while(false); + + furi_string_free(temp_str); +} \ No newline at end of file diff --git a/applications/plugins/totp/cli/commands/notification/notification.h b/applications/plugins/totp/cli/commands/notification/notification.h new file mode 100644 index 000000000..c349f9620 --- /dev/null +++ b/applications/plugins/totp/cli/commands/notification/notification.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include "../../../types/plugin_state.h" + +#define TOTP_CLI_COMMAND_NOTIFICATION "notify" + +void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString* args, Cli* cli); +void totp_cli_command_notification_docopt_commands(); +void totp_cli_command_notification_docopt_usage(); +void totp_cli_command_notification_docopt_arguments(); \ No newline at end of file diff --git a/applications/plugins/totp/cli/commands/pin/pin.c b/applications/plugins/totp/cli/commands/pin/pin.c new file mode 100644 index 000000000..045976eef --- /dev/null +++ b/applications/plugins/totp/cli/commands/pin/pin.c @@ -0,0 +1,172 @@ +#include "pin.h" + +#include +#include +#include "../../../types/token_info.h" +#include "../../../types/user_pin_codes.h" +#include "../../../services/config/config.h" +#include "../../cli_helpers.h" +#include "../../../lib/polyfills/memset_s.h" +#include "../../../services/crypto/crypto.h" +#include "../../../ui/scene_director.h" + +#define TOTP_CLI_COMMAND_PIN_COMMAND_SET "set" +#define TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE "remove" + +void totp_cli_command_pin_docopt_commands() { + TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_PIN " Set\\change\\remove PIN\r\n"); +} + +void totp_cli_command_pin_docopt_usage() { + TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_PIN " " DOCOPT_REQUIRED( + TOTP_CLI_COMMAND_PIN_COMMAND_SET " | " TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE) "\r\n"); +} + +static inline uint8_t totp_cli_key_to_pin_code(uint8_t key) { + uint8_t code = 0; + switch(key) { + case 0x44: // left + code = PinCodeArrowLeft; + break; + case 0x41: // up + code = PinCodeArrowUp; + break; + case 0x43: // right + code = PinCodeArrowRight; + break; + case 0x42: // down + code = PinCodeArrowDown; + break; + default: + break; + } + + return code; +} + +static bool totp_cli_read_pin(Cli* cli, uint8_t* pin, uint8_t* pin_length) { + TOTP_CLI_PRINTF("Enter new PIN (use arrow keys on your keyboard): "); + fflush(stdout); + uint8_t c; + *pin_length = 0; + while(cli_read(cli, &c, 1) == 1) { + if(c == CliSymbolAsciiEsc) { + uint8_t c2; + uint8_t c3; + if(cli_read_timeout(cli, &c2, 1, 0) == 1 && cli_read_timeout(cli, &c3, 1, 0) == 1 && + c2 == 0x5b) { + uint8_t code = totp_cli_key_to_pin_code(c3); + if(code > 0) { + pin[*pin_length] = code; + *pin_length = *pin_length + 1; + putc('*', stdout); + fflush(stdout); + } + } + } else if(c == CliSymbolAsciiETX) { + TOTP_CLI_DELETE_CURRENT_LINE(); + TOTP_CLI_PRINTF("Cancelled by user\r\n"); + return false; + } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) { + if(*pin_length > 0) { + *pin_length = *pin_length - 1; + pin[*pin_length] = 0; + TOTP_CLI_DELETE_LAST_CHAR(); + } + } else if(c == CliSymbolAsciiCR) { + cli_nl(); + break; + } + } + + TOTP_CLI_DELETE_LAST_LINE(); + return true; +} + +void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { + UNUSED(plugin_state); + FuriString* temp_str = furi_string_alloc(); + + bool do_change = false; + bool do_remove = false; + UNUSED(do_remove); + if(args_read_string_and_trim(args, temp_str)) { + if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_SET) == 0) { + do_change = true; + } else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE) == 0) { + do_remove = true; + } else { + TOTP_CLI_PRINT_INVALID_ARGUMENTS(); + } + } else { + TOTP_CLI_PRINT_INVALID_ARGUMENTS(); + } + + if((do_change || do_remove) && totp_cli_ensure_authenticated(plugin_state, cli)) { + bool load_generate_token_scene = false; + do { + uint8_t old_iv[TOTP_IV_SIZE]; + memcpy(&old_iv[0], &plugin_state->iv[0], TOTP_IV_SIZE); + uint8_t new_pin[TOTP_IV_SIZE]; + uint8_t new_pin_length = 0; + if(do_change) { + if(!totp_cli_read_pin(cli, &new_pin[0], &new_pin_length) || + !totp_cli_ensure_authenticated(plugin_state, cli)) { + memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE); + break; + } + } else if(do_remove) { + new_pin_length = 0; + memset(&new_pin[0], 0, TOTP_IV_SIZE); + } + + if(plugin_state->current_scene == TotpSceneGenerateToken) { + totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL); + load_generate_token_scene = true; + } + + TOTP_CLI_PRINTF("Encrypting, please wait...\r\n"); + + memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); + memset(&plugin_state->base_iv[0], 0, TOTP_IV_SIZE); + if(plugin_state->crypto_verify_data != NULL) { + free(plugin_state->crypto_verify_data); + plugin_state->crypto_verify_data = NULL; + } + + totp_crypto_seed_iv( + plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length); + + TOTP_LIST_FOREACH(plugin_state->tokens_list, node, { + TokenInfo* token_info = node->data; + size_t plain_token_length; + uint8_t* plain_token = totp_crypto_decrypt( + token_info->token, token_info->token_length, &old_iv[0], &plain_token_length); + free(token_info->token); + token_info->token = totp_crypto_encrypt( + plain_token, + plain_token_length, + &plugin_state->iv[0], + &token_info->token_length); + memset_s(plain_token, plain_token_length, 0, plain_token_length); + free(plain_token); + }); + + totp_full_save_config_file(plugin_state); + + TOTP_CLI_DELETE_LAST_LINE(); + + if(do_change) { + TOTP_CLI_PRINTF("PIN has been successfully changed\r\n"); + } else if(do_remove) { + TOTP_CLI_PRINTF("PIN has been successfully removed\r\n"); + } + } while(false); + + if(load_generate_token_scene) { + totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + } + } + + furi_string_free(temp_str); +} \ No newline at end of file diff --git a/applications/plugins/totp/cli/commands/pin/pin.h b/applications/plugins/totp/cli/commands/pin/pin.h new file mode 100644 index 000000000..1308ae736 --- /dev/null +++ b/applications/plugins/totp/cli/commands/pin/pin.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "../../../types/plugin_state.h" + +#define TOTP_CLI_COMMAND_PIN "pin" + +void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli); +void totp_cli_command_pin_docopt_commands(); +void totp_cli_command_pin_docopt_usage(); \ No newline at end of file diff --git a/applications/plugins/totp/services/cli/commands/timezone/timezone.c b/applications/plugins/totp/cli/commands/timezone/timezone.c similarity index 91% rename from applications/plugins/totp/services/cli/commands/timezone/timezone.c rename to applications/plugins/totp/cli/commands/timezone/timezone.c index d997aa116..7a17c1ae2 100644 --- a/applications/plugins/totp/services/cli/commands/timezone/timezone.c +++ b/applications/plugins/totp/cli/commands/timezone/timezone.c @@ -1,7 +1,7 @@ #include "timezone.h" #include -#include "../../../config/config.h" -#include "../../../../scenes/scene_director.h" +#include "../../../services/config/config.h" +#include "../../../ui/scene_director.h" #include "../../cli_helpers.h" #define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "timezone" @@ -21,8 +21,6 @@ void totp_cli_command_timezone_docopt_usage() { void totp_cli_command_timezone_docopt_arguments() { TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE " Timezone offset in hours to be set.\r\n"); - TOTP_CLI_PRINTF( - " If not provided then current timezone offset will be printed\r\n"); } void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { diff --git a/applications/plugins/totp/services/cli/commands/timezone/timezone.h b/applications/plugins/totp/cli/commands/timezone/timezone.h similarity index 89% rename from applications/plugins/totp/services/cli/commands/timezone/timezone.h rename to applications/plugins/totp/cli/commands/timezone/timezone.h index 0c0d82abf..9823cf0ee 100644 --- a/applications/plugins/totp/services/cli/commands/timezone/timezone.h +++ b/applications/plugins/totp/cli/commands/timezone/timezone.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../../../types/plugin_state.h" +#include "../../../types/plugin_state.h" #define TOTP_CLI_COMMAND_TIMEZONE "timezone" #define TOTP_CLI_COMMAND_TIMEZONE_ALT "tz" diff --git a/applications/plugins/totp/images/totp_arrow_bottom_10x5.png b/applications/plugins/totp/images/totp_arrow_bottom_10x5.png new file mode 100644 index 000000000..54e22f5ef Binary files /dev/null and b/applications/plugins/totp/images/totp_arrow_bottom_10x5.png differ diff --git a/applications/plugins/totp/services/base32/base32.c b/applications/plugins/totp/lib/base32/base32.c similarity index 100% rename from applications/plugins/totp/services/base32/base32.c rename to applications/plugins/totp/lib/base32/base32.c diff --git a/applications/plugins/totp/services/base32/base32.h b/applications/plugins/totp/lib/base32/base32.h similarity index 100% rename from applications/plugins/totp/services/base32/base32.h rename to applications/plugins/totp/lib/base32/base32.h diff --git a/applications/plugins/totp/services/list/list.c b/applications/plugins/totp/lib/list/list.c similarity index 100% rename from applications/plugins/totp/services/list/list.c rename to applications/plugins/totp/lib/list/list.c diff --git a/applications/plugins/totp/services/list/list.h b/applications/plugins/totp/lib/list/list.h similarity index 90% rename from applications/plugins/totp/services/list/list.h rename to applications/plugins/totp/lib/list/list.h index 715c74901..c52d4c25a 100644 --- a/applications/plugins/totp/services/list/list.h +++ b/applications/plugins/totp/lib/list/list.h @@ -92,3 +92,11 @@ void list_free(ListNode* head); assert(list_add(head, item) != NULL); \ } \ } while(false) + +#define TOTP_LIST_FOREACH(head, node, action) \ + do { \ + ListNode* node = head; \ + while(node != NULL) { \ + action node = node->next; \ + } \ + } while(false) diff --git a/applications/plugins/totp/services/crypto/memset_s.c b/applications/plugins/totp/lib/polyfills/memset_s.c similarity index 100% rename from applications/plugins/totp/services/crypto/memset_s.c rename to applications/plugins/totp/lib/polyfills/memset_s.c diff --git a/applications/plugins/totp/services/crypto/memset_s.h b/applications/plugins/totp/lib/polyfills/memset_s.h similarity index 100% rename from applications/plugins/totp/services/crypto/memset_s.h rename to applications/plugins/totp/lib/polyfills/memset_s.h diff --git a/applications/plugins/totp/lib/polyfills/strnlen.c b/applications/plugins/totp/lib/polyfills/strnlen.c new file mode 100644 index 000000000..54d183895 --- /dev/null +++ b/applications/plugins/totp/lib/polyfills/strnlen.c @@ -0,0 +1,11 @@ +#include "strnlen.h" + +size_t strnlen(const char* s, size_t maxlen) { + size_t len; + + for(len = 0; len < maxlen; len++, s++) { + if(!*s) break; + } + + return len; +} \ No newline at end of file diff --git a/applications/plugins/totp/lib/polyfills/strnlen.h b/applications/plugins/totp/lib/polyfills/strnlen.h new file mode 100644 index 000000000..7dcef3a18 --- /dev/null +++ b/applications/plugins/totp/lib/polyfills/strnlen.h @@ -0,0 +1,3 @@ +#include + +size_t strnlen(const char* s, size_t maxlen); \ No newline at end of file diff --git a/applications/plugins/totp/services/roll_value/roll_value.c b/applications/plugins/totp/lib/roll_value/roll_value.c similarity index 100% rename from applications/plugins/totp/services/roll_value/roll_value.c rename to applications/plugins/totp/lib/roll_value/roll_value.c diff --git a/applications/plugins/totp/services/roll_value/roll_value.h b/applications/plugins/totp/lib/roll_value/roll_value.h similarity index 95% rename from applications/plugins/totp/services/roll_value/roll_value.h rename to applications/plugins/totp/lib/roll_value/roll_value.h index bb8360c96..3c270be9a 100644 --- a/applications/plugins/totp/services/roll_value/roll_value.h +++ b/applications/plugins/totp/lib/roll_value/roll_value.h @@ -2,7 +2,9 @@ #include -typedef enum { +typedef uint8_t TotpRollValueOverflowBehavior; + +enum TotpRollValueOverflowBehaviors { /** * @brief Do not change value if it reached constraint */ @@ -12,7 +14,7 @@ typedef enum { * @brief Set value to opposite constraint value if it reached constraint */ RollOverflowBehaviorRoll -} TotpRollValueOverflowBehavior; +}; #define TOTP_ROLL_VALUE_FN_HEADER(type, step_type) \ void totp_roll_value_##type( \ diff --git a/applications/plugins/totp/services/timezone_utils/timezone_utils.c b/applications/plugins/totp/lib/timezone_utils/timezone_utils.c similarity index 100% rename from applications/plugins/totp/services/timezone_utils/timezone_utils.c rename to applications/plugins/totp/lib/timezone_utils/timezone_utils.c diff --git a/applications/plugins/totp/services/timezone_utils/timezone_utils.h b/applications/plugins/totp/lib/timezone_utils/timezone_utils.h similarity index 100% rename from applications/plugins/totp/services/timezone_utils/timezone_utils.h rename to applications/plugins/totp/lib/timezone_utils/timezone_utils.h diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c index 765b9c20e..ff7e4eb2d 100644 --- a/applications/plugins/totp/services/config/config.c +++ b/applications/plugins/totp/services/config/config.c @@ -10,32 +10,6 @@ #define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf" #define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup" -static uint8_t token_info_get_digits_as_int(const TokenInfo* token_info) { - switch(token_info->digits) { - case TOTP_6_DIGITS: - return 6; - case TOTP_8_DIGITS: - return 8; - default: - break; - } - - return 6; -} - -static void token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) { - switch(digits) { - case 6: - token_info->digits = TOTP_6_DIGITS; - break; - case 8: - token_info->digits = TOTP_8_DIGITS; - break; - default: - break; - } -} - static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) { switch(token_info->algo) { case SHA1: @@ -106,6 +80,15 @@ FlipperFormat* totp_open_config_file(Storage* storage) { fff_data_file, "Timezone offset in hours. Important note: do not put '+' sign for positive values"); flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &tmp_tz, 1); + + uint32_t tmp_uint32 = NotificationMethodSound | NotificationMethodVibro; + flipper_format_write_comment_cstr(fff_data_file, " "); + flipper_format_write_comment_cstr( + fff_data_file, + "How to notify user when new token is generated or badusb mode is activated (possible values: 0 - do not notify, 1 - sound, 2 - vibro, 3 sound and vibro)"); + flipper_format_write_uint32( + fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1); + FuriString* temp_str = furi_string_alloc(); flipper_format_write_comment_cstr(fff_data_file, " "); @@ -172,8 +155,8 @@ void totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* tok } flipper_format_write_string_cstr( file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info)); - uint32_t digits_count_as_uint32 = token_info_get_digits_as_int(token_info); - flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &digits_count_as_uint32, 1); + uint32_t tmp_uint32 = token_info->digits; + flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1); } void totp_config_file_save_new_token(const TokenInfo* token_info) { @@ -196,6 +179,32 @@ void totp_config_file_update_timezone_offset(float new_timezone_offset) { totp_close_storage(); } +void totp_config_file_update_notification_method(NotificationMethod new_notification_method) { + Storage* cfg_storage = totp_open_storage(); + FlipperFormat* file = totp_open_config_file(cfg_storage); + + uint32_t tmp_uint32 = new_notification_method; + flipper_format_insert_or_update_uint32( + file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1); + + totp_close_config_file(file); + totp_close_storage(); +} + +void totp_config_file_update_user_settings(const PluginState* plugin_state) { + Storage* cfg_storage = totp_open_storage(); + FlipperFormat* file = totp_open_config_file(cfg_storage); + + flipper_format_insert_or_update_float( + file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1); + uint32_t tmp_uint32 = plugin_state->notification_method; + flipper_format_insert_or_update_uint32( + file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1); + + totp_close_config_file(file); + totp_close_storage(); +} + void totp_full_save_config_file(const PluginState* const plugin_state) { Storage* storage = totp_open_storage(); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); @@ -213,12 +222,14 @@ void totp_full_save_config_file(const PluginState* const plugin_state) { flipper_format_write_float( fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1); flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1); - ListNode* node = plugin_state->tokens_list; - while(node != NULL) { + uint32_t tmp_uint32 = plugin_state->notification_method; + flipper_format_write_uint32( + fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1); + + TOTP_LIST_FOREACH(plugin_state->tokens_list, node, { const TokenInfo* token_info = node->data; totp_config_file_save_new_token_i(fff_data_file, token_info); - node = node->next; - } + }); totp_close_config_file(fff_data_file); totp_close_storage(); @@ -321,6 +332,16 @@ void totp_config_file_load_base(PluginState* const plugin_state) { plugin_state->pin_set = true; } + flipper_format_rewind(fff_data_file); + + uint32_t tmp_uint32; + if(!flipper_format_read_uint32( + fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) { + tmp_uint32 = NotificationMethodSound | NotificationMethodVibro; + } + + plugin_state->notification_method = tmp_uint32; + furi_string_free(temp_str); totp_close_config_file(fff_data_file); totp_close_storage(); @@ -409,10 +430,9 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) tokenInfo->algo = SHA1; } - if(flipper_format_read_uint32( - fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1)) { - token_info_set_digits_from_int(tokenInfo, temp_data32); - } else { + if(!flipper_format_read_uint32( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1) || + !token_info_set_digits_from_int(tokenInfo, temp_data32)) { tokenInfo->digits = TOTP_6_DIGITS; } diff --git a/applications/plugins/totp/services/config/config.h b/applications/plugins/totp/services/config/config.h index cf433f9e5..1eabe3365 100644 --- a/applications/plugins/totp/services/config/config.h +++ b/applications/plugins/totp/services/config/config.h @@ -6,10 +6,12 @@ #include "../../types/token_info.h" #include "constants.h" +typedef uint8_t TokenLoadingResult; + /** * @brief Token loading results */ -typedef enum { +enum TokenLoadingResults { /** * @brief All the tokens loaded successfully */ @@ -24,7 +26,7 @@ typedef enum { * @brief Tokens not loaded because of error(s) */ TokenLoadingResultError -} TokenLoadingResult; +}; /** * @brief Opens storage record @@ -80,3 +82,15 @@ void totp_config_file_save_new_token(const TokenInfo* token_info); * @param new_timezone_offset new timezone offset to be set */ void totp_config_file_update_timezone_offset(float new_timezone_offset); + +/** + * @brief Updates notification method in an application config file + * @param new_notification_method new notification method to be set + */ +void totp_config_file_update_notification_method(NotificationMethod new_notification_method); + +/** + * @brief Updates application user settings + * @param plugin_state application state + */ +void totp_config_file_update_user_settings(const PluginState* plugin_state); \ No newline at end of file diff --git a/applications/plugins/totp/services/config/constants.h b/applications/plugins/totp/services/config/constants.h index b094f653f..696ea1593 100644 --- a/applications/plugins/totp/services/config/constants.h +++ b/applications/plugins/totp/services/config/constants.h @@ -11,6 +11,7 @@ #define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto" #define TOTP_CONFIG_KEY_BASE_IV "BaseIV" #define TOTP_CONFIG_KEY_PINSET "PinIsSet" +#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod" #define TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME "sha1" #define TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME "sha256" diff --git a/applications/plugins/totp/services/convert/convert.h b/applications/plugins/totp/services/convert/convert.h new file mode 100644 index 000000000..740d47ace --- /dev/null +++ b/applications/plugins/totp/services/convert/convert.h @@ -0,0 +1,4 @@ +#pragma once + +#define CONVERT_DIGIT_TO_CHAR(digit) ((digit) + '0') +#define CONVERT_CHAR_TO_DIGIT(ch) ((ch) - '0') diff --git a/applications/plugins/totp/services/hid_worker/hid_worker.h b/applications/plugins/totp/services/hid_worker/hid_worker.h deleted file mode 100644 index c14492f47..000000000 --- a/applications/plugins/totp/services/hid_worker/hid_worker.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -typedef struct { - char* string; - uint8_t string_length; - FuriThread* thread; - FuriMutex* string_sync; - FuriHalUsbInterface* usb_mode_prev; -} TotpHidWorkerTypeContext; - -typedef enum { - TotpHidWorkerEvtReserved = (1 << 0), - TotpHidWorkerEvtStop = (1 << 1), - TotpHidWorkerEvtType = (1 << 2) -} TotpHidWorkerEvtFlags; - -TotpHidWorkerTypeContext* totp_hid_worker_start(); -void totp_hid_worker_stop(TotpHidWorkerTypeContext* context); -void totp_hid_worker_notify(TotpHidWorkerTypeContext* context, TotpHidWorkerEvtFlags event); \ No newline at end of file diff --git a/applications/plugins/totp/services/totp/totp.c b/applications/plugins/totp/services/totp/totp.c index 0816d1812..1a20d58c1 100644 --- a/applications/plugins/totp/services/totp/totp.c +++ b/applications/plugins/totp/services/totp/totp.c @@ -9,7 +9,7 @@ #include "../hmac/hmac_sha256.h" #include "../hmac/hmac_sha512.h" #include "../hmac/byteswap.h" -#include "../timezone_utils/timezone_utils.h" +#include "../../lib/timezone_utils/timezone_utils.h" #define HMAC_MAX_SIZE 64 diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c index aece31197..5a551c4f1 100644 --- a/applications/plugins/totp/totp_app.c +++ b/applications/plugins/totp/totp_app.c @@ -7,24 +7,22 @@ #include #include #include -#include "services/base32/base32.h" -#include "services/list/list.h" #include "services/config/config.h" #include "types/plugin_state.h" #include "types/token_info.h" #include "types/plugin_event.h" #include "types/event_type.h" #include "types/common.h" -#include "scenes/scene_director.h" -#include "services/ui/constants.h" +#include "ui/scene_director.h" +#include "ui/constants.h" #include "services/crypto/crypto.h" -#include "services/cli/cli.h" +#include "cli/cli.h" #define IDLE_TIMEOUT 60000 static void render_callback(Canvas* const canvas, void* ctx) { PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); - if(plugin_state != NULL && !plugin_state->changing_scene) { + if(plugin_state != NULL) { totp_scene_director_render(canvas, plugin_state); } @@ -40,8 +38,8 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu static bool totp_plugin_state_init(PluginState* const plugin_state) { plugin_state->gui = furi_record_open(RECORD_GUI); - plugin_state->notification = furi_record_open(RECORD_NOTIFICATION); - plugin_state->dialogs = furi_record_open(RECORD_DIALOGS); + plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION); + plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS); totp_config_file_load_base(plugin_state); @@ -59,7 +57,8 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) { SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter); - DialogMessageButton dialog_result = dialog_message_show(plugin_state->dialogs, message); + DialogMessageButton dialog_result = + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); if(dialog_result == DialogMessageButtonRight) { totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL); @@ -86,7 +85,7 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) { SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter); - dialog_message_show(plugin_state->dialogs, message); + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); return false; } @@ -152,7 +151,6 @@ int32_t totp_app() { bool processing = true; uint32_t last_user_interaction_time = furi_get_tick(); while(processing) { - if(plugin_state->changing_scene) continue; FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); PluginState* plugin_state_m = acquire_mutex_block(&state_mutex); diff --git a/applications/plugins/totp/types/event_type.h b/applications/plugins/totp/types/event_type.h index ed890caf1..4fe916872 100644 --- a/applications/plugins/totp/types/event_type.h +++ b/applications/plugins/totp/types/event_type.h @@ -1,7 +1,9 @@ #pragma once #include -typedef enum { +typedef uint8_t EventType; + +enum EventTypes { EventTypeTick, EventTypeKey, -} EventType; +}; diff --git a/applications/plugins/totp/types/notification_method.h b/applications/plugins/totp/types/notification_method.h new file mode 100644 index 000000000..f86613352 --- /dev/null +++ b/applications/plugins/totp/types/notification_method.h @@ -0,0 +1,9 @@ +#pragma once + +typedef uint8_t NotificationMethod; + +enum NotificationMethods { + NotificationMethodNone = 0b00, + NotificationMethodSound = 0b01, + NotificationMethodVibro = 0b10, +}; diff --git a/applications/plugins/totp/services/nullable/nullable.h b/applications/plugins/totp/types/nullable.h similarity index 100% rename from applications/plugins/totp/services/nullable/nullable.h rename to applications/plugins/totp/types/nullable.h diff --git a/applications/plugins/totp/types/plugin_state.h b/applications/plugins/totp/types/plugin_state.h index 637f9916f..0aad2e125 100644 --- a/applications/plugins/totp/types/plugin_state.h +++ b/applications/plugins/totp/types/plugin_state.h @@ -3,8 +3,9 @@ #include #include #include -#include "../services/list/list.h" -#include "../scenes/totp_scenes_enum.h" +#include "../lib/list/list.h" +#include "../ui/totp_scenes_enum.h" +#include "notification_method.h" #define TOTP_IV_SIZE 16 @@ -22,20 +23,15 @@ typedef struct { */ void* current_scene_state; - /** - * @brief Whether scene is changing now - */ - bool changing_scene; - /** * @brief Reference to the firmware notification subsystem */ - NotificationApp* notification; + NotificationApp* notification_app; /** * @brief Reference to the firmware dialogs subsystem */ - DialogsApp* dialogs; + DialogsApp* dialogs_app; /** * @brief Reference to the firmware GUI subsystem @@ -86,4 +82,9 @@ typedef struct { * @brief Basic randomly-generated initialization vector (IV) */ uint8_t base_iv[TOTP_IV_SIZE]; + + /** + * @brief Notification method + */ + NotificationMethod notification_method; } PluginState; diff --git a/applications/plugins/totp/types/token_info.c b/applications/plugins/totp/types/token_info.c index 66e32f5a4..c032c6d3f 100644 --- a/applications/plugins/totp/types/token_info.c +++ b/applications/plugins/totp/types/token_info.c @@ -3,9 +3,9 @@ #include "token_info.h" #include "stdlib.h" #include "common.h" -#include "../services/base32/base32.h" +#include "../lib/base32/base32.h" #include "../services/crypto/crypto.h" -#include "../services/crypto/memset_s.h" +#include "../lib/polyfills/memset_s.h" TokenInfo* token_info_alloc() { TokenInfo* tokenInfo = malloc(sizeof(TokenInfo)); @@ -45,15 +45,17 @@ bool token_info_set_secret( return result; } -uint8_t token_info_get_digits_count(const TokenInfo* token_info) { - switch(token_info->digits) { - case TOTP_6_DIGITS: - return 6; - case TOTP_8_DIGITS: - return 8; +bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) { + switch(digits) { + case 6: + token_info->digits = TOTP_6_DIGITS; + return true; + case 8: + token_info->digits = TOTP_8_DIGITS; + return true; default: break; } - return 6; + return false; } diff --git a/applications/plugins/totp/types/token_info.h b/applications/plugins/totp/types/token_info.h index cbcf0ddef..04caa68a8 100644 --- a/applications/plugins/totp/types/token_info.h +++ b/applications/plugins/totp/types/token_info.h @@ -2,10 +2,13 @@ #include +typedef uint8_t TokenHashAlgo; +typedef uint8_t TokenDigitsCount; + /** * @brief Hashing algorithm to be used to generate token */ -typedef enum { +enum TokenHashAlgos { /** * @brief SHA1 hashing algorithm */ @@ -20,22 +23,22 @@ typedef enum { * @brief SHA512 hashing algorithm */ SHA512 -} TokenHashAlgo; +}; /** * @brief Token digits count to be generated. */ -typedef enum { +enum TokenDigitsCounts { /** * @brief 6 digits */ - TOTP_6_DIGITS, + TOTP_6_DIGITS = 6, /** * @brief 8 digits */ - TOTP_8_DIGITS -} TokenDigitsCount; + TOTP_8_DIGITS = 8 +}; #define TOTP_TOKEN_DIGITS_MAX_COUNT 8 @@ -96,8 +99,9 @@ bool token_info_set_secret( const uint8_t* iv); /** - * @brief Gets token digits count as \c uint8_t type - * @param token_info instance which's desired digits count should be returned - * @return Token digits length as \c uint8_t type + * @brief Sets token digits count from \c uint8_t value + * @param token_info instance whichs token digits count length should be updated + * @param digits desired token digits count length + * @return \c true if token digits count length has been updated; \c false p */ -uint8_t token_info_get_digits_count(const TokenInfo* token_info); +bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits); diff --git a/applications/plugins/totp/types/user_pin_codes.h b/applications/plugins/totp/types/user_pin_codes.h new file mode 100644 index 000000000..b5d72d398 --- /dev/null +++ b/applications/plugins/totp/types/user_pin_codes.h @@ -0,0 +1,10 @@ +#pragma once + +typedef uint8_t TotpUserPinCode; + +enum TotpUserPinCodes { + PinCodeArrowUp = 2, + PinCodeArrowRight = 8, + PinCodeArrowDown = 11, + PinCodeArrowLeft = 5 +}; \ No newline at end of file diff --git a/applications/plugins/totp/services/ui/constants.h b/applications/plugins/totp/ui/constants.h similarity index 100% rename from applications/plugins/totp/services/ui/constants.h rename to applications/plugins/totp/ui/constants.h diff --git a/applications/plugins/totp/scenes/scene_director.c b/applications/plugins/totp/ui/scene_director.c similarity index 92% rename from applications/plugins/totp/scenes/scene_director.c rename to applications/plugins/totp/ui/scene_director.c index a518dcfc8..fcc9f37d8 100644 --- a/applications/plugins/totp/scenes/scene_director.c +++ b/applications/plugins/totp/ui/scene_director.c @@ -1,16 +1,15 @@ #include "../types/common.h" #include "scene_director.h" -#include "authenticate/totp_scene_authenticate.h" -#include "generate_token/totp_scene_generate_token.h" -#include "add_new_token/totp_scene_add_new_token.h" -#include "token_menu/totp_scene_token_menu.h" -#include "app_settings/totp_app_settings.h" +#include "scenes/authenticate/totp_scene_authenticate.h" +#include "scenes/generate_token/totp_scene_generate_token.h" +#include "scenes/add_new_token/totp_scene_add_new_token.h" +#include "scenes/token_menu/totp_scene_token_menu.h" +#include "scenes/app_settings/totp_app_settings.h" void totp_scene_director_activate_scene( PluginState* const plugin_state, Scene scene, const void* context) { - plugin_state->changing_scene = true; totp_scene_director_deactivate_active_scene(plugin_state); switch(scene) { case TotpSceneGenerateToken: @@ -35,7 +34,6 @@ void totp_scene_director_activate_scene( } plugin_state->current_scene = scene; - plugin_state->changing_scene = false; } void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state) { diff --git a/applications/plugins/totp/scenes/scene_director.h b/applications/plugins/totp/ui/scene_director.h similarity index 100% rename from applications/plugins/totp/scenes/scene_director.h rename to applications/plugins/totp/ui/scene_director.h diff --git a/applications/plugins/totp/scenes/add_new_token/totp_input_text.c b/applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.c similarity index 93% rename from applications/plugins/totp/scenes/add_new_token/totp_input_text.c rename to applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.c index 8ae8d32b0..6956ec1ad 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_input_text.c +++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.c @@ -1,16 +1,6 @@ #include "totp_input_text.h" #include -#include "../../types/common.h" - -size_t strnlen(const char* s, size_t maxlen) { - size_t len; - - for(len = 0; len < maxlen; len++, s++) { - if(!*s) break; - } - - return len; -} +#include "../../../lib/polyfills/strnlen.h" void view_draw(View* view, Canvas* canvas) { furi_assert(view); diff --git a/applications/plugins/totp/scenes/add_new_token/totp_input_text.h b/applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.h similarity index 89% rename from applications/plugins/totp/scenes/add_new_token/totp_input_text.h rename to applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.h index dda0dc301..145e8904d 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_input_text.h +++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_input_text.h @@ -3,10 +3,8 @@ #include #include #include -#include -#include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" typedef struct { char* user_input; diff --git a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c similarity index 90% rename from applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c rename to applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c index 97b642f5c..e6351010e 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c +++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c @@ -1,21 +1,19 @@ #include "totp_scene_add_new_token.h" -#include "../../types/common.h" -#include "../../services/ui/constants.h" -#include "../scene_director.h" +#include "../../../types/common.h" +#include "../../constants.h" +#include "../../scene_director.h" #include "totp_input_text.h" -#include "../../types/token_info.h" -#include "../../services/list/list.h" -#include "../../services/base32/base32.h" -#include "../../services/config/config.h" -#include "../../services/ui/ui_controls.h" -#include "../../services/roll_value/roll_value.h" -#include "../../services/nullable/nullable.h" +#include "../../../types/token_info.h" +#include "../../../lib/list/list.h" +#include "../../../services/config/config.h" +#include "../../ui_controls.h" +#include "../../../lib/roll_value/roll_value.h" +#include "../../../types/nullable.h" #include "../generate_token/totp_scene_generate_token.h" -#define TOKEN_ALGO_LIST_LENGTH 3 char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512"}; -#define TOKEN_DIGITS_LIST_LENGTH 2 -char* TOKEN_DIGITS_LIST[] = {"6 digits", "8 digits"}; +char* TOKEN_DIGITS_TEXT_LIST[] = {"6 digits", "8 digits"}; +TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {TOTP_6_DIGITS, TOTP_8_DIGITS}; typedef enum { TokenNameTextBox, @@ -39,7 +37,7 @@ typedef struct { TotpNullable_uint16_t current_token_index; int16_t screen_y_offset; TokenHashAlgo algo; - TokenDigitsCount digits_count; + uint8_t digits_count_index; } SceneState; void totp_scene_add_new_token_init(const PluginState* plugin_state) { @@ -127,7 +125,7 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s 0, 63 - scene_state->screen_y_offset, SCREEN_WIDTH, - TOKEN_DIGITS_LIST[scene_state->digits_count], + TOKEN_DIGITS_TEXT_LIST[scene_state->digits_count_index], scene_state->selected_control == TokenLengthSelect); ui_control_button_render( canvas, @@ -197,11 +195,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState totp_roll_value_uint8_t(&scene_state->algo, 1, SHA1, SHA512, RollOverflowBehaviorRoll); } else if(scene_state->selected_control == TokenLengthSelect) { totp_roll_value_uint8_t( - &scene_state->digits_count, - 1, - TOTP_6_DIGITS, - TOTP_8_DIGITS, - RollOverflowBehaviorRoll); + &scene_state->digits_count_index, 1, 0, 1, RollOverflowBehaviorRoll); } break; case InputKeyLeft: @@ -210,11 +204,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState &scene_state->algo, -1, SHA1, SHA512, RollOverflowBehaviorRoll); } else if(scene_state->selected_control == TokenLengthSelect) { totp_roll_value_uint8_t( - &scene_state->digits_count, - -1, - TOTP_6_DIGITS, - TOTP_8_DIGITS, - RollOverflowBehaviorRoll); + &scene_state->digits_count_index, -1, 0, 1, RollOverflowBehaviorRoll); } break; case InputKeyOk: @@ -253,7 +243,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState strlcpy( tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1); tokenInfo->algo = scene_state->algo; - tokenInfo->digits = scene_state->digits_count; + tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[scene_state->digits_count_index]; TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check); plugin_state->tokens_count++; @@ -275,7 +265,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter); - dialog_message_show(plugin_state->dialogs, message); + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); scene_state->selected_control = TokenSecretTextBox; update_screen_y_offset(scene_state); diff --git a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h similarity index 89% rename from applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h rename to applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h index 9f53fe799..c412e5f0f 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h +++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h @@ -3,8 +3,8 @@ #include #include #include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" typedef struct { uint16_t current_token_index; diff --git a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c similarity index 57% rename from applications/plugins/totp/scenes/app_settings/totp_app_settings.c rename to applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c index 84f749159..5f68c6772 100644 --- a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c +++ b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c @@ -1,19 +1,25 @@ #include "totp_app_settings.h" -#include "../../services/ui/ui_controls.h" -#include "../scene_director.h" +#include +#include +#include "../../ui_controls.h" +#include "../../scene_director.h" #include "../token_menu/totp_scene_token_menu.h" -#include "../../services/ui/constants.h" -#include "../../services/config/config.h" -#include "../../services/roll_value/roll_value.h" -#include "../../services/nullable/nullable.h" +#include "../../constants.h" +#include "../../../services/config/config.h" +#include "../../../services/convert/convert.h" +#include "../../../lib/roll_value/roll_value.h" +#include "../../../types/nullable.h" -#define DIGIT_TO_CHAR(digit) ((digit) + '0') +char* YES_NO_LIST[] = {"NO", "YES"}; -typedef enum { HoursInput, MinutesInput, ConfirmButton } Control; +typedef enum { HoursInput, MinutesInput, Sound, Vibro, ConfirmButton } Control; typedef struct { int8_t tz_offset_hours; uint8_t tz_offset_minutes; + bool notification_sound; + bool notification_vibro; + uint8_t y_offset; TotpNullable_uint16_t current_token_index; Control selected_control; } SceneState; @@ -38,55 +44,87 @@ void totp_scene_app_settings_activate( float off_dec = modff(plugin_state->timezone_offset, &off_int); scene_state->tz_offset_hours = off_int; scene_state->tz_offset_minutes = 60.0f * off_dec; + scene_state->notification_sound = plugin_state->notification_method & NotificationMethodSound; + scene_state->notification_vibro = plugin_state->notification_method & NotificationMethodVibro; } static void two_digit_to_str(int8_t num, char* str) { uint8_t index = 0; if(num < 0) { - str[0] = '-'; - index++; + str[index++] = '-'; num = -num; } uint8_t d1 = (num / 10) % 10; uint8_t d2 = num % 10; - str[index] = DIGIT_TO_CHAR(d1); - str[index + 1] = DIGIT_TO_CHAR(d2); - str[index + 2] = '\0'; + str[index++] = CONVERT_DIGIT_TO_CHAR(d1); + str[index++] = CONVERT_DIGIT_TO_CHAR(d2); + str[index++] = '\0'; } -void totp_scene_app_settings_render(Canvas* const canvas, PluginState* plugin_state) { - const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; +void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plugin_state) { + const SceneState* scene_state = plugin_state->current_scene_state; canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Timezone offset"); + canvas_draw_str_aligned( + canvas, 0, 0 - scene_state->y_offset, AlignLeft, AlignTop, "Timezone offset"); canvas_set_font(canvas, FontSecondary); char tmp_str[4]; two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]); - canvas_draw_str_aligned(canvas, 0, 16, AlignLeft, AlignTop, "Hours:"); + canvas_draw_str_aligned(canvas, 0, 16 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:"); ui_control_select_render( canvas, 36, - 10, + 10 - scene_state->y_offset, SCREEN_WIDTH - 36, &tmp_str[0], scene_state->selected_control == HoursInput); two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]); - canvas_draw_str_aligned(canvas, 0, 34, AlignLeft, AlignTop, "Minutes:"); + canvas_draw_str_aligned( + canvas, 0, 34 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:"); ui_control_select_render( canvas, 36, - 28, + 28 - scene_state->y_offset, SCREEN_WIDTH - 36, &tmp_str[0], scene_state->selected_control == MinutesInput); + canvas_draw_icon( + canvas, + SCREEN_WIDTH_CENTER - 5, + SCREEN_HEIGHT - 5 - scene_state->y_offset, + &I_totp_arrow_bottom_10x5); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned( + canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications"); + canvas_set_font(canvas, FontSecondary); + + canvas_draw_str_aligned(canvas, 0, 80 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:"); + ui_control_select_render( + canvas, + 36, + 74 - scene_state->y_offset, + SCREEN_WIDTH - 36, + YES_NO_LIST[scene_state->notification_sound], + scene_state->selected_control == Sound); + + canvas_draw_str_aligned(canvas, 0, 98 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:"); + ui_control_select_render( + canvas, + 36, + 92 - scene_state->y_offset, + SCREEN_WIDTH - 36, + YES_NO_LIST[scene_state->notification_vibro], + scene_state->selected_control == Vibro); + ui_control_button_render( canvas, SCREEN_WIDTH_CENTER - 24, - 50, + 115 - scene_state->y_offset, 48, 13, "Confirm", @@ -113,10 +151,20 @@ bool totp_scene_app_settings_handle_event( HoursInput, ConfirmButton, RollOverflowBehaviorStop); + if(scene_state->selected_control > MinutesInput) { + scene_state->y_offset = 64; + } else { + scene_state->y_offset = 0; + } break; case InputKeyDown: totp_roll_value_uint8_t( &scene_state->selected_control, 1, HoursInput, ConfirmButton, RollOverflowBehaviorStop); + if(scene_state->selected_control > MinutesInput) { + scene_state->y_offset = 64; + } else { + scene_state->y_offset = 0; + } break; case InputKeyRight: if(scene_state->selected_control == HoursInput) { @@ -125,6 +173,10 @@ bool totp_scene_app_settings_handle_event( } else if(scene_state->selected_control == MinutesInput) { totp_roll_value_uint8_t( &scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == Sound) { + scene_state->notification_sound = !scene_state->notification_sound; + } else if(scene_state->selected_control == Vibro) { + scene_state->notification_vibro = !scene_state->notification_vibro; } break; case InputKeyLeft: @@ -134,13 +186,23 @@ bool totp_scene_app_settings_handle_event( } else if(scene_state->selected_control == MinutesInput) { totp_roll_value_uint8_t( &scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == Sound) { + scene_state->notification_sound = !scene_state->notification_sound; + } else if(scene_state->selected_control == Vibro) { + scene_state->notification_vibro = !scene_state->notification_vibro; } break; case InputKeyOk: if(scene_state->selected_control == ConfirmButton) { plugin_state->timezone_offset = (float)scene_state->tz_offset_hours + (float)scene_state->tz_offset_minutes / 60.0f; - totp_config_file_update_timezone_offset(plugin_state->timezone_offset); + + plugin_state->notification_method = + (scene_state->notification_sound ? NotificationMethodSound : + NotificationMethodNone) | + (scene_state->notification_vibro ? NotificationMethodVibro : + NotificationMethodNone); + totp_config_file_update_user_settings(plugin_state); if(!scene_state->current_token_index.is_null) { TokenMenuSceneContext generate_scene_context = { diff --git a/applications/plugins/totp/scenes/app_settings/totp_app_settings.h b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.h similarity index 72% rename from applications/plugins/totp/scenes/app_settings/totp_app_settings.h rename to applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.h index bcf930839..1721186ed 100644 --- a/applications/plugins/totp/scenes/app_settings/totp_app_settings.h +++ b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.h @@ -1,10 +1,8 @@ #pragma once #include -#include -#include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" typedef struct { uint16_t current_token_index; @@ -14,7 +12,7 @@ void totp_scene_app_settings_init(const PluginState* plugin_state); void totp_scene_app_settings_activate( PluginState* plugin_state, const AppSettingsSceneContext* context); -void totp_scene_app_settings_render(Canvas* const canvas, PluginState* plugin_state); +void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plugin_state); bool totp_scene_app_settings_handle_event( const PluginEvent* const event, PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c b/applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.c similarity index 91% rename from applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c rename to applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.c index 627f6a10d..c595b5bd0 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.c @@ -1,21 +1,18 @@ #include "totp_scene_authenticate.h" #include #include -#include "../../types/common.h" -#include "../../services/ui/constants.h" -#include "../../services/config/config.h" -#include "../scene_director.h" -#include "../totp_scenes_enum.h" -#include "../../services/crypto/crypto.h" +#include "../../../types/common.h" +#include "../../constants.h" +#include "../../../services/config/config.h" +#include "../../scene_director.h" +#include "../../totp_scenes_enum.h" +#include "../../../services/crypto/crypto.h" +#include "../../../types/user_pin_codes.h" #define MAX_CODE_LENGTH TOTP_IV_SIZE -#define ARROW_UP_CODE 2 -#define ARROW_RIGHT_CODE 8 -#define ARROW_DOWN_CODE 11 -#define ARROW_LEFT_CODE 5 typedef struct { - uint8_t code_input[MAX_CODE_LENGTH]; + TotpUserPinCode code_input[MAX_CODE_LENGTH]; uint8_t code_length; } SceneState; @@ -98,25 +95,25 @@ bool totp_scene_authenticate_handle_event( switch(event->input.key) { case InputKeyUp: if(scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_UP_CODE; + scene_state->code_input[scene_state->code_length] = PinCodeArrowUp; scene_state->code_length++; } break; case InputKeyDown: if(scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_DOWN_CODE; + scene_state->code_input[scene_state->code_length] = PinCodeArrowDown; scene_state->code_length++; } break; case InputKeyRight: if(scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_RIGHT_CODE; + scene_state->code_input[scene_state->code_length] = PinCodeArrowRight; scene_state->code_length++; } break; case InputKeyLeft: if(scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_LEFT_CODE; + scene_state->code_input[scene_state->code_length] = PinCodeArrowLeft; scene_state->code_length++; } break; @@ -142,7 +139,7 @@ bool totp_scene_authenticate_handle_event( AlignCenter, AlignCenter); dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17); - dialog_message_show(plugin_state->dialogs, message); + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); } break; diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h b/applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.h similarity index 81% rename from applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h rename to applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.h index c54152f62..b8fe174ae 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h +++ b/applications/plugins/totp/ui/scenes/authenticate/totp_scene_authenticate.h @@ -1,10 +1,8 @@ #pragma once #include -#include -#include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" void totp_scene_authenticate_init(PluginState* plugin_state); void totp_scene_authenticate_activate(PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c similarity index 60% rename from applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c rename to applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c index 266c04736..c90cc6b23 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c @@ -3,20 +3,20 @@ #include #include #include "totp_scene_generate_token.h" -#include "../../types/token_info.h" -#include "../../types/common.h" -#include "../../services/ui/constants.h" -#include "../../services/totp/totp.h" -#include "../../services/config/config.h" -#include "../../services/crypto/crypto.h" -#include "../../services/crypto/memset_s.h" -#include "../../services/roll_value/roll_value.h" -#include "../scene_director.h" +#include "../../../types/token_info.h" +#include "../../../types/common.h" +#include "../../constants.h" +#include "../../../services/totp/totp.h" +#include "../../../services/config/config.h" +#include "../../../services/crypto/crypto.h" +#include "../../../services/convert/convert.h" +#include "../../../lib/polyfills/memset_s.h" +#include "../../../lib/roll_value/roll_value.h" +#include "../../scene_director.h" #include "../token_menu/totp_scene_token_menu.h" -#include "../../services/hid_worker/hid_worker.h" +#include "../../../workers/type_code/type_code.h" #define TOKEN_LIFETIME 30 -#define DIGIT_TO_CHAR(digit) ((digit) + '0') typedef struct { uint16_t current_token_index; @@ -24,60 +24,108 @@ typedef struct { char* last_code_name; bool need_token_update; uint32_t last_token_gen_time; - TotpHidWorkerTypeContext* hid_worker_context; + TotpTypeCodeWorkerContext* type_code_worker_context; + NotificationMessage const** notification_sequence_new_token; + NotificationMessage const** notification_sequence_badusb; } SceneState; -static const NotificationSequence notification_sequence_new_token = { - &message_display_backlight_on, - &message_green_255, - &message_vibro_on, - &message_note_c5, - &message_delay_50, - &message_vibro_off, - &message_sound_off, - NULL, -}; - -static const NotificationSequence notification_sequence_badusb = { - &message_vibro_on, - &message_note_d5, - &message_delay_50, - &message_note_e4, - &message_delay_50, - &message_note_f3, - &message_delay_50, - &message_vibro_off, - &message_sound_off, - NULL, -}; - -static void i_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount len) { - uint8_t str_token_length = 0; - if(len == TOTP_8_DIGITS) { - str[8] = '\0'; - str_token_length = 8; - } else if(len == TOTP_6_DIGITS) { - str[6] = '\0'; - str_token_length = 6; - } - - if(i_token_code == OTP_ERROR) { - memset(&str[0], '-', str_token_length); - } else { - if(len == TOTP_8_DIGITS) { - str[7] = DIGIT_TO_CHAR(i_token_code % 10); - str[6] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - str[5] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - } else if(len == TOTP_6_DIGITS) { - str[5] = DIGIT_TO_CHAR(i_token_code % 10); +static const NotificationSequence* + get_notification_sequence_new_token(const PluginState* plugin_state, SceneState* scene_state) { + if(scene_state->notification_sequence_new_token == NULL) { + uint8_t i = 0; + uint8_t length = 4; + if(plugin_state->notification_method & NotificationMethodVibro) { + length += 2; } - str[4] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - str[3] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - str[2] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - str[1] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - str[0] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); + if(plugin_state->notification_method & NotificationMethodSound) { + length += 2; + } + + scene_state->notification_sequence_new_token = malloc(sizeof(void*) * length); + furi_check(scene_state->notification_sequence_new_token != NULL); + scene_state->notification_sequence_new_token[i++] = &message_display_backlight_on; + scene_state->notification_sequence_new_token[i++] = &message_green_255; + if(plugin_state->notification_method & NotificationMethodVibro) { + scene_state->notification_sequence_new_token[i++] = &message_vibro_on; + } + + if(plugin_state->notification_method & NotificationMethodSound) { + scene_state->notification_sequence_new_token[i++] = &message_note_c5; + } + + scene_state->notification_sequence_new_token[i++] = &message_delay_50; + + if(plugin_state->notification_method & NotificationMethodVibro) { + scene_state->notification_sequence_new_token[i++] = &message_vibro_off; + } + + if(plugin_state->notification_method & NotificationMethodSound) { + scene_state->notification_sequence_new_token[i++] = &message_sound_off; + } + + scene_state->notification_sequence_new_token[i++] = NULL; } + + return (NotificationSequence*)scene_state->notification_sequence_new_token; +} + +static const NotificationSequence* + get_notification_sequence_badusb(const PluginState* plugin_state, SceneState* scene_state) { + if(scene_state->notification_sequence_badusb == NULL) { + uint8_t i = 0; + uint8_t length = 3; + if(plugin_state->notification_method & NotificationMethodVibro) { + length += 2; + } + + if(plugin_state->notification_method & NotificationMethodSound) { + length += 6; + } + + scene_state->notification_sequence_badusb = malloc(sizeof(void*) * length); + furi_check(scene_state->notification_sequence_badusb != NULL); + + scene_state->notification_sequence_badusb[i++] = &message_blue_255; + if(plugin_state->notification_method & NotificationMethodVibro) { + scene_state->notification_sequence_badusb[i++] = &message_vibro_on; + } + + if(plugin_state->notification_method & NotificationMethodSound) { + scene_state->notification_sequence_badusb[i++] = &message_note_d5; //-V525 + scene_state->notification_sequence_badusb[i++] = &message_delay_50; + scene_state->notification_sequence_badusb[i++] = &message_note_e4; + scene_state->notification_sequence_badusb[i++] = &message_delay_50; + scene_state->notification_sequence_badusb[i++] = &message_note_f3; + } + + scene_state->notification_sequence_badusb[i++] = &message_delay_50; + + if(plugin_state->notification_method & NotificationMethodVibro) { + scene_state->notification_sequence_badusb[i++] = &message_vibro_off; + } + + if(plugin_state->notification_method & NotificationMethodSound) { + scene_state->notification_sequence_badusb[i++] = &message_sound_off; + } + + scene_state->notification_sequence_badusb[i++] = NULL; + } + + return (NotificationSequence*)scene_state->notification_sequence_badusb; +} + +static void int_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount len) { + if(i_token_code == OTP_ERROR) { + memset(&str[0], '-', len); + } else { + for(int i = len - 1; i >= 0; i--) { + str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10); + i_token_code = i_token_code / 10; + } + } + + str[len] = '\0'; } TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) { @@ -137,7 +185,7 @@ void totp_scene_generate_token_activate( AlignCenter); } - dialog_message_show(plugin_state->dialogs, message); + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); } } @@ -152,9 +200,9 @@ void totp_scene_generate_token_activate( plugin_state->current_scene_state = scene_state; FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset); update_totp_params(plugin_state); - scene_state->hid_worker_context = totp_hid_worker_start(); - scene_state->hid_worker_context->string = &scene_state->last_code[0]; - scene_state->hid_worker_context->string_length = TOTP_TOKEN_DIGITS_MAX_COUNT + 1; + scene_state->type_code_worker_context = totp_type_code_worker_start(); + scene_state->type_code_worker_context->string = &scene_state->last_code[0]; + scene_state->type_code_worker_context->string_length = TOTP_TOKEN_DIGITS_MAX_COUNT + 1; } void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) { @@ -196,15 +244,16 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ ->data); if(tokenInfo->token != NULL && tokenInfo->token_length > 0) { - furi_mutex_acquire(scene_state->hid_worker_context->string_sync, FuriWaitForever); + furi_mutex_acquire( + scene_state->type_code_worker_context->string_sync, FuriWaitForever); size_t key_length; uint8_t* key = totp_crypto_decrypt( tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length); - i_token_to_str( + int_token_to_str( totp_at( get_totp_algo_impl(tokenInfo->algo), - token_info_get_digits_count(tokenInfo), + tokenInfo->digits, key, key_length, curr_ts, @@ -215,14 +264,17 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ memset_s(key, key_length, 0, key_length); free(key); } else { - furi_mutex_acquire(scene_state->hid_worker_context->string_sync, FuriWaitForever); - i_token_to_str(0, scene_state->last_code, tokenInfo->digits); + furi_mutex_acquire( + scene_state->type_code_worker_context->string_sync, FuriWaitForever); + int_token_to_str(0, scene_state->last_code, tokenInfo->digits); } - furi_mutex_release(scene_state->hid_worker_context->string_sync); + furi_mutex_release(scene_state->type_code_worker_context->string_sync); if(is_new_token_time) { - notification_message(plugin_state->notification, ¬ification_sequence_new_token); + notification_message( + plugin_state->notification_app, + get_notification_sequence_new_token(plugin_state, scene_state)); } } @@ -288,8 +340,11 @@ bool totp_scene_generate_token_handle_event( SceneState* scene_state; if(event->input.type == InputTypeLong && event->input.key == InputKeyDown) { scene_state = (SceneState*)plugin_state->current_scene_state; - totp_hid_worker_notify(scene_state->hid_worker_context, TotpHidWorkerEvtType); - notification_message(plugin_state->notification, ¬ification_sequence_badusb); + totp_type_code_worker_notify( + scene_state->type_code_worker_context, TotpTypeCodeWorkerEventType); + notification_message( + plugin_state->notification_app, + get_notification_sequence_badusb(plugin_state, scene_state)); return true; } @@ -342,7 +397,15 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) { if(plugin_state->current_scene_state == NULL) return; SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; - totp_hid_worker_stop(scene_state->hid_worker_context); + totp_type_code_worker_stop(scene_state->type_code_worker_context); + + if(scene_state->notification_sequence_new_token != NULL) { + free(scene_state->notification_sequence_new_token); + } + + if(scene_state->notification_sequence_badusb != NULL) { + free(scene_state->notification_sequence_badusb); + } free(scene_state); plugin_state->current_scene_state = NULL; diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.h similarity index 84% rename from applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h rename to applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.h index 65f9b84e0..44a3b1c0f 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h +++ b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.h @@ -1,10 +1,8 @@ #pragma once #include -#include -#include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" typedef struct { uint16_t current_token_index; diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c similarity index 94% rename from applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c rename to applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c index d4a837a69..dc713f0a8 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c +++ b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c @@ -1,17 +1,17 @@ #include "totp_scene_token_menu.h" #include #include -#include "../../services/ui/ui_controls.h" -#include "../../services/ui/constants.h" -#include "../scene_director.h" -#include "../../services/config/config.h" -#include "../../services/list/list.h" -#include "../../types/token_info.h" +#include "../../ui_controls.h" +#include "../../constants.h" +#include "../../scene_director.h" +#include "../../../services/config/config.h" +#include "../../../lib/list/list.h" +#include "../../../types/token_info.h" #include "../generate_token/totp_scene_generate_token.h" #include "../add_new_token/totp_scene_add_new_token.h" #include "../app_settings/totp_app_settings.h" -#include "../../services/nullable/nullable.h" -#include "../../services/roll_value/roll_value.h" +#include "../../../types/nullable.h" +#include "../../../lib/roll_value/roll_value.h" #define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3) #define SCREEN_HEIGHT_THIRD_CENTER (SCREEN_HEIGHT_THIRD >> 1) @@ -143,7 +143,7 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt AlignCenter, AlignCenter); DialogMessageButton dialog_result = - dialog_message_show(plugin_state->dialogs, message); + dialog_message_show(plugin_state->dialogs_app, message); dialog_message_free(message); if(dialog_result == DialogMessageButtonRight && !scene_state->current_token_index.is_null) { diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.h similarity index 83% rename from applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h rename to applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.h index acb499be8..059b8e571 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h +++ b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.h @@ -1,10 +1,8 @@ #pragma once #include -#include -#include -#include "../../types/plugin_state.h" -#include "../../types/plugin_event.h" +#include "../../../types/plugin_state.h" +#include "../../../types/plugin_event.h" typedef struct { uint16_t current_token_index; diff --git a/applications/plugins/totp/scenes/totp_scenes_enum.h b/applications/plugins/totp/ui/totp_scenes_enum.h similarity index 94% rename from applications/plugins/totp/scenes/totp_scenes_enum.h rename to applications/plugins/totp/ui/totp_scenes_enum.h index c90f76bab..0c73af772 100644 --- a/applications/plugins/totp/scenes/totp_scenes_enum.h +++ b/applications/plugins/totp/ui/totp_scenes_enum.h @@ -1,9 +1,11 @@ #pragma once +typedef uint8_t Scene; + /** * @brief TOTP application scenes */ -typedef enum { +enum Scenes { /** * @brief Empty scene which does nothing */ @@ -33,4 +35,4 @@ typedef enum { * @brief Scene where user can change application settings */ TotpSceneAppSettings -} Scene; +}; diff --git a/applications/plugins/totp/services/ui/ui_controls.c b/applications/plugins/totp/ui/ui_controls.c similarity index 100% rename from applications/plugins/totp/services/ui/ui_controls.c rename to applications/plugins/totp/ui/ui_controls.c diff --git a/applications/plugins/totp/services/ui/ui_controls.h b/applications/plugins/totp/ui/ui_controls.h similarity index 100% rename from applications/plugins/totp/services/ui/ui_controls.h rename to applications/plugins/totp/ui/ui_controls.h diff --git a/applications/plugins/totp/services/hid_worker/hid_worker.c b/applications/plugins/totp/workers/type_code/type_code.c similarity index 58% rename from applications/plugins/totp/services/hid_worker/hid_worker.c rename to applications/plugins/totp/workers/type_code/type_code.c index 538fdbe97..3eb59047a 100644 --- a/applications/plugins/totp/services/hid_worker/hid_worker.c +++ b/applications/plugins/totp/workers/type_code/type_code.c @@ -1,4 +1,5 @@ -#include "hid_worker.h" +#include "type_code.h" +#include "../../services/convert/convert.h" static const uint8_t hid_number_keys[10] = { HID_KEYBOARD_0, @@ -12,18 +13,18 @@ static const uint8_t hid_number_keys[10] = { HID_KEYBOARD_8, HID_KEYBOARD_9}; -static void totp_hid_worker_restore_usb_mode(TotpHidWorkerTypeContext* context) { +static void totp_type_code_worker_restore_usb_mode(TotpTypeCodeWorkerContext* context) { if(context->usb_mode_prev != NULL) { furi_hal_usb_set_config(context->usb_mode_prev, NULL); context->usb_mode_prev = NULL; } } -static inline bool totp_hid_worker_stop_requested() { - return furi_thread_flags_get() & TotpHidWorkerEvtStop; +static inline bool totp_type_code_worker_stop_requested() { + return furi_thread_flags_get() & TotpTypeCodeWorkerEventStop; } -static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) { +static void totp_type_code_worker_type_code(TotpTypeCodeWorkerContext* context) { context->usb_mode_prev = furi_hal_usb_get_config(); furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true); @@ -31,14 +32,14 @@ static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) { do { furi_delay_ms(500); i++; - } while(!furi_hal_hid_is_connected() && i < 100 && !totp_hid_worker_stop_requested()); + } while(!furi_hal_hid_is_connected() && i < 100 && !totp_type_code_worker_stop_requested()); if(furi_hal_hid_is_connected() && furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) { furi_delay_ms(500); i = 0; while(i < context->string_length && context->string[i] != 0) { - uint8_t digit = context->string[i] - '0'; + uint8_t digit = CONVERT_CHAR_TO_DIGIT(context->string[i]); if(digit > 9) break; uint8_t hid_kb_key = hid_number_keys[digit]; furi_hal_hid_kb_press(hid_kb_key); @@ -52,24 +53,26 @@ static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) { furi_delay_ms(100); } - totp_hid_worker_restore_usb_mode(context); + totp_type_code_worker_restore_usb_mode(context); } -static int32_t totp_hid_worker_callback(void* context) { +static int32_t totp_type_code_worker_callback(void* context) { ValueMutex context_mutex; - if(!init_mutex(&context_mutex, context, sizeof(TotpHidWorkerTypeContext))) { + if(!init_mutex(&context_mutex, context, sizeof(TotpTypeCodeWorkerContext))) { return 251; } while(true) { uint32_t flags = furi_thread_flags_wait( - TotpHidWorkerEvtStop | TotpHidWorkerEvtType, FuriFlagWaitAny, FuriWaitForever); + TotpTypeCodeWorkerEventStop | TotpTypeCodeWorkerEventType, + FuriFlagWaitAny, + FuriWaitForever); furi_check((flags & FuriFlagError) == 0); //-V562 - if(flags & TotpHidWorkerEvtStop) break; + if(flags & TotpTypeCodeWorkerEventStop) break; - TotpHidWorkerTypeContext* h_context = acquire_mutex_block(&context_mutex); - if(flags & TotpHidWorkerEvtType) { - totp_hid_worker_type_code(h_context); + TotpTypeCodeWorkerContext* h_context = acquire_mutex_block(&context_mutex); + if(flags & TotpTypeCodeWorkerEventType) { + totp_type_code_worker_type_code(h_context); } release_mutex(&context_mutex, h_context); @@ -80,8 +83,8 @@ static int32_t totp_hid_worker_callback(void* context) { return 0; } -TotpHidWorkerTypeContext* totp_hid_worker_start() { - TotpHidWorkerTypeContext* context = malloc(sizeof(TotpHidWorkerTypeContext)); +TotpTypeCodeWorkerContext* totp_type_code_worker_start() { + TotpTypeCodeWorkerContext* context = malloc(sizeof(TotpTypeCodeWorkerContext)); furi_check(context != NULL); context->string_sync = furi_mutex_alloc(FuriMutexTypeNormal); context->thread = furi_thread_alloc(); @@ -89,22 +92,24 @@ TotpHidWorkerTypeContext* totp_hid_worker_start() { furi_thread_set_name(context->thread, "TOTPHidWorker"); furi_thread_set_stack_size(context->thread, 1024); furi_thread_set_context(context->thread, context); - furi_thread_set_callback(context->thread, totp_hid_worker_callback); + furi_thread_set_callback(context->thread, totp_type_code_worker_callback); furi_thread_start(context->thread); return context; } -void totp_hid_worker_stop(TotpHidWorkerTypeContext* context) { +void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context) { furi_assert(context != NULL); - furi_thread_flags_set(furi_thread_get_id(context->thread), TotpHidWorkerEvtStop); + furi_thread_flags_set(furi_thread_get_id(context->thread), TotpTypeCodeWorkerEventStop); furi_thread_join(context->thread); furi_thread_free(context->thread); furi_mutex_free(context->string_sync); - totp_hid_worker_restore_usb_mode(context); + totp_type_code_worker_restore_usb_mode(context); free(context); } -void totp_hid_worker_notify(TotpHidWorkerTypeContext* context, TotpHidWorkerEvtFlags event) { +void totp_type_code_worker_notify( + TotpTypeCodeWorkerContext* context, + TotpTypeCodeWorkerEvent event) { furi_assert(context != NULL); furi_thread_flags_set(furi_thread_get_id(context->thread), event); } \ No newline at end of file diff --git a/applications/plugins/totp/workers/type_code/type_code.h b/applications/plugins/totp/workers/type_code/type_code.h new file mode 100644 index 000000000..27f2e02d4 --- /dev/null +++ b/applications/plugins/totp/workers/type_code/type_code.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +typedef uint8_t TotpTypeCodeWorkerEvent; + +typedef struct { + char* string; + uint8_t string_length; + FuriThread* thread; + FuriMutex* string_sync; + FuriHalUsbInterface* usb_mode_prev; +} TotpTypeCodeWorkerContext; + +enum TotpTypeCodeWorkerEvents { + TotpTypeCodeWorkerEventReserved = (1 << 0), + TotpTypeCodeWorkerEventStop = (1 << 1), + TotpTypeCodeWorkerEventType = (1 << 2) +}; + +TotpTypeCodeWorkerContext* totp_type_code_worker_start(); +void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context); +void totp_type_code_worker_notify( + TotpTypeCodeWorkerContext* context, + TotpTypeCodeWorkerEvent event); \ No newline at end of file