diff --git a/cli/commands/add/add.c b/cli/commands/add/add.c index 6b7572bce09..4cfd4fe06f0 100644 --- a/cli/commands/add/add.c +++ b/cli/commands/add/add.c @@ -60,6 +60,8 @@ void totp_cli_command_add_docopt_options() { " - Type key at the end of token input automation\r\n"); TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME " - Type key at the end of token input automation\r\n"); + TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME + " - Type slower\r\n"); } void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { diff --git a/cli/commands/details/details.c b/cli/commands/details/details.c index 0bee99bb7eb..aa16295a499 100644 --- a/cli/commands/details/details.c +++ b/cli/commands/details/details.c @@ -7,7 +7,14 @@ #include "../../cli_helpers.h" #include "../../common_command_arguments.h" -#define AUTOMATION_FEATURES_PROPERTY_HEADER "Automation features" +#define TOTP_CLI_PRINTF_AUTOMATION_FEATURE(description, header_printed) \ + do { \ + TOTP_CLI_PRINTF( \ + "| %-20s | %-28.28s |\r\n", \ + header_printed ? "" : "Automation features", \ + description); \ + header_printed = true; \ + } while(false) static void print_automation_features(const TokenInfo* token_info) { if(token_info->automation_features == TOKEN_AUTOMATION_FEATURE_NONE) { @@ -17,19 +24,15 @@ static void print_automation_features(const TokenInfo* token_info) { bool header_printed = false; if(token_info->automation_features & TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END) { - TOTP_CLI_PRINTF( - "| %-20s | %-28.28s |\r\n", - AUTOMATION_FEATURES_PROPERTY_HEADER, - "Type key at the end"); - header_printed = true; + TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type key at the end", header_printed); } if(token_info->automation_features & TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END) { - TOTP_CLI_PRINTF( - "| %-20s | %-28.28s |\r\n", - header_printed ? "" : AUTOMATION_FEATURES_PROPERTY_HEADER, - "Type key at the end"); - header_printed = true; + TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type key at the end", header_printed); + } + + if(token_info->automation_features & TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER) { + TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type slower", header_printed); } } diff --git a/types/token_info.c b/types/token_info.c index 19d83448c0d..fd9699ecf0d 100644 --- a/types/token_info.c +++ b/types/token_info.c @@ -118,6 +118,11 @@ bool token_info_set_automation_feature_from_str(TokenInfo* token_info, const Fur return true; } + if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) { + token_info->automation_features |= TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER; + return true; + } + if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) { token_info->automation_features = TOKEN_AUTOMATION_FEATURE_NONE; return true; diff --git a/types/token_info.h b/types/token_info.h index 1af9dfe4e42..fea0c09d72a 100644 --- a/types/token_info.h +++ b/types/token_info.h @@ -14,6 +14,7 @@ #define TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME "none" #define TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME "enter" #define TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME "tab" +#define TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME "slower" typedef uint8_t TokenHashAlgo; typedef uint8_t TokenDigitsCount; @@ -61,17 +62,22 @@ enum TokenAutomationFeatures { /** * @brief No features enabled */ - TOKEN_AUTOMATION_FEATURE_NONE = 0b00, + TOKEN_AUTOMATION_FEATURE_NONE = 0b000, /** * @brief Press "Enter" key at the end as a part of token input automation */ - TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END = 0b01, + TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END = 0b001, /** * @brief Press "Tab" key at the end as a part of token input automation */ - TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END = 0b10 + TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END = 0b010, + + /** + * @brief Press keys slower and wait longer between keystrokes + */ + TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER = 0b100 }; #define TOTP_TOKEN_DIGITS_MAX_COUNT 8 diff --git a/workers/bt_type_code/bt_type_code.c b/workers/bt_type_code/bt_type_code.c index 0dbb586127d..b84dfead929 100644 --- a/workers/bt_type_code/bt_type_code.c +++ b/workers/bt_type_code/bt_type_code.c @@ -11,12 +11,6 @@ static inline bool totp_type_code_worker_stop_requested() { return furi_thread_flags_get() & TotpBtTypeCodeWorkerEventStop; } -static void totp_type_code_worker_press_key(uint8_t key) { - furi_hal_bt_hid_kb_press(key); - furi_delay_ms(30); - furi_hal_bt_hid_kb_release(key); -} - static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context) { uint8_t i = 0; do { @@ -26,7 +20,8 @@ static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context if(context->is_connected && furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) { totp_type_code_worker_execute_automation( - &totp_type_code_worker_press_key, + &furi_hal_bt_hid_kb_press, + &furi_hal_bt_hid_kb_release, context->string, context->string_length, context->flags); diff --git a/workers/common.c b/workers/common.c index b603c4ec1c3..5ca5d4fdf24 100644 --- a/workers/common.c +++ b/workers/common.c @@ -15,8 +15,35 @@ static const uint8_t hid_number_keys[10] = { HID_KEYBOARD_8, HID_KEYBOARD_9}; +static uint32_t get_keystroke_delay(TokenAutomationFeature features) { + if(features & TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER) { + return 100; + } + + return 30; +} + +static uint32_t get_keypress_delay(TokenAutomationFeature features) { + if(features & TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER) { + return 60; + } + + return 30; +} + +static void totp_type_code_worker_press_key( + uint8_t key, + TOTP_AUTOMATION_KEY_HANDLER key_press_fn, + TOTP_AUTOMATION_KEY_HANDLER key_release_fn, + TokenAutomationFeature features) { + (*key_press_fn)(key); + furi_delay_ms(get_keypress_delay(features)); + (*key_release_fn)(key); +} + void totp_type_code_worker_execute_automation( - TOTP_AUTOMATION_PRESS_KEY key_press_fn, + TOTP_AUTOMATION_KEY_HANDLER key_press_fn, + TOTP_AUTOMATION_KEY_HANDLER key_release_fn, const char* string, uint8_t string_length, TokenAutomationFeature features) { @@ -26,17 +53,19 @@ void totp_type_code_worker_execute_automation( uint8_t digit = CONVERT_CHAR_TO_DIGIT(string[i]); if(digit > 9) break; uint8_t hid_kb_key = hid_number_keys[digit]; - (*key_press_fn)(hid_kb_key); + totp_type_code_worker_press_key(hid_kb_key, key_press_fn, key_release_fn, features); + furi_delay_ms(get_keystroke_delay(features)); i++; } if(features & TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END) { - furi_delay_ms(30); - (*key_press_fn)(HID_KEYBOARD_RETURN); + furi_delay_ms(get_keystroke_delay(features)); + totp_type_code_worker_press_key( + HID_KEYBOARD_RETURN, key_press_fn, key_release_fn, features); } if(features & TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END) { - furi_delay_ms(30); - (*key_press_fn)(HID_KEYBOARD_TAB); + furi_delay_ms(get_keystroke_delay(features)); + totp_type_code_worker_press_key(HID_KEYBOARD_TAB, key_press_fn, key_release_fn, features); } } \ No newline at end of file diff --git a/workers/common.h b/workers/common.h index 0bb48d50153..5e3a2006e3f 100644 --- a/workers/common.h +++ b/workers/common.h @@ -2,10 +2,11 @@ #include #include "../types/token_info.h" -typedef void (*TOTP_AUTOMATION_PRESS_KEY)(uint8_t key); +typedef bool (*TOTP_AUTOMATION_KEY_HANDLER)(uint16_t key); void totp_type_code_worker_execute_automation( - TOTP_AUTOMATION_PRESS_KEY key_press_fn, + TOTP_AUTOMATION_KEY_HANDLER key_press_fn, + TOTP_AUTOMATION_KEY_HANDLER key_release_fn, const char* string, uint8_t string_length, TokenAutomationFeature features); \ No newline at end of file diff --git a/workers/usb_type_code/usb_type_code.c b/workers/usb_type_code/usb_type_code.c index 2b36426ea1a..d3e09a06574 100644 --- a/workers/usb_type_code/usb_type_code.c +++ b/workers/usb_type_code/usb_type_code.c @@ -14,12 +14,6 @@ static inline bool totp_type_code_worker_stop_requested() { return furi_thread_flags_get() & TotpUsbTypeCodeWorkerEventStop; } -static void totp_type_code_worker_press_key(uint8_t key) { - furi_hal_hid_kb_press(key); - furi_delay_ms(30); - furi_hal_hid_kb_release(key); -} - static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* context) { context->usb_mode_prev = furi_hal_usb_get_config(); furi_hal_usb_unlock(); @@ -33,7 +27,8 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex if(furi_hal_hid_is_connected() && furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) { totp_type_code_worker_execute_automation( - &totp_type_code_worker_press_key, + &furi_hal_hid_kb_press, + &furi_hal_hid_kb_release, context->string, context->string_length, context->flags);