diff --git a/application.fam b/application.fam index 5b026649331..fbd21ddf745 100644 --- a/application.fam +++ b/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/services/cli/cli.c b/cli/cli.c similarity index 94% rename from services/cli/cli.c rename to cli/cli.c index 2cfae3f1520..cd5cf729abb 100644 --- a/services/cli/cli.c +++ b/cli/cli.c @@ -9,6 +9,7 @@ #include "commands/timezone/timezone.h" #include "commands/help/help.h" #include "commands/move/move.h" +#include "commands/pin/pin.h" static void totp_cli_print_unknown_command(const FuriString* unknown_command) { TOTP_CLI_PRINTF( @@ -49,6 +50,9 @@ 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 { totp_cli_print_unknown_command(cmd); } diff --git a/services/cli/cli.h b/cli/cli.h similarity index 79% rename from services/cli/cli.h rename to cli/cli.h index 5297dd61bea..3eb18172cf7 100644 --- a/services/cli/cli.h +++ b/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/services/cli/cli_helpers.c b/cli/cli_helpers.c similarity index 100% rename from services/cli/cli_helpers.c rename to cli/cli_helpers.c diff --git a/services/cli/cli_helpers.h b/cli/cli_helpers.h similarity index 97% rename from services/cli/cli_helpers.h rename to cli/cli_helpers.h index 144e19ed9a1..0b375ec084d 100644 --- a/services/cli/cli_helpers.h +++ b/cli/cli_helpers.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../../types/plugin_state.h" +#include "../types/plugin_state.h" #define TOTP_CLI_COMMAND_NAME "totp" diff --git a/services/cli/commands/add/add.c b/cli/commands/add/add.c similarity index 97% rename from services/cli/commands/add/add.c rename to cli/commands/add/add.c index 4b7aaf32716..26131d894b1 100644 --- a/services/cli/commands/add/add.c +++ b/cli/commands/add/add.c @@ -1,11 +1,11 @@ #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 "../../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" @@ -94,7 +94,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); diff --git a/services/cli/commands/add/add.h b/cli/commands/add/add.h similarity index 90% rename from services/cli/commands/add/add.h rename to cli/commands/add/add.h index 7b1138e5bf0..001dc9e804e 100644 --- a/services/cli/commands/add/add.h +++ b/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/services/cli/commands/delete/delete.c b/cli/commands/delete/delete.c similarity index 96% rename from services/cli/commands/delete/delete.c rename to cli/commands/delete/delete.c index bbeb6ec4d05..7eddb96bd72 100644 --- a/services/cli/commands/delete/delete.c +++ b/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/services/cli/commands/delete/delete.h b/cli/commands/delete/delete.h similarity index 90% rename from services/cli/commands/delete/delete.h rename to cli/commands/delete/delete.h index 0b60932e3b6..deb7f74fe2a 100644 --- a/services/cli/commands/delete/delete.h +++ b/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/services/cli/commands/help/help.c b/cli/commands/help/help.c similarity index 93% rename from services/cli/commands/help/help.c rename to cli/commands/help/help.c index 432f0ab71f8..7da5a230839 100644 --- a/services/cli/commands/help/help.c +++ b/cli/commands/help/help.c @@ -5,6 +5,7 @@ #include "../list/list.h" #include "../timezone/timezone.h" #include "../move/move.h" +#include "../pin/pin.h" void totp_cli_command_help_docopt_commands() { TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT @@ -25,6 +26,7 @@ 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(); cli_nl(); TOTP_CLI_PRINTF("Commands:\r\n"); totp_cli_command_help_docopt_commands(); @@ -33,6 +35,7 @@ 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(); cli_nl(); TOTP_CLI_PRINTF("Arguments:\r\n"); totp_cli_command_add_docopt_arguments(); diff --git a/services/cli/commands/help/help.h b/cli/commands/help/help.h similarity index 100% rename from services/cli/commands/help/help.h rename to cli/commands/help/help.h diff --git a/services/cli/commands/list/list.c b/cli/commands/list/list.c similarity index 94% rename from services/cli/commands/list/list.c rename to cli/commands/list/list.c index 9f6bf2d0f3e..ef7142163ce 100644 --- a/services/cli/commands/list/list.c +++ b/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) { diff --git a/services/cli/commands/list/list.h b/cli/commands/list/list.h similarity index 86% rename from services/cli/commands/list/list.h rename to cli/commands/list/list.h index d8c3cb12749..7d6de5874b5 100644 --- a/services/cli/commands/list/list.h +++ b/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/services/cli/commands/move/move.c b/cli/commands/move/move.c similarity index 97% rename from services/cli/commands/move/move.c rename to cli/commands/move/move.c index 9ed0a604ad1..95cb8dcac27 100644 --- a/services/cli/commands/move/move.c +++ b/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/services/cli/commands/move/move.h b/cli/commands/move/move.h similarity index 88% rename from services/cli/commands/move/move.h rename to cli/commands/move/move.h index b06a716794b..9eaad5319b8 100644 --- a/services/cli/commands/move/move.h +++ b/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/cli/commands/pin/pin.c b/cli/commands/pin/pin.c new file mode 100644 index 00000000000..ff361fa8099 --- /dev/null +++ b/cli/commands/pin/pin.c @@ -0,0 +1,166 @@ +#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 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 = 0; + switch (c3) { + 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; + } + + 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); + do { + if (!args_read_string_and_trim(args, temp_str)) { + TOTP_CLI_PRINT_INVALID_ARGUMENTS(); + break; + } + + 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(); + break; + } + } while (false); + + 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); + ListNode* node = plugin_state->tokens_list; + while (node != NULL) { + 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); + node = node->next; + } + + 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/cli/commands/pin/pin.h b/cli/commands/pin/pin.h new file mode 100644 index 00000000000..1308ae7367b --- /dev/null +++ b/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/services/cli/commands/timezone/timezone.c b/cli/commands/timezone/timezone.c similarity index 96% rename from services/cli/commands/timezone/timezone.c rename to cli/commands/timezone/timezone.c index d997aa116f8..8aed95722aa 100644 --- a/services/cli/commands/timezone/timezone.c +++ b/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" diff --git a/services/cli/commands/timezone/timezone.h b/cli/commands/timezone/timezone.h similarity index 89% rename from services/cli/commands/timezone/timezone.h rename to cli/commands/timezone/timezone.h index 0c0d82abf8d..9823cf0eee1 100644 --- a/services/cli/commands/timezone/timezone.h +++ b/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/services/base32/base32.c b/lib/base32/base32.c similarity index 100% rename from services/base32/base32.c rename to lib/base32/base32.c diff --git a/services/base32/base32.h b/lib/base32/base32.h similarity index 100% rename from services/base32/base32.h rename to lib/base32/base32.h diff --git a/services/list/list.c b/lib/list/list.c similarity index 100% rename from services/list/list.c rename to lib/list/list.c diff --git a/services/list/list.h b/lib/list/list.h similarity index 100% rename from services/list/list.h rename to lib/list/list.h diff --git a/services/crypto/memset_s.c b/lib/polyfills/memset_s.c similarity index 100% rename from services/crypto/memset_s.c rename to lib/polyfills/memset_s.c diff --git a/services/crypto/memset_s.h b/lib/polyfills/memset_s.h similarity index 100% rename from services/crypto/memset_s.h rename to lib/polyfills/memset_s.h diff --git a/lib/polyfills/strnlen.c b/lib/polyfills/strnlen.c new file mode 100644 index 00000000000..54d1838958a --- /dev/null +++ b/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/lib/polyfills/strnlen.h b/lib/polyfills/strnlen.h new file mode 100644 index 00000000000..7dcef3a1874 --- /dev/null +++ b/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/services/roll_value/roll_value.c b/lib/roll_value/roll_value.c similarity index 100% rename from services/roll_value/roll_value.c rename to lib/roll_value/roll_value.c diff --git a/services/roll_value/roll_value.h b/lib/roll_value/roll_value.h similarity index 100% rename from services/roll_value/roll_value.h rename to lib/roll_value/roll_value.h diff --git a/services/timezone_utils/timezone_utils.c b/lib/timezone_utils/timezone_utils.c similarity index 100% rename from services/timezone_utils/timezone_utils.c rename to lib/timezone_utils/timezone_utils.c diff --git a/services/timezone_utils/timezone_utils.h b/lib/timezone_utils/timezone_utils.h similarity index 100% rename from services/timezone_utils/timezone_utils.h rename to lib/timezone_utils/timezone_utils.h diff --git a/services/hid_worker/hid_worker.h b/services/hid_worker/hid_worker.h deleted file mode 100644 index c14492f47c0..00000000000 --- a/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/services/totp/totp.c b/services/totp/totp.c index 0816d1812c0..1a20d58c139 100644 --- a/services/totp/totp.c +++ b/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/totp_app.c b/totp_app.c index aece31197f6..b3b1af504b3 100644 --- a/totp_app.c +++ b/totp_app.c @@ -7,18 +7,16 @@ #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 diff --git a/services/nullable/nullable.h b/types/nullable.h similarity index 100% rename from services/nullable/nullable.h rename to types/nullable.h diff --git a/types/plugin_state.h b/types/plugin_state.h index 637f9916f77..3d554adc61d 100644 --- a/types/plugin_state.h +++ b/types/plugin_state.h @@ -3,8 +3,8 @@ #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" #define TOTP_IV_SIZE 16 diff --git a/types/token_info.c b/types/token_info.c index 66e32f5a41c..26329c77674 100644 --- a/types/token_info.c +++ b/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)); diff --git a/types/user_pin_codes.h b/types/user_pin_codes.h new file mode 100644 index 00000000000..7cf5756caa7 --- /dev/null +++ b/types/user_pin_codes.h @@ -0,0 +1,8 @@ +#pragma once + +typedef enum uint8_t { + PinCodeArrowUp = 2, + PinCodeArrowRight = 8, + PinCodeArrowDown = 11, + PinCodeArrowLeft = 5 +} TotpUserPinCode; \ No newline at end of file diff --git a/services/ui/constants.h b/ui/constants.h similarity index 100% rename from services/ui/constants.h rename to ui/constants.h diff --git a/scenes/scene_director.c b/ui/scene_director.c similarity index 93% rename from scenes/scene_director.c rename to ui/scene_director.c index a518dcfc893..e02e7790c5c 100644 --- a/scenes/scene_director.c +++ b/ui/scene_director.c @@ -1,10 +1,10 @@ #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, diff --git a/scenes/scene_director.h b/ui/scene_director.h similarity index 100% rename from scenes/scene_director.h rename to ui/scene_director.h diff --git a/scenes/add_new_token/totp_input_text.c b/ui/scenes/add_new_token/totp_input_text.c similarity index 93% rename from scenes/add_new_token/totp_input_text.c rename to ui/scenes/add_new_token/totp_input_text.c index 8ae8d32b019..6956ec1adb1 100644 --- a/scenes/add_new_token/totp_input_text.c +++ b/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/scenes/add_new_token/totp_input_text.h b/ui/scenes/add_new_token/totp_input_text.h similarity index 89% rename from scenes/add_new_token/totp_input_text.h rename to ui/scenes/add_new_token/totp_input_text.h index dda0dc30167..145e8904d8b 100644 --- a/scenes/add_new_token/totp_input_text.h +++ b/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/scenes/add_new_token/totp_scene_add_new_token.c b/ui/scenes/add_new_token/totp_scene_add_new_token.c similarity index 96% rename from scenes/add_new_token/totp_scene_add_new_token.c rename to ui/scenes/add_new_token/totp_scene_add_new_token.c index 97b642f5c27..e6693b8b8bc 100644 --- a/scenes/add_new_token/totp_scene_add_new_token.c +++ b/ui/scenes/add_new_token/totp_scene_add_new_token.c @@ -1,15 +1,14 @@ #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 diff --git a/scenes/add_new_token/totp_scene_add_new_token.h b/ui/scenes/add_new_token/totp_scene_add_new_token.h similarity index 89% rename from scenes/add_new_token/totp_scene_add_new_token.h rename to ui/scenes/add_new_token/totp_scene_add_new_token.h index 9f53fe7997c..c412e5f0f6d 100644 --- a/scenes/add_new_token/totp_scene_add_new_token.h +++ b/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/scenes/app_settings/totp_app_settings.c b/ui/scenes/app_settings/totp_app_settings.c similarity index 95% rename from scenes/app_settings/totp_app_settings.c rename to ui/scenes/app_settings/totp_app_settings.c index 84f74915944..f87ada3ddf8 100644 --- a/scenes/app_settings/totp_app_settings.c +++ b/ui/scenes/app_settings/totp_app_settings.c @@ -1,11 +1,12 @@ #include "totp_app_settings.h" -#include "../../services/ui/ui_controls.h" -#include "../scene_director.h" +#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 "../../../lib/roll_value/roll_value.h" +#include "../../../types/nullable.h" #define DIGIT_TO_CHAR(digit) ((digit) + '0') diff --git a/scenes/app_settings/totp_app_settings.h b/ui/scenes/app_settings/totp_app_settings.h similarity index 84% rename from scenes/app_settings/totp_app_settings.h rename to ui/scenes/app_settings/totp_app_settings.h index bcf930839a9..4f24861d5a4 100644 --- a/scenes/app_settings/totp_app_settings.h +++ b/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; diff --git a/scenes/authenticate/totp_scene_authenticate.c b/ui/scenes/authenticate/totp_scene_authenticate.c similarity index 92% rename from scenes/authenticate/totp_scene_authenticate.c rename to ui/scenes/authenticate/totp_scene_authenticate.c index 627f6a10d12..e642f291201 100644 --- a/scenes/authenticate/totp_scene_authenticate.c +++ b/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; diff --git a/scenes/authenticate/totp_scene_authenticate.h b/ui/scenes/authenticate/totp_scene_authenticate.h similarity index 81% rename from scenes/authenticate/totp_scene_authenticate.h rename to ui/scenes/authenticate/totp_scene_authenticate.h index c54152f6260..b8fe174ae19 100644 --- a/scenes/authenticate/totp_scene_authenticate.h +++ b/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/scenes/generate_token/totp_scene_generate_token.c b/ui/scenes/generate_token/totp_scene_generate_token.c similarity index 90% rename from scenes/generate_token/totp_scene_generate_token.c rename to ui/scenes/generate_token/totp_scene_generate_token.c index 266c04736ed..33a1c2f97b7 100644 --- a/scenes/generate_token/totp_scene_generate_token.c +++ b/ui/scenes/generate_token/totp_scene_generate_token.c @@ -3,17 +3,17 @@ #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 "../../../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') @@ -24,7 +24,7 @@ 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; } SceneState; static const NotificationSequence notification_sequence_new_token = { @@ -152,9 +152,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,7 +196,7 @@ 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); @@ -215,11 +215,11 @@ 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); + furi_mutex_acquire(scene_state->type_code_worker_context->string_sync, FuriWaitForever); i_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); @@ -288,7 +288,7 @@ 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); + totp_type_code_worker_notify(scene_state->type_code_worker_context, TotpTypeCodeWorkerEvtType); notification_message(plugin_state->notification, ¬ification_sequence_badusb); return true; } @@ -342,7 +342,7 @@ 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); free(scene_state); plugin_state->current_scene_state = NULL; diff --git a/scenes/generate_token/totp_scene_generate_token.h b/ui/scenes/generate_token/totp_scene_generate_token.h similarity index 84% rename from scenes/generate_token/totp_scene_generate_token.h rename to ui/scenes/generate_token/totp_scene_generate_token.h index 65f9b84e07b..44a3b1c0f0b 100644 --- a/scenes/generate_token/totp_scene_generate_token.h +++ b/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/scenes/token_menu/totp_scene_token_menu.c b/ui/scenes/token_menu/totp_scene_token_menu.c similarity index 95% rename from scenes/token_menu/totp_scene_token_menu.c rename to ui/scenes/token_menu/totp_scene_token_menu.c index d4a837a6981..0cf57e54a03 100644 --- a/scenes/token_menu/totp_scene_token_menu.c +++ b/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) diff --git a/scenes/token_menu/totp_scene_token_menu.h b/ui/scenes/token_menu/totp_scene_token_menu.h similarity index 83% rename from scenes/token_menu/totp_scene_token_menu.h rename to ui/scenes/token_menu/totp_scene_token_menu.h index acb499be832..059b8e5712e 100644 --- a/scenes/token_menu/totp_scene_token_menu.h +++ b/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/scenes/totp_scenes_enum.h b/ui/totp_scenes_enum.h similarity index 100% rename from scenes/totp_scenes_enum.h rename to ui/totp_scenes_enum.h diff --git a/services/ui/ui_controls.c b/ui/ui_controls.c similarity index 100% rename from services/ui/ui_controls.c rename to ui/ui_controls.c diff --git a/services/ui/ui_controls.h b/ui/ui_controls.h similarity index 100% rename from services/ui/ui_controls.h rename to ui/ui_controls.h diff --git a/services/hid_worker/hid_worker.c b/workers/type_code/type_code.c similarity index 62% rename from services/hid_worker/hid_worker.c rename to workers/type_code/type_code.c index 538fdbe97ca..f998ca09d03 100644 --- a/services/hid_worker/hid_worker.c +++ b/workers/type_code/type_code.c @@ -1,4 +1,4 @@ -#include "hid_worker.h" +#include "type_code.h" static const uint8_t hid_number_keys[10] = { HID_KEYBOARD_0, @@ -12,18 +12,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() & TotpTypeCodeWorkerEvtStop; } -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,7 +31,7 @@ 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) { @@ -52,24 +52,24 @@ 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); + TotpTypeCodeWorkerEvtStop | TotpTypeCodeWorkerEvtType, FuriFlagWaitAny, FuriWaitForever); furi_check((flags & FuriFlagError) == 0); //-V562 - if(flags & TotpHidWorkerEvtStop) break; + if(flags & TotpTypeCodeWorkerEvtStop) 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 & TotpTypeCodeWorkerEvtType) { + totp_type_code_worker_type_code(h_context); } release_mutex(&context_mutex, h_context); @@ -80,8 +80,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 +89,22 @@ 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), TotpTypeCodeWorkerEvtStop); 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, TotpTypeCodeWorkerEvtFlags 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/workers/type_code/type_code.h b/workers/type_code/type_code.h new file mode 100644 index 00000000000..09ab9623944 --- /dev/null +++ b/workers/type_code/type_code.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +typedef struct { + char* string; + uint8_t string_length; + FuriThread* thread; + FuriMutex* string_sync; + FuriHalUsbInterface* usb_mode_prev; +} TotpTypeCodeWorkerContext; + +typedef enum { + TotpTypeCodeWorkerEvtReserved = (1 << 0), + TotpTypeCodeWorkerEvtStop = (1 << 1), + TotpTypeCodeWorkerEvtType = (1 << 2) +} TotpTypeCodeWorkerEvtFlags; + +TotpTypeCodeWorkerContext* totp_type_code_worker_start(); +void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context); +void totp_type_code_worker_notify(TotpTypeCodeWorkerContext* context, TotpTypeCodeWorkerEvtFlags event); \ No newline at end of file