This commit is contained in:
Willy-JL
2023-08-10 02:18:22 +02:00
92 changed files with 2125 additions and 938 deletions

View File

@@ -4,6 +4,15 @@
#include <gui/gui.h>
#include <font_info.h>
/**
* @brief Draw string using given font
* @param canvas canvas to draw string at
* @param x horizontal position
* @param y vertical position
* @param text string to draw
* @param text_length string length
* @param font font to be used to draw string
*/
void canvas_draw_str_ex(
Canvas* canvas,
uint8_t x,

View File

@@ -3,5 +3,16 @@
#include <dialogs/dialogs.h>
#include "../types/plugin_state.h"
/**
* @brief Shows standard dialog about the fact that error occurred when loading config file
* @param plugin_state application state
* @return dialog button which user pressed to close the dialog
*/
DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state);
/**
* @brief Shows standard dialog about the fact that error occurred when updating config file
* @param plugin_state application state
* @return dialog button which user pressed to close the dialog
*/
DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state);

View File

@@ -116,3 +116,8 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
return processing;
}
void totp_scene_director_force_redraw(PluginState* const plugin_state) {
PluginEvent event = {.type = EventForceRedraw};
furi_message_queue_put(plugin_state->event_queue, &event, FuriWaitForever);
}

View File

@@ -33,3 +33,9 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
* @return \c true if event handled and applilcation should continue; \c false if application should be closed
*/
bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state);
/**
* @brief Forces screen to be redraw\updated
* @param plugin_state application state
*/
void totp_scene_director_force_redraw(PluginState* const plugin_state);

View File

