mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-20 03:41:42 +03:00
parent
c9cc2b5e20
commit
8373a21af2
6
applications/external/totp/application.fam
vendored
6
applications/external/totp/application.fam
vendored
@ -9,10 +9,14 @@ App(
|
||||
"dialogs",
|
||||
"storage",
|
||||
"input",
|
||||
"notification"
|
||||
"notification",
|
||||
"bt"
|
||||
],
|
||||
stack_size=2 * 1024,
|
||||
order=20,
|
||||
fap_author="Alexander Kopachov (@akopachov)",
|
||||
fap_description="Software-based TOTP authenticator for Flipper Zero device",
|
||||
fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
|
||||
fap_category="Misc",
|
||||
fap_icon_assets="images",
|
||||
fap_icon="totp_10px.png",
|
||||
|
3
applications/external/totp/cli/cli.c
vendored
3
applications/external/totp/cli/cli.c
vendored
@ -12,6 +12,7 @@
|
||||
#include "commands/pin/pin.h"
|
||||
#include "commands/notification/notification.h"
|
||||
#include "commands/reset/reset.h"
|
||||
#include "commands/automation/automation.h"
|
||||
|
||||
static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
|
||||
TOTP_CLI_PRINTF_ERROR(
|
||||
@ -57,6 +58,8 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
|
||||
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 if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_AUTOMATION) == 0) {
|
||||
totp_cli_command_automation_handle(plugin_state, args, cli);
|
||||
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_RESET) == 0) {
|
||||
totp_cli_command_reset_handle(cli, cli_context->event_queue);
|
||||
} else {
|
||||
|
133
applications/external/totp/cli/commands/automation/automation.c
vendored
Normal file
133
applications/external/totp/cli/commands/automation/automation.c
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
#include "automation.h"
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../ui/scene_director.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD "automation"
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE "none"
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB "usb"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT "bt"
|
||||
#endif
|
||||
|
||||
void totp_cli_command_automation_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_AUTOMATION " Get or set automation method\r\n");
|
||||
}
|
||||
|
||||
void totp_cli_command_automation_docopt_usage() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_AUTOMATION " " DOCOPT_OPTIONAL(
|
||||
DOCOPT_MULTIPLE(DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD))) "\r\n");
|
||||
}
|
||||
|
||||
void totp_cli_command_automation_docopt_arguments() {
|
||||
TOTP_CLI_PRINTF(
|
||||
" " TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD
|
||||
" Automation method to be set. Must be one of [" TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE
|
||||
", " TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
", " TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT
|
||||
#endif
|
||||
"]\r\n");
|
||||
}
|
||||
|
||||
static void totp_cli_command_automation_print_method(AutomationMethod method, char* color) {
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
bool has_previous_method = false;
|
||||
#endif
|
||||
if(method & AutomationMethodBadUsb) {
|
||||
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB "\"");
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
has_previous_method = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(method & AutomationMethodBadBt) {
|
||||
if(has_previous_method) {
|
||||
TOTP_CLI_PRINTF_COLORFUL(color, " and ");
|
||||
}
|
||||
|
||||
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT "\"");
|
||||
}
|
||||
#endif
|
||||
|
||||
if(method == AutomationMethodNone) {
|
||||
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE "\"");
|
||||
}
|
||||
}
|
||||
|
||||
void totp_cli_command_automation_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;
|
||||
AutomationMethod new_method = AutomationMethodNone;
|
||||
bool args_valid = true;
|
||||
while(args_read_string_and_trim(args, temp_str)) {
|
||||
if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE) == 0) {
|
||||
new_method_provided = true;
|
||||
new_method = AutomationMethodNone;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB) == 0) {
|
||||
new_method_provided = true;
|
||||
new_method |= AutomationMethodBadUsb;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT) == 0) {
|
||||
new_method_provided = true;
|
||||
new_method |= AutomationMethodBadBt;
|
||||
}
|
||||
#endif
|
||||
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->automation_method = new_method;
|
||||
if(totp_config_file_update_automation_method(new_method) ==
|
||||
TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS("Automation method is set to ");
|
||||
totp_cli_command_automation_print_method(new_method, TOTP_CLI_COLOR_SUCCESS);
|
||||
cli_nl();
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(!(new_method & AutomationMethodBadBt) &&
|
||||
plugin_state->bt_type_code_worker_context != NULL) {
|
||||
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
|
||||
plugin_state->bt_type_code_worker_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(previous_scene != TotpSceneNone) {
|
||||
totp_scene_director_activate_scene(plugin_state, previous_scene, NULL);
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINTF_INFO("Current automation method is ");
|
||||
totp_cli_command_automation_print_method(
|
||||
plugin_state->automation_method, TOTP_CLI_COLOR_INFO);
|
||||
cli_nl();
|
||||
}
|
||||
} while(false);
|
||||
|
||||
furi_string_free(temp_str);
|
||||
}
|
11
applications/external/totp/cli/commands/automation/automation.h
vendored
Normal file
11
applications/external/totp/cli/commands/automation/automation.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION "automation"
|
||||
|
||||
void totp_cli_command_automation_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
void totp_cli_command_automation_docopt_commands();
|
||||
void totp_cli_command_automation_docopt_usage();
|
||||
void totp_cli_command_automation_docopt_arguments();
|
@ -8,6 +8,7 @@
|
||||
#include "../pin/pin.h"
|
||||
#include "../notification/notification.h"
|
||||
#include "../reset/reset.h"
|
||||
#include "../automation/automation.h"
|
||||
|
||||
void totp_cli_command_help_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
|
||||
@ -31,6 +32,7 @@ void totp_cli_command_help_handle() {
|
||||
totp_cli_command_pin_docopt_usage();
|
||||
totp_cli_command_notification_docopt_usage();
|
||||
totp_cli_command_reset_docopt_usage();
|
||||
totp_cli_command_automation_docopt_usage();
|
||||
cli_nl();
|
||||
TOTP_CLI_PRINTF("Commands:\r\n");
|
||||
totp_cli_command_help_docopt_commands();
|
||||
@ -42,12 +44,14 @@ void totp_cli_command_help_handle() {
|
||||
totp_cli_command_pin_docopt_commands();
|
||||
totp_cli_command_notification_docopt_commands();
|
||||
totp_cli_command_reset_docopt_commands();
|
||||
totp_cli_command_automation_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();
|
||||
totp_cli_command_automation_docopt_arguments();
|
||||
cli_nl();
|
||||
TOTP_CLI_PRINTF("Options:\r\n");
|
||||
totp_cli_command_add_docopt_options();
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "../../../ui/scene_director.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD "method"
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD "notification"
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE "none"
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "sound"
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "vibro"
|
||||
|
2
applications/external/totp/features_config.h
vendored
Normal file
2
applications/external/totp/features_config.h
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#define TOTP_BADBT_TYPE_ENABLED
|
||||
#define TOTP_BADBT_TYPE_ICON_ENABLED
|
BIN
applications/external/totp/images/hid_ble_10x7.png
vendored
Normal file
BIN
applications/external/totp/images/hid_ble_10x7.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 B |
@ -4,6 +4,7 @@
|
||||
#include "../list/list.h"
|
||||
#include "../../types/common.h"
|
||||
#include "../../types/token_info.h"
|
||||
#include "../../features_config.h"
|
||||
#include "migrations/config_migration_v1_to_v2.h"
|
||||
#include "migrations/config_migration_v2_to_v3.h"
|
||||
|
||||
@ -136,6 +137,14 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
||||
|
||||
tmp_uint32 = AutomationMethodBadUsb;
|
||||
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||
flipper_format_write_comment_cstr(
|
||||
fff_data_file,
|
||||
"Automation method (0 - None, 1 - BadUSB, 2 - BadBT, 3 - BadUSB and BadBT)");
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1);
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
|
||||
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||
@ -329,6 +338,33 @@ TotpConfigFileUpdateResult
|
||||
return update_result;
|
||||
}
|
||||
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_automation_method(AutomationMethod new_automation_method) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
|
||||
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
uint32_t tmp_uint32 = new_automation_method;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
|
||||
TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file;
|
||||
@ -347,6 +383,13 @@ TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginSta
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_uint32 = plugin_state->automation_method;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
@ -409,6 +452,13 @@ TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const p
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_uint32 = plugin_state->automation_method;
|
||||
if(!flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
bool tokens_written = true;
|
||||
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
||||
const TokenInfo* token_info = node->data;
|
||||
@ -594,6 +644,15 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
|
||||
}
|
||||
|
||||
plugin_state->notification_method = tmp_uint32;
|
||||
|
||||
flipper_format_rewind(fff_data_file);
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = AutomationMethodBadUsb;
|
||||
}
|
||||
|
||||
plugin_state->automation_method = tmp_uint32;
|
||||
} while(false);
|
||||
|
||||
furi_string_free(temp_str);
|
||||
|
@ -103,6 +103,14 @@ TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_tim
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_notification_method(NotificationMethod new_notification_method);
|
||||
|
||||
/**
|
||||
* @brief Updates automation method in an application config file
|
||||
* @param new_automation_method new automation method to be set
|
||||
* @return Config file update result
|
||||
*/
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_automation_method(AutomationMethod new_automation_method);
|
||||
|
||||
/**
|
||||
* @brief Updates application user settings
|
||||
* @param plugin_state application state
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
||||
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
|
||||
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
|
||||
|
||||
#define TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||
#define TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||
|
16
applications/external/totp/totp_app.c
vendored
16
applications/external/totp/totp_app.c
vendored
@ -8,6 +8,7 @@
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
#include "features_config.h"
|
||||
#include "services/config/config.h"
|
||||
#include "types/plugin_state.h"
|
||||
#include "types/token_info.h"
|
||||
@ -108,6 +109,14 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
plugin_state->bt_type_code_worker_context = totp_bt_type_code_worker_init();
|
||||
} else {
|
||||
plugin_state->bt_type_code_worker_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -130,6 +139,13 @@ static void totp_plugin_state_free(PluginState* plugin_state) {
|
||||
free(plugin_state->crypto_verify_data);
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(plugin_state->bt_type_code_worker_context != NULL) {
|
||||
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
|
||||
plugin_state->bt_type_code_worker_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
free(plugin_state);
|
||||
}
|
||||
|
13
applications/external/totp/types/automation_method.h
vendored
Normal file
13
applications/external/totp/types/automation_method.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../features_config.h"
|
||||
|
||||
typedef uint8_t AutomationMethod;
|
||||
|
||||
enum AutomationMethods {
|
||||
AutomationMethodNone = 0b00,
|
||||
AutomationMethodBadUsb = 0b01,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
AutomationMethodBadBt = 0b10,
|
||||
#endif
|
||||
};
|
17
applications/external/totp/types/plugin_state.h
vendored
17
applications/external/totp/types/plugin_state.h
vendored
@ -3,9 +3,14 @@
|
||||
#include <notification/notification.h>
|
||||
#include <gui/gui.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../features_config.h"
|
||||
#include "../lib/list/list.h"
|
||||
#include "../ui/totp_scenes_enum.h"
|
||||
#include "notification_method.h"
|
||||
#include "automation_method.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
#define TOTP_IV_SIZE 16
|
||||
|
||||
@ -92,4 +97,16 @@ typedef struct {
|
||||
* @brief Main rendering loop mutex
|
||||
*/
|
||||
FuriMutex* mutex;
|
||||
|
||||
/**
|
||||
* @brief Automation method
|
||||
*/
|
||||
AutomationMethod automation_method;
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
/**
|
||||
* @brief Bad-Bluetooth worker context
|
||||
*/
|
||||
TotpBtTypeCodeWorkerContext* bt_type_code_worker_context;
|
||||
#endif
|
||||
} PluginState;
|
||||
|
@ -37,7 +37,9 @@ void totp_scene_director_activate_scene(
|
||||
}
|
||||
|
||||
void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state) {
|
||||
switch(plugin_state->current_scene) {
|
||||
Scene current_scene = plugin_state->current_scene;
|
||||
plugin_state->current_scene = TotpSceneNone;
|
||||
switch(current_scene) {
|
||||
case TotpSceneGenerateToken:
|
||||
totp_scene_generate_token_deactivate(plugin_state);
|
||||
break;
|
||||
|
@ -10,16 +10,35 @@
|
||||
#include "../../../services/convert/convert.h"
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include "../../../types/nullable.h"
|
||||
#include "../../../features_config.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
|
||||
typedef enum { HoursInput, MinutesInput, Sound, Vibro, ConfirmButton } Control;
|
||||
typedef enum {
|
||||
HoursInput,
|
||||
MinutesInput,
|
||||
Sound,
|
||||
Vibro,
|
||||
BadUsb,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
BadBt,
|
||||
#endif
|
||||
ConfirmButton
|
||||
} Control;
|
||||
|
||||
typedef struct {
|
||||
int8_t tz_offset_hours;
|
||||
uint8_t tz_offset_minutes;
|
||||
bool notification_sound;
|
||||
bool notification_vibro;
|
||||
bool badusb_enabled;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
bool badbt_enabled;
|
||||
#endif
|
||||
uint8_t y_offset;
|
||||
TotpNullable_uint16_t current_token_index;
|
||||
Control selected_control;
|
||||
@ -47,6 +66,10 @@ void totp_scene_app_settings_activate(
|
||||
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;
|
||||
scene_state->badusb_enabled = plugin_state->automation_method & AutomationMethodBadUsb;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
scene_state->badbt_enabled = plugin_state->automation_method & AutomationMethodBadBt;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void two_digit_to_str(int8_t num, char* str) {
|
||||
@ -73,7 +96,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
|
||||
char tmp_str[4];
|
||||
two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(canvas, 0, 16 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
|
||||
canvas_draw_str_aligned(canvas, 0, 17 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
@ -84,7 +107,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
|
||||
two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 34 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
|
||||
canvas, 0, 35 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
@ -104,7 +127,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
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:");
|
||||
canvas_draw_str_aligned(canvas, 0, 81 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
@ -113,7 +136,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
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:");
|
||||
canvas_draw_str_aligned(canvas, 0, 99 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
@ -122,10 +145,43 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == Vibro);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 123 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
138 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badusb_enabled],
|
||||
scene_state->selected_control == BadUsb);
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
156 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badbt_enabled],
|
||||
scene_state->selected_control == BadBt);
|
||||
#endif
|
||||
|
||||
ui_control_button_render(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 24,
|
||||
115 - scene_state->y_offset,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
178 - scene_state->y_offset,
|
||||
#else
|
||||
165 - scene_state->y_offset,
|
||||
#endif
|
||||
48,
|
||||
13,
|
||||
"Confirm",
|
||||
@ -152,7 +208,9 @@ bool totp_scene_app_settings_handle_event(
|
||||
HoursInput,
|
||||
ConfirmButton,
|
||||
RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > MinutesInput) {
|
||||
if(scene_state->selected_control > Vibro) {
|
||||
scene_state->y_offset = 128;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
@ -161,7 +219,9 @@ bool totp_scene_app_settings_handle_event(
|
||||
case InputKeyDown:
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->selected_control, 1, HoursInput, ConfirmButton, RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > MinutesInput) {
|
||||
if(scene_state->selected_control > Vibro) {
|
||||
scene_state->y_offset = 128;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
@ -178,7 +238,14 @@ bool totp_scene_app_settings_handle_event(
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == HoursInput) {
|
||||
@ -191,7 +258,14 @@ bool totp_scene_app_settings_handle_event(
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(scene_state->selected_control == ConfirmButton) {
|
||||
@ -204,12 +278,26 @@ bool totp_scene_app_settings_handle_event(
|
||||
(scene_state->notification_vibro ? NotificationMethodVibro :
|
||||
NotificationMethodNone);
|
||||
|
||||
plugin_state->automation_method =
|
||||
scene_state->badusb_enabled ? AutomationMethodBadUsb : AutomationMethodNone;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
plugin_state->automation_method |= scene_state->badbt_enabled ? AutomationMethodBadBt :
|
||||
AutomationMethodNone;
|
||||
#endif
|
||||
|
||||
if(totp_config_file_update_user_settings(plugin_state) !=
|
||||
TotpConfigFileUpdateSuccess) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(!scene_state->badbt_enabled && plugin_state->bt_type_code_worker_context != NULL) {
|
||||
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
|
||||
plugin_state->bt_type_code_worker_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!scene_state->current_token_index.is_null) {
|
||||
TokenMenuSceneContext generate_scene_context = {
|
||||
.current_token_index = scene_state->current_token_index.value};
|
||||
|
@ -14,7 +14,11 @@
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../token_menu/totp_scene_token_menu.h"
|
||||
#include "../../../workers/type_code/type_code.h"
|
||||
#include "../../../features_config.h"
|
||||
#include "../../../workers/usb_type_code/usb_type_code.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
static const uint8_t PROGRESS_BAR_MARGIN = 3;
|
||||
static const uint8_t PROGRESS_BAR_HEIGHT = 4;
|
||||
@ -25,9 +29,10 @@ typedef struct {
|
||||
bool need_token_update;
|
||||
TokenInfo* current_token;
|
||||
uint32_t last_token_gen_time;
|
||||
TotpTypeCodeWorkerContext* type_code_worker_context;
|
||||
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
||||
NotificationMessage const** notification_sequence_new_token;
|
||||
NotificationMessage const** notification_sequence_badusb;
|
||||
FuriMutex* last_code_update_sync;
|
||||
} SceneState;
|
||||
|
||||
static const NotificationSequence*
|
||||
@ -72,7 +77,7 @@ static const NotificationSequence*
|
||||
}
|
||||
|
||||
static const NotificationSequence*
|
||||
get_notification_sequence_badusb(const PluginState* plugin_state, SceneState* scene_state) {
|
||||
get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) {
|
||||
if(scene_state->notification_sequence_badusb == NULL) {
|
||||
uint8_t i = 0;
|
||||
uint8_t length = 3;
|
||||
@ -201,9 +206,28 @@ 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->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;
|
||||
|
||||
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
|
||||
&scene_state->last_code[0],
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
if(plugin_state->bt_type_code_worker_context == NULL) {
|
||||
plugin_state->bt_type_code_worker_context = totp_bt_type_code_worker_init();
|
||||
}
|
||||
totp_bt_type_code_worker_start(
|
||||
plugin_state->bt_type_code_worker_context,
|
||||
&scene_state->last_code[0],
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||
@ -242,8 +266,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
const TokenInfo* tokenInfo = scene_state->current_token;
|
||||
|
||||
if(tokenInfo->token != NULL && tokenInfo->token_length > 0) {
|
||||
furi_mutex_acquire(
|
||||
scene_state->type_code_worker_context->string_sync, FuriWaitForever);
|
||||
furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever);
|
||||
size_t key_length;
|
||||
uint8_t* key = totp_crypto_decrypt(
|
||||
tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length);
|
||||
@ -262,12 +285,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->type_code_worker_context->string_sync, FuriWaitForever);
|
||||
furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever);
|
||||
int_token_to_str(0, scene_state->last_code, tokenInfo->digits);
|
||||
}
|
||||
|
||||
furi_mutex_release(scene_state->type_code_worker_context->string_sync);
|
||||
furi_mutex_release(scene_state->last_code_update_sync);
|
||||
|
||||
if(is_new_token_time) {
|
||||
notification_message(
|
||||
@ -327,6 +349,15 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9);
|
||||
}
|
||||
|
||||
#if defined(TOTP_BADBT_TYPE_ENABLED) && defined(TOTP_BADBT_TYPE_ICON_ENABLED)
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt &&
|
||||
plugin_state->bt_type_code_worker_context != NULL &&
|
||||
plugin_state->bt_type_code_worker_context->is_advertising) {
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, SCREEN_HEIGHT_CENTER + 13, &I_hid_ble_10x7);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool totp_scene_generate_token_handle_event(
|
||||
@ -341,15 +372,28 @@ bool totp_scene_generate_token_handle_event(
|
||||
}
|
||||
|
||||
SceneState* scene_state;
|
||||
if(event->input.type == InputTypeLong && event->input.key == InputKeyDown) {
|
||||
if(event->input.type == InputTypeLong) {
|
||||
if(event->input.key == InputKeyDown && plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||
totp_type_code_worker_notify(
|
||||
scene_state->type_code_worker_context, TotpTypeCodeWorkerEventType);
|
||||
totp_usb_type_code_worker_notify(
|
||||
scene_state->usb_type_code_worker_context, TotpUsbTypeCodeWorkerEventType);
|
||||
notification_message(
|
||||
plugin_state->notification_app,
|
||||
get_notification_sequence_badusb(plugin_state, scene_state));
|
||||
get_notification_sequence_automation(plugin_state, scene_state));
|
||||
return true;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(event->input.key == InputKeyUp && plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||
totp_bt_type_code_worker_notify(
|
||||
plugin_state->bt_type_code_worker_context, TotpBtTypeCodeWorkerEventType);
|
||||
notification_message(
|
||||
plugin_state->notification_app,
|
||||
get_notification_sequence_automation(plugin_state, scene_state));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(event->input.type != InputTypePress && event->input.type != InputTypeRepeat) {
|
||||
return true;
|
||||
@ -400,7 +444,14 @@ 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_type_code_worker_stop(scene_state->type_code_worker_context);
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context);
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
totp_bt_type_code_worker_stop(plugin_state->bt_type_code_worker_context);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(scene_state->notification_sequence_new_token != NULL) {
|
||||
free(scene_state->notification_sequence_new_token);
|
||||
@ -410,6 +461,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
|
||||
free(scene_state->notification_sequence_badusb);
|
||||
}
|
||||
|
||||
furi_mutex_free(scene_state->last_code_update_sync);
|
||||
|
||||
free(scene_state);
|
||||
plugin_state->current_scene_state = NULL;
|
||||
}
|
||||
|
141
applications/external/totp/workers/bt_type_code/bt_type_code.c
vendored
Normal file
141
applications/external/totp/workers/bt_type_code/bt_type_code.c
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
#include "bt_type_code.h"
|
||||
#include <furi_hal_bt_hid.h>
|
||||
#include <storage/storage.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../../services/convert/convert.h"
|
||||
#include "../constants.h"
|
||||
|
||||
#define HID_BT_KEYS_STORAGE_PATH EXT_PATH("authenticator/.bt_hid.keys")
|
||||
|
||||
static inline bool totp_type_code_worker_stop_requested() {
|
||||
return furi_thread_flags_get() & TotpBtTypeCodeWorkerEventStop;
|
||||
}
|
||||
|
||||
static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context) {
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
furi_delay_ms(500);
|
||||
i++;
|
||||
} while(!furi_hal_bt_is_active() && i < 100 && !totp_type_code_worker_stop_requested());
|
||||
|
||||
if(furi_hal_bt_is_active() && 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 = CONVERT_CHAR_TO_DIGIT(context->string[i]);
|
||||
if(digit > 9) break;
|
||||
uint8_t hid_kb_key = hid_number_keys[digit];
|
||||
furi_hal_bt_hid_kb_press(hid_kb_key);
|
||||
furi_delay_ms(30);
|
||||
furi_hal_bt_hid_kb_release(hid_kb_key);
|
||||
i++;
|
||||
}
|
||||
|
||||
furi_mutex_release(context->string_sync);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t totp_type_code_worker_callback(void* context) {
|
||||
furi_assert(context);
|
||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(context_mutex == NULL) {
|
||||
return 251;
|
||||
}
|
||||
|
||||
TotpBtTypeCodeWorkerContext* bt_context = context;
|
||||
|
||||
furi_hal_bt_start_advertising();
|
||||
bt_context->is_advertising = true;
|
||||
|
||||
while(true) {
|
||||
uint32_t flags = furi_thread_flags_wait(
|
||||
TotpBtTypeCodeWorkerEventStop | TotpBtTypeCodeWorkerEventType,
|
||||
FuriFlagWaitAny,
|
||||
FuriWaitForever);
|
||||
furi_check((flags & FuriFlagError) == 0); //-V562
|
||||
if(flags & TotpBtTypeCodeWorkerEventStop) break;
|
||||
|
||||
if(furi_mutex_acquire(context_mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
if(flags & TotpBtTypeCodeWorkerEventType) {
|
||||
totp_type_code_worker_type_code(bt_context);
|
||||
}
|
||||
|
||||
furi_mutex_release(context_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
furi_hal_bt_stop_advertising();
|
||||
|
||||
bt_context->is_advertising = false;
|
||||
|
||||
furi_mutex_free(context_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_start(
|
||||
TotpBtTypeCodeWorkerContext* context,
|
||||
char* code_buf,
|
||||
uint8_t code_buf_length,
|
||||
FuriMutex* code_buf_update_sync) {
|
||||
furi_assert(context != NULL);
|
||||
context->string = code_buf;
|
||||
context->string_length = code_buf_length;
|
||||
context->string_sync = code_buf_update_sync;
|
||||
context->thread = furi_thread_alloc();
|
||||
furi_thread_set_name(context->thread, "TOTPBtHidWorker");
|
||||
furi_thread_set_stack_size(context->thread, 1024);
|
||||
furi_thread_set_context(context->thread, context);
|
||||
furi_thread_set_callback(context->thread, totp_type_code_worker_callback);
|
||||
furi_thread_start(context->thread);
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpBtTypeCodeWorkerEventStop);
|
||||
furi_thread_join(context->thread);
|
||||
furi_thread_free(context->thread);
|
||||
context->thread = NULL;
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_notify(
|
||||
TotpBtTypeCodeWorkerContext* context,
|
||||
TotpBtTypeCodeWorkerEvent event) {
|
||||
furi_assert(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), event);
|
||||
}
|
||||
|
||||
TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
TotpBtTypeCodeWorkerContext* context = malloc(sizeof(TotpBtTypeCodeWorkerContext));
|
||||
furi_check(context != NULL);
|
||||
|
||||
context->bt = furi_record_open(RECORD_BT);
|
||||
context->is_advertising = false;
|
||||
bt_disconnect(context->bt);
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
|
||||
if(!bt_set_profile(context->bt, BtProfileHidKeyboard)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Failed to switch BT to keyboard HID profile");
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
|
||||
if(context->thread != NULL) {
|
||||
totp_bt_type_code_worker_stop(context);
|
||||
}
|
||||
|
||||
bt_disconnect(context->bt);
|
||||
bt_keys_storage_set_default_path(context->bt);
|
||||
|
||||
if(!bt_set_profile(context->bt, BtProfileSerial)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Failed to switch BT to Serial profile");
|
||||
}
|
||||
furi_record_close(RECORD_BT);
|
||||
context->bt = NULL;
|
||||
|
||||
free(context);
|
||||
}
|
35
applications/external/totp/workers/bt_type_code/bt_type_code.h
vendored
Normal file
35
applications/external/totp/workers/bt_type_code/bt_type_code.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <furi/furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <bt/bt_service/bt.h>
|
||||
|
||||
typedef uint8_t TotpBtTypeCodeWorkerEvent;
|
||||
|
||||
typedef struct {
|
||||
char* string;
|
||||
uint8_t string_length;
|
||||
FuriThread* thread;
|
||||
FuriMutex* string_sync;
|
||||
Bt* bt;
|
||||
bool is_advertising;
|
||||
} TotpBtTypeCodeWorkerContext;
|
||||
|
||||
enum TotpBtTypeCodeWorkerEvents {
|
||||
TotpBtTypeCodeWorkerEventReserved = (1 << 0),
|
||||
TotpBtTypeCodeWorkerEventStop = (1 << 1),
|
||||
TotpBtTypeCodeWorkerEventType = (1 << 2)
|
||||
};
|
||||
|
||||
TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init();
|
||||
void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context);
|
||||
void totp_bt_type_code_worker_start(
|
||||
TotpBtTypeCodeWorkerContext* context,
|
||||
char* code_buf,
|
||||
uint8_t code_buf_length,
|
||||
FuriMutex* code_buf_update_sync);
|
||||
void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context);
|
||||
void totp_bt_type_code_worker_notify(
|
||||
TotpBtTypeCodeWorkerContext* context,
|
||||
TotpBtTypeCodeWorkerEvent event);
|
14
applications/external/totp/workers/constants.c
vendored
Normal file
14
applications/external/totp/workers/constants.c
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
#include "constants.h"
|
||||
#include <furi_hal.h>
|
||||
|
||||
const uint8_t hid_number_keys[10] = {
|
||||
HID_KEYBOARD_0,
|
||||
HID_KEYBOARD_1,
|
||||
HID_KEYBOARD_2,
|
||||
HID_KEYBOARD_3,
|
||||
HID_KEYBOARD_4,
|
||||
HID_KEYBOARD_5,
|
||||
HID_KEYBOARD_6,
|
||||
HID_KEYBOARD_7,
|
||||
HID_KEYBOARD_8,
|
||||
HID_KEYBOARD_9};
|
4
applications/external/totp/workers/constants.h
vendored
Normal file
4
applications/external/totp/workers/constants.h
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint8_t hid_number_keys[10];
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <furi/furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
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);
|
@ -1,19 +1,8 @@
|
||||
#include "type_code.h"
|
||||
#include "usb_type_code.h"
|
||||
#include "../../services/convert/convert.h"
|
||||
#include "../constants.h"
|
||||
|
||||
static const uint8_t hid_number_keys[10] = {
|
||||
HID_KEYBOARD_0,
|
||||
HID_KEYBOARD_1,
|
||||
HID_KEYBOARD_2,
|
||||
HID_KEYBOARD_3,
|
||||
HID_KEYBOARD_4,
|
||||
HID_KEYBOARD_5,
|
||||
HID_KEYBOARD_6,
|
||||
HID_KEYBOARD_7,
|
||||
HID_KEYBOARD_8,
|
||||
HID_KEYBOARD_9};
|
||||
|
||||
static void totp_type_code_worker_restore_usb_mode(TotpTypeCodeWorkerContext* context) {
|
||||
static void totp_type_code_worker_restore_usb_mode(TotpUsbTypeCodeWorkerContext* context) {
|
||||
if(context->usb_mode_prev != NULL) {
|
||||
furi_hal_usb_set_config(context->usb_mode_prev, NULL);
|
||||
context->usb_mode_prev = NULL;
|
||||
@ -21,10 +10,10 @@ static void totp_type_code_worker_restore_usb_mode(TotpTypeCodeWorkerContext* co
|
||||
}
|
||||
|
||||
static inline bool totp_type_code_worker_stop_requested() {
|
||||
return furi_thread_flags_get() & TotpTypeCodeWorkerEventStop;
|
||||
return furi_thread_flags_get() & TotpUsbTypeCodeWorkerEventStop;
|
||||
}
|
||||
|
||||
static void totp_type_code_worker_type_code(TotpTypeCodeWorkerContext* context) {
|
||||
static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* 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);
|
||||
@ -57,6 +46,7 @@ static void totp_type_code_worker_type_code(TotpTypeCodeWorkerContext* context)
|
||||
}
|
||||
|
||||
static int32_t totp_type_code_worker_callback(void* context) {
|
||||
furi_assert(context);
|
||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(context_mutex == NULL) {
|
||||
return 251;
|
||||
@ -64,14 +54,14 @@ static int32_t totp_type_code_worker_callback(void* context) {
|
||||
|
||||
while(true) {
|
||||
uint32_t flags = furi_thread_flags_wait(
|
||||
TotpTypeCodeWorkerEventStop | TotpTypeCodeWorkerEventType,
|
||||
TotpUsbTypeCodeWorkerEventStop | TotpUsbTypeCodeWorkerEventType,
|
||||
FuriFlagWaitAny,
|
||||
FuriWaitForever);
|
||||
furi_check((flags & FuriFlagError) == 0); //-V562
|
||||
if(flags & TotpTypeCodeWorkerEventStop) break;
|
||||
if(flags & TotpUsbTypeCodeWorkerEventStop) break;
|
||||
|
||||
if(furi_mutex_acquire(context_mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
if(flags & TotpTypeCodeWorkerEventType) {
|
||||
if(flags & TotpUsbTypeCodeWorkerEventType) {
|
||||
totp_type_code_worker_type_code(context);
|
||||
}
|
||||
|
||||
@ -84,13 +74,18 @@ static int32_t totp_type_code_worker_callback(void* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TotpTypeCodeWorkerContext* totp_type_code_worker_start() {
|
||||
TotpTypeCodeWorkerContext* context = malloc(sizeof(TotpTypeCodeWorkerContext));
|
||||
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
||||
char* code_buf,
|
||||
uint8_t code_buf_length,
|
||||
FuriMutex* code_buf_update_sync) {
|
||||
TotpUsbTypeCodeWorkerContext* context = malloc(sizeof(TotpUsbTypeCodeWorkerContext));
|
||||
furi_check(context != NULL);
|
||||
context->string_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
context->string = code_buf;
|
||||
context->string_length = code_buf_length;
|
||||
context->string_sync = code_buf_update_sync;
|
||||
context->thread = furi_thread_alloc();
|
||||
context->usb_mode_prev = NULL;
|
||||
furi_thread_set_name(context->thread, "TOTPHidWorker");
|
||||
furi_thread_set_name(context->thread, "TOTPUsbHidWorker");
|
||||
furi_thread_set_stack_size(context->thread, 1024);
|
||||
furi_thread_set_context(context->thread, context);
|
||||
furi_thread_set_callback(context->thread, totp_type_code_worker_callback);
|
||||
@ -98,19 +93,18 @@ TotpTypeCodeWorkerContext* totp_type_code_worker_start() {
|
||||
return context;
|
||||
}
|
||||
|
||||
void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context) {
|
||||
void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpTypeCodeWorkerEventStop);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpUsbTypeCodeWorkerEventStop);
|
||||
furi_thread_join(context->thread);
|
||||
furi_thread_free(context->thread);
|
||||
furi_mutex_free(context->string_sync);
|
||||
totp_type_code_worker_restore_usb_mode(context);
|
||||
free(context);
|
||||
}
|
||||
|
||||
void totp_type_code_worker_notify(
|
||||
TotpTypeCodeWorkerContext* context,
|
||||
TotpTypeCodeWorkerEvent event) {
|
||||
void totp_usb_type_code_worker_notify(
|
||||
TotpUsbTypeCodeWorkerContext* context,
|
||||
TotpUsbTypeCodeWorkerEvent event) {
|
||||
furi_assert(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), event);
|
||||
}
|
30
applications/external/totp/workers/usb_type_code/usb_type_code.h
vendored
Normal file
30
applications/external/totp/workers/usb_type_code/usb_type_code.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <furi/furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
typedef uint8_t TotpUsbTypeCodeWorkerEvent;
|
||||
|
||||
typedef struct {
|
||||
char* string;
|
||||
uint8_t string_length;
|
||||
FuriThread* thread;
|
||||
FuriMutex* string_sync;
|
||||
FuriHalUsbInterface* usb_mode_prev;
|
||||
} TotpUsbTypeCodeWorkerContext;
|
||||
|
||||
enum TotpUsbTypeCodeWorkerEvents {
|
||||
TotpUsbTypeCodeWorkerEventReserved = (1 << 0),
|
||||
TotpUsbTypeCodeWorkerEventStop = (1 << 1),
|
||||
TotpUsbTypeCodeWorkerEventType = (1 << 2)
|
||||
};
|
||||
|
||||
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
||||
char* code_buf,
|
||||
uint8_t code_buf_length,
|
||||
FuriMutex* code_buf_update_sync);
|
||||
void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context);
|
||||
void totp_usb_type_code_worker_notify(
|
||||
TotpUsbTypeCodeWorkerContext* context,
|
||||
TotpUsbTypeCodeWorkerEvent event);
|
Loading…
Reference in New Issue
Block a user