@@ -42,7 +42,7 @@ typedef struct {
struct TotpAddContext {
SceneState* scene_state;
uint8_t* iv;
const CryptoSettings* crypto_settings;
};
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
@@ -58,7 +58,7 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
context_t->scene_state->token_secret,
context_t->scene_state->token_secret_length,
PlainTokenSecretEncodingBase32,
context_t->iv)) {
context_t->crypto_settings)) {
return TotpIteratorUpdateTokenResultInvalidSecret;
}
@@ -271,7 +271,7 @@ bool totp_scene_add_new_token_handle_event(
break;
case ConfirmButton: {
struct TotpAddContext add_context = {
.iv = plugin_state->iv, .scene_state = scene_state};
.scene_state = scene_state, .crypto_settings = &plugin_state->crypto_settings};
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(

View File

@@ -13,14 +13,30 @@
#include "../../../services/convert/convert.h"
#include <roll_value.h>
#include "../../../features_config.h"
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
#define AUTOMATION_LIST_MAX_INDEX (3)
#else
#define AUTOMATION_LIST_MAX_INDEX (1)
#endif
#define BAD_KB_LAYOUT_LIST_MAX_INDEX (1)
#define FONT_TEST_STR_LENGTH (7)
static const char* YES_NO_LIST[] = {"NO", "YES"};
static const char* ON_OFF_LIST[] = {"OFF", "ON"};
static const char* AUTOMATION_LIST[] = {
"None",
"USB"
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
,
"Bluetooth",
"BT and USB"
#endif
};
static const char* BAD_KB_LAYOUT_LIST[] = {"QWERTY", "AZERTY"};
static const char* FONT_TEST_STR = "0123BCD";
static const uint8_t FONT_TEST_STR_LENGTH = 7;
typedef enum {
HoursInput,
@@ -28,10 +44,8 @@ typedef enum {
FontSelect,
SoundSwitch,
VibroSwitch,
BadUsbSwitch,
#ifdef TOTP_BADBT_TYPE_ENABLED
BadBtSwitch,
#endif
AutomationSwitch,
BadKeyboardLayoutSelect,
ConfirmButton
} Control;
@@ -40,11 +54,9 @@ typedef struct {
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;
AutomationMethod automation_method;
uint16_t y_offset;
AutomationKeyboardLayout automation_kb_layout;
Control selected_control;
uint8_t active_font;
} SceneState;
@@ -60,10 +72,11 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
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
scene_state->automation_method =
MIN(plugin_state->automation_method, AUTOMATION_LIST_MAX_INDEX);
scene_state->automation_kb_layout =
MIN(plugin_state->automation_kb_layout, BAD_KB_LAYOUT_LIST_MAX_INDEX);
scene_state->active_font = plugin_state->active_font_index;
}
@@ -83,127 +96,121 @@ static void two_digit_to_str(int8_t num, char* str) {
void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plugin_state) {
const SceneState* scene_state = plugin_state->current_scene_state;
if(scene_state->selected_control < FontSelect) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 0 - scene_state->y_offset, AlignLeft, AlignTop, "Timezone offset");
canvas_set_font(canvas, FontSecondary);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 0 - scene_state->y_offset, AlignLeft, AlignTop, "Timezone offset");
canvas_set_font(canvas, FontSecondary);
char tmp_str[4];
two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]);
canvas_draw_str_aligned(
canvas, 0, 17 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
ui_control_select_render(
canvas,
36,
10 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
&tmp_str[0],
scene_state->selected_control == HoursInput);
char tmp_str[4];
two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]);
canvas_draw_str_aligned(canvas, 0, 17 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
ui_control_select_render(
canvas,
36,
10 - scene_state->y_offset,
SCREEN_WIDTH - 36,
&tmp_str[0],
scene_state->selected_control == HoursInput);
two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]);
canvas_draw_str_aligned(
canvas, 0, 35 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
ui_control_select_render(
canvas,
36,
28 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
&tmp_str[0],
scene_state->selected_control == MinutesInput);
two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]);
canvas_draw_str_aligned(
canvas, 0, 35 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
ui_control_select_render(
canvas,
36,
28 - scene_state->y_offset,
SCREEN_WIDTH - 36,
&tmp_str[0],
scene_state->selected_control == MinutesInput);
} else if(scene_state->selected_control < SoundSwitch) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
canvas_set_font(canvas, FontSecondary);
canvas_draw_icon(
canvas,
SCREEN_WIDTH_CENTER - 5,
SCREEN_HEIGHT - 5 - scene_state->y_offset,
&I_totp_arrow_bottom_10x5);
const FONT_INFO* const font = available_fonts[scene_state->active_font];
ui_control_select_render(
canvas,
0,
74 - scene_state->y_offset,
SCREEN_WIDTH - UI_CONTROL_VSCROLL_WIDTH,
font->name,
scene_state->selected_control == FontSelect);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
canvas_set_font(canvas, FontSecondary);
uint8_t font_x_offset =
SCREEN_WIDTH_CENTER -
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
canvas_draw_str_ex(
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
const FONT_INFO* const font = available_fonts[scene_state->active_font];
ui_control_select_render(
canvas,
0,
74 - scene_state->y_offset,
SCREEN_WIDTH,
font->name,
scene_state->selected_control == FontSelect);
} else if(scene_state->selected_control < AutomationSwitch) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
canvas_set_font(canvas, FontSecondary);
uint8_t font_x_offset =
SCREEN_WIDTH_CENTER -
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
canvas_draw_str_ex(
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
canvas_draw_str_aligned(
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
ui_control_select_render(
canvas,
36,
138 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
YES_NO_LIST[scene_state->notification_sound],
scene_state->selected_control == SoundSwitch);
canvas_draw_icon(
canvas, SCREEN_WIDTH_CENTER - 5, 123 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
canvas_draw_str_aligned(
canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
ui_control_select_render(
canvas,
36,
156 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
YES_NO_LIST[scene_state->notification_vibro],
scene_state->selected_control == VibroSwitch);
} else {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
canvas_set_font(canvas, FontSecondary);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "Method:");
ui_control_select_render(
canvas,
36,
202 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
AUTOMATION_LIST[scene_state->automation_method],
scene_state->selected_control == AutomationSwitch);
canvas_draw_str_aligned(canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
ui_control_select_render(
canvas,
36,
138 - scene_state->y_offset,
SCREEN_WIDTH - 36,
YES_NO_LIST[scene_state->notification_sound],
scene_state->selected_control == SoundSwitch);
canvas_draw_str_aligned(
canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "Layout:");
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
ui_control_select_render(
canvas,
36,
156 - scene_state->y_offset,
SCREEN_WIDTH - 36,
YES_NO_LIST[scene_state->notification_vibro],
scene_state->selected_control == VibroSwitch);
ui_control_select_render(
canvas,
36,
220 - scene_state->y_offset,
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
BAD_KB_LAYOUT_LIST[scene_state->automation_kb_layout],
scene_state->selected_control == BadKeyboardLayoutSelect);
canvas_draw_icon(
canvas, SCREEN_WIDTH_CENTER - 5, 187 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
ui_control_button_render(
canvas,
SCREEN_WIDTH_CENTER - 24,
242 - scene_state->y_offset,
48,
13,
"Confirm",
scene_state->selected_control == ConfirmButton);
}
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
ui_control_select_render(
canvas,
36,
202 - scene_state->y_offset,
SCREEN_WIDTH - 36,
ON_OFF_LIST[scene_state->badusb_enabled],
scene_state->selected_control == BadUsbSwitch);
#ifdef TOTP_BADBT_TYPE_ENABLED
canvas_draw_str_aligned(canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
ui_control_select_render(
canvas,
36,
220 - scene_state->y_offset,
SCREEN_WIDTH - 36,
ON_OFF_LIST[scene_state->badbt_enabled],
scene_state->selected_control == BadBtSwitch);
#endif
ui_control_button_render(
canvas,
SCREEN_WIDTH_CENTER - 24,
#ifdef TOTP_BADBT_TYPE_ENABLED
242 - scene_state->y_offset,
#else
229 - scene_state->y_offset,
#endif
48,
13,
"Confirm",
scene_state->selected_control == ConfirmButton);
ui_control_vscroll_render(
canvas, SCREEN_WIDTH - 3, 0, SCREEN_HEIGHT, scene_state->selected_control, ConfirmButton);
}
bool totp_scene_app_settings_handle_event(
@@ -268,14 +275,21 @@ bool totp_scene_app_settings_handle_event(
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == VibroSwitch) {
scene_state->notification_vibro = !scene_state->notification_vibro;
} else if(scene_state->selected_control == BadUsbSwitch) {
scene_state->badusb_enabled = !scene_state->badusb_enabled;
} else if(scene_state->selected_control == AutomationSwitch) {
totp_roll_value_uint8_t(
&scene_state->automation_method,
1,
0,
AUTOMATION_LIST_MAX_INDEX,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
totp_roll_value_uint8_t(
&scene_state->automation_kb_layout,
1,
0,
BAD_KB_LAYOUT_LIST_MAX_INDEX,
RollOverflowBehaviorRoll);
}
#ifdef TOTP_BADBT_TYPE_ENABLED
else if(scene_state->selected_control == BadBtSwitch) {
scene_state->badbt_enabled = !scene_state->badbt_enabled;
}
#endif
break;
case InputKeyLeft:
if(scene_state->selected_control == HoursInput) {
@@ -295,14 +309,21 @@ bool totp_scene_app_settings_handle_event(
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == VibroSwitch) {
scene_state->notification_vibro = !scene_state->notification_vibro;
} else if(scene_state->selected_control == BadUsbSwitch) {
scene_state->badusb_enabled = !scene_state->badusb_enabled;
} else if(scene_state->selected_control == AutomationSwitch) {
totp_roll_value_uint8_t(
&scene_state->automation_method,
-1,
0,
AUTOMATION_LIST_MAX_INDEX,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
totp_roll_value_uint8_t(
&scene_state->automation_kb_layout,
-1,
0,
BAD_KB_LAYOUT_LIST_MAX_INDEX,
RollOverflowBehaviorRoll);
}
#ifdef TOTP_BADBT_TYPE_ENABLED
else if(scene_state->selected_control == BadBtSwitch) {
scene_state->badbt_enabled = !scene_state->badbt_enabled;
}
#endif
break;
case InputKeyOk:
break;
@@ -323,22 +344,18 @@ bool totp_scene_app_settings_handle_event(
(scene_state->notification_sound ? NotificationMethodSound : NotificationMethodNone) |
(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
plugin_state->automation_method = scene_state->automation_method;
plugin_state->active_font_index = scene_state->active_font;
plugin_state->automation_kb_layout = scene_state->automation_kb_layout;
if(!totp_config_file_update_user_settings(plugin_state)) {
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) {
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
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;
}

View File

@@ -7,10 +7,10 @@
#include "../../../services/config/config.h"
#include "../../scene_director.h"
#include "../../totp_scenes_enum.h"
#include "../../../services/crypto/crypto.h"
#include "../../../services/crypto/crypto_facade.h"
#include "../../../types/user_pin_codes.h"
#define MAX_CODE_LENGTH TOTP_IV_SIZE
#define MAX_CODE_LENGTH CRYPTO_IV_LENGTH
static const uint8_t PIN_ASTERISK_RADIUS = 3;
static const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2;
@@ -25,7 +25,7 @@ void totp_scene_authenticate_activate(PluginState* plugin_state) {
scene_state->code_length = 0;
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
plugin_state->current_scene_state = scene_state;
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
}
void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) {
@@ -36,7 +36,7 @@ void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_st
v_shift = -10;
}
if(plugin_state->crypto_verify_data == NULL) {
if(plugin_state->crypto_settings.crypto_verify_data == NULL) {
canvas_draw_str_aligned(
canvas,
SCREEN_WIDTH_CENTER,
@@ -124,20 +124,22 @@ bool totp_scene_authenticate_handle_event(
}
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
CryptoSeedIVResult seed_result = totp_crypto_seed_iv(
plugin_state, &scene_state->code_input[0], scene_state->code_length);
&plugin_state->crypto_settings, &scene_state->code_input[0], scene_state->code_length);
if(seed_result & CryptoSeedIVResultFlagSuccess &&
seed_result & CryptoSeedIVResultFlagNewCryptoVerifyData) {
totp_config_file_update_crypto_signatures(plugin_state);
}
if(totp_crypto_verify_key(plugin_state)) {
if(totp_crypto_verify_key(&plugin_state->crypto_settings)) {
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
totp_config_file_ensure_latest_encryption(
plugin_state, &scene_state->code_input[0], scene_state->code_length);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
} else {
FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid");
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
scene_state->code_length = 0;
DialogMessage* message = dialog_message_alloc();

View File

@@ -16,7 +16,7 @@
#include "../../../features_config.h"
#include "../../../workers/generate_totp_code/generate_totp_code.h"
#include "../../../workers/usb_type_code/usb_type_code.h"
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
@@ -34,50 +34,40 @@ typedef struct {
typedef struct {
char last_code[TokenDigitsCountMax + 1];
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
NotificationMessage const** notification_sequence_new_token;
NotificationMessage const** notification_sequence_automation;
NotificationMessage const* notification_sequence_new_token[8];
NotificationMessage const* notification_sequence_automation[11];
FuriMutex* last_code_update_sync;
TotpGenerateCodeWorkerContext* generate_code_worker_context;
UiPrecalculatedDimensions ui_precalculated_dimensions;
const FONT_INFO* active_font;
NotificationApp* notification_app;
} SceneState;
static const NotificationSequence*
get_notification_sequence_new_token(const PluginState* plugin_state, SceneState* scene_state) {
if(scene_state->notification_sequence_new_token == NULL) {
uint8_t i = 0;
uint8_t length = 4;
if(scene_state->notification_sequence_new_token[0] == NULL) {
NotificationMessage const** sequence = &scene_state->notification_sequence_new_token[0];
*(sequence++) = &message_display_backlight_on;
*(sequence++) = &message_green_255;
if(plugin_state->notification_method & NotificationMethodVibro) {
length += 2;
*(sequence++) = &message_vibro_on;
}
if(plugin_state->notification_method & NotificationMethodSound) {
length += 2;
*(sequence++) = &message_note_c5;
}
scene_state->notification_sequence_new_token = malloc(sizeof(void*) * length);
furi_check(scene_state->notification_sequence_new_token != NULL);
scene_state->notification_sequence_new_token[i++] = &message_display_backlight_on;
scene_state->notification_sequence_new_token[i++] = &message_green_255;
*(sequence++) = &message_delay_50;
if(plugin_state->notification_method & NotificationMethodVibro) {
scene_state->notification_sequence_new_token[i++] = &message_vibro_on;
*(sequence++) = &message_vibro_off;
}
if(plugin_state->notification_method & NotificationMethodSound) {
scene_state->notification_sequence_new_token[i++] = &message_note_c5;
*(sequence++) = &message_sound_off;
}
scene_state->notification_sequence_new_token[i++] = &message_delay_50;
if(plugin_state->notification_method & NotificationMethodVibro) {
scene_state->notification_sequence_new_token[i++] = &message_vibro_off;
}
if(plugin_state->notification_method & NotificationMethodSound) {
scene_state->notification_sequence_new_token[i++] = &message_sound_off;
}
scene_state->notification_sequence_new_token[i++] = NULL;
*(sequence++) = NULL;
}
return (NotificationSequence*)scene_state->notification_sequence_new_token;
@@ -85,44 +75,33 @@ static const NotificationSequence*
static const NotificationSequence*
get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) {
if(scene_state->notification_sequence_automation == NULL) {
uint8_t i = 0;
uint8_t length = 3;
if(scene_state->notification_sequence_automation[0] == NULL) {
NotificationMessage const** sequence = &scene_state->notification_sequence_automation[0];
*(sequence++) = &message_blue_255;
if(plugin_state->notification_method & NotificationMethodVibro) {
length += 2;
*(sequence++) = &message_vibro_on;
}
if(plugin_state->notification_method & NotificationMethodSound) {
length += 6;
*(sequence++) = &message_note_d5; //-V525
*(sequence++) = &message_delay_50;
*(sequence++) = &message_note_e4;
*(sequence++) = &message_delay_50;
*(sequence++) = &message_note_f3;
}
scene_state->notification_sequence_automation = malloc(sizeof(void*) * length);
furi_check(scene_state->notification_sequence_automation != NULL);
*(sequence++) = &message_delay_50;
scene_state->notification_sequence_automation[i++] = &message_blue_255;
if(plugin_state->notification_method & NotificationMethodVibro) {
scene_state->notification_sequence_automation[i++] = &message_vibro_on;
*(sequence++) = &message_vibro_off;
}
if(plugin_state->notification_method & NotificationMethodSound) {
scene_state->notification_sequence_automation[i++] = &message_note_d5; //-V525
scene_state->notification_sequence_automation[i++] = &message_delay_50;
scene_state->notification_sequence_automation[i++] = &message_note_e4;
scene_state->notification_sequence_automation[i++] = &message_delay_50;
scene_state->notification_sequence_automation[i++] = &message_note_f3;
*(sequence++) = &message_sound_off;
}
scene_state->notification_sequence_automation[i++] = &message_delay_50;
if(plugin_state->notification_method & NotificationMethodVibro) {
scene_state->notification_sequence_automation[i++] = &message_vibro_off;
}
if(plugin_state->notification_method & NotificationMethodSound) {
scene_state->notification_sequence_automation[i++] = &message_sound_off;
}
scene_state->notification_sequence_automation[i++] = NULL;
*(sequence++) = NULL;
}
return (NotificationSequence*)scene_state->notification_sequence_automation;
@@ -154,7 +133,7 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
}
static void on_new_token_code_generated(bool time_left, void* context) {
const PluginState* plugin_state = context;
PluginState* const plugin_state = context;
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(totp_token_info_iterator_get_total_count(iterator_context) == 0) {
@@ -175,13 +154,16 @@ static void on_new_token_code_generated(bool time_left, void* context) {
if(time_left) {
notification_message(
plugin_state->notification_app,
get_notification_sequence_new_token(plugin_state, plugin_state->current_scene_state));
scene_state->notification_app,
get_notification_sequence_new_token(plugin_state, scene_state));
}
totp_scene_director_force_redraw(plugin_state);
}
static void on_code_lifetime_updated_generated(float code_lifetime_percent, void* context) {
SceneState* scene_state = context;
PluginState* const plugin_state = context;
SceneState* scene_state = plugin_state->current_scene_state;
scene_state->ui_precalculated_dimensions.progress_bar_width =
(uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * code_lifetime_percent);
scene_state->ui_precalculated_dimensions.progress_bar_x =
@@ -189,6 +171,7 @@ static void on_code_lifetime_updated_generated(float code_lifetime_percent, void
scene_state->ui_precalculated_dimensions.progress_bar_width) >>
1) +
PROGRESS_BAR_MARGIN;
totp_scene_director_force_redraw(plugin_state);
}
void totp_scene_generate_token_activate(PluginState* plugin_state) {
@@ -201,12 +184,18 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
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, TokenDigitsCountMax + 1, scene_state->last_code_update_sync);
scene_state->last_code,
TokenDigitsCountMax + 1,
scene_state->last_code_update_sync,
plugin_state->automation_kb_layout);
}
scene_state->active_font = available_fonts[plugin_state->active_font_index];
scene_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
scene_state->notification_sequence_automation[0] = NULL;
scene_state->notification_sequence_new_token[0] = NULL;
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
if(plugin_state->automation_method & AutomationMethodBadBt) {
if(plugin_state->bt_type_code_worker_context == NULL) {
@@ -216,7 +205,8 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
plugin_state->bt_type_code_worker_context,
scene_state->last_code,
TokenDigitsCountMax + 1,
scene_state->last_code_update_sync);
scene_state->last_code_update_sync,
plugin_state->automation_kb_layout);
}
#endif
const TokenInfoIteratorContext* iterator_context =
@@ -226,7 +216,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
totp_token_info_iterator_get_current_token(iterator_context),
scene_state->last_code_update_sync,
plugin_state->timezone_offset,
plugin_state->iv);
&plugin_state->crypto_settings);
totp_generate_code_worker_set_code_generated_handler(
scene_state->generate_code_worker_context, &on_new_token_code_generated, plugin_state);
@@ -234,7 +224,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
totp_generate_code_worker_set_lifetime_changed_handler(
scene_state->generate_code_worker_context,
&on_code_lifetime_updated_generated,
scene_state);
plugin_state);
update_totp_params(
plugin_state, totp_token_info_iterator_get_current_token_index(iterator_context));
@@ -298,11 +288,10 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
canvas, SCREEN_WIDTH - 8, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9);
}
#ifdef TOTP_AUTOMATION_ICONS_ENABLED
if(plugin_state->automation_method & AutomationMethodBadUsb) {
canvas_draw_icon(
canvas,
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
SCREEN_WIDTH_CENTER -
(plugin_state->automation_method & AutomationMethodBadBt ? 33 : 15),
#else
@@ -313,7 +302,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
&I_hid_usb_31x9);
}
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
if(plugin_state->automation_method & AutomationMethodBadBt &&
plugin_state->bt_type_code_worker_context != NULL &&
totp_bt_type_code_worker_is_advertising(plugin_state->bt_type_code_worker_context)) {
@@ -325,7 +314,6 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
&I_hid_ble_31x9);
}
#endif
#endif
}
bool totp_scene_generate_token_handle_event(
@@ -351,11 +339,11 @@ bool totp_scene_generate_token_handle_event(
TotpUsbTypeCodeWorkerEventType,
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
notification_message(
plugin_state->notification_app,
scene_state->notification_app,
get_notification_sequence_automation(plugin_state, scene_state));
return true;
}
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
else if(
event->input.key == InputKeyUp &&
plugin_state->automation_method & AutomationMethodBadBt) {
@@ -367,7 +355,7 @@ bool totp_scene_generate_token_handle_event(
TotpBtTypeCodeWorkerEventType,
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
notification_message(
plugin_state->notification_app,
scene_state->notification_app,
get_notification_sequence_automation(plugin_state, scene_state));
return true;
}
@@ -428,23 +416,17 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
totp_generate_code_worker_stop(scene_state->generate_code_worker_context);
furi_record_close(RECORD_NOTIFICATION);
if(plugin_state->automation_method & AutomationMethodBadUsb) {
totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context);
}
#ifdef TOTP_BADBT_TYPE_ENABLED
#ifdef TOTP_BADBT_AUTOMATION_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);
}
if(scene_state->notification_sequence_automation != NULL) {
free(scene_state->notification_sequence_automation);
}
furi_mutex_free(scene_state->last_code_update_sync);
free(scene_state);

View File

@@ -113,3 +113,27 @@ void ui_control_button_render(
canvas_set_color(canvas, ColorBlack);
}
}
void ui_control_vscroll_render(
Canvas* const canvas,
uint8_t x,
uint8_t y,
uint8_t height,
uint8_t position,
uint8_t max_position) {
canvas_draw_line(canvas, x, y, x, y + height);
uint8_t block_height = height / MIN(10, max_position);
uint8_t block_position_y =
height * ((float)position / (float)max_position) - (block_height >> 1);
uint8_t block_position_y_abs = y + block_position_y;
if(block_position_y_abs + block_height > height) {
block_position_y_abs = height - block_height;
}
canvas_draw_box(
canvas,
x - (UI_CONTROL_VSCROLL_WIDTH >> 1),
block_position_y_abs,
UI_CONTROL_VSCROLL_WIDTH,
block_height);
}

View File

@@ -3,6 +3,8 @@
#include <inttypes.h>
#include <gui/gui.h>
#define UI_CONTROL_VSCROLL_WIDTH (3)
/**
* @brief Renders TextBox control
* @param canvas canvas to render control at
@@ -51,3 +53,20 @@ void ui_control_select_render(
uint8_t width,
const char* text,
bool is_selected);
/**
* @brief Renders vertical scroll bar
* @param canvas canvas to render control at
* @param x horizontal position of a control to be rendered at
* @param y vertical position of a control to be rendered at
* @param height control height
* @param position current position
* @param max_position maximal position
*/
void ui_control_vscroll_render(
Canvas* const canvas,
uint8_t x,
uint8_t y,
uint8_t height,
uint8_t position,
uint8_t max_position);