mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Merge branch 'dev' into release
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,14 +1,10 @@
|
||||
## New changes
|
||||
* SubGHz: OFW PR: change the operation of the TIM17 timer in CC1101_ext to 2µs -> **CAME Atomo and other protocols issues with external module should be fixed now**
|
||||
* SubGHz: Temporatily revert new AM_Q in default modulations due to external CC1101 module issues
|
||||
* Plugins: NRF24 MouseJacker -> Fixed issue #551 - Wrong folder path
|
||||
* Plugins: Spectrum Analyzer -> Add a Precise mode and other small changes (by @ALEEF02 | PR #550 #553)
|
||||
* Plugins: Updated Lightmeter [(by oleksiikutuzov)](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
|
||||
* Plugins: Various uFBT fixes (by @hedger)
|
||||
* Infrared: Universal remote assets - Add Xiaomi TV and (Daikin AC from OFW PR 2913 by minchogaydarov)
|
||||
* OFW PR 2912: NFC: Fix key invalidation (again) (by AloneLiberty)
|
||||
* OFW PR 2907: Fix about screen (by andzhr)
|
||||
* OFW PR 2896: BadUSB - Added French Canadian layout (by francis2054)
|
||||
* Plugins: **22+ plugins was fixed (UI update issues) in extra pack and in base firmware pack**
|
||||
* Plugins: Spectrum Analyzer - Modulation switching (hold OK) (by @ALEEF02 | PR #557)
|
||||
* Plugins: BadBT -> Temp fix for macOS
|
||||
* Plugins: Update TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) -> + added fix for UI update too
|
||||
* Infrared: Add Play / Pause in universal projector remote
|
||||
* Infrared: Update Universal remote assets (by @amec0e)
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ const uint8_t BAD_BT_EMPTY_MAC_ADDRESS[BAD_BT_MAC_ADDRESS_LEN] =
|
||||
* Delays for waiting between HID key press and key release
|
||||
*/
|
||||
const uint8_t bt_hid_delays[LevelRssiNum] = {
|
||||
30, // LevelRssi122_100
|
||||
25, // LevelRssi99_80
|
||||
20, // LevelRssi79_60
|
||||
17, // LevelRssi59_40
|
||||
14, // LevelRssi39_0
|
||||
60, // LevelRssi122_100
|
||||
55, // LevelRssi99_80
|
||||
50, // LevelRssi79_60
|
||||
47, // LevelRssi59_40
|
||||
34, // LevelRssi39_0
|
||||
};
|
||||
|
||||
uint8_t bt_timeout = 0;
|
||||
|
||||
@@ -73,7 +73,8 @@ int32_t i2ctools_app(void* p) {
|
||||
// Share scanner with sender
|
||||
i2ctools->sender->scanner = i2ctools->scanner;
|
||||
|
||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
while(1) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
// Back
|
||||
if(event.key == InputKeyBack && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
@@ -213,6 +214,7 @@ int32_t i2ctools_app(void* p) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
view_port_update(i2ctools->view_port);
|
||||
}
|
||||
gui_remove_view_port(gui, i2ctools->view_port);
|
||||
|
||||
17
applications/external/hex_viewer/hex_viewer.c
vendored
17
applications/external/hex_viewer/hex_viewer.c
vendored
@@ -229,19 +229,21 @@ int32_t hex_viewer_app(void* p) {
|
||||
hex_viewer_read_file(hex_viewer);
|
||||
|
||||
InputEvent input;
|
||||
while(furi_message_queue_get(hex_viewer->input_queue, &input, FuriWaitForever) ==
|
||||
FuriStatusOk) {
|
||||
while(1) {
|
||||
if(furi_message_queue_get(hex_viewer->input_queue, &input, 100) == FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(hex_viewer->model->file_offset > 0) {
|
||||
hex_viewer->model->file_offset -= HEX_VIEWER_BYTES_PER_LINE;
|
||||
if(!hex_viewer_read_file(hex_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyDown) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
uint32_t last_byte_on_screen =
|
||||
hex_viewer->model->file_offset + hex_viewer->model->file_read_bytes;
|
||||
|
||||
@@ -251,7 +253,8 @@ int32_t hex_viewer_app(void* p) {
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyLeft) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
hex_viewer->model->mode = !hex_viewer->model->mode;
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyRight) {
|
||||
@@ -266,7 +269,8 @@ int32_t hex_viewer_app(void* p) {
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(message, "Hex Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_header(
|
||||
message, "Hex Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_hex_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
@@ -277,6 +281,7 @@ int32_t hex_viewer_app(void* p) {
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
}
|
||||
|
||||
view_port_update(hex_viewer->view_port);
|
||||
}
|
||||
|
||||
7
applications/external/ir_scope/ir_scope.c
vendored
7
applications/external/ir_scope/ir_scope.c
vendored
@@ -140,8 +140,8 @@ int32_t ir_scope_app(void* p) {
|
||||
|
||||
InputEvent event;
|
||||
bool processing = true;
|
||||
while(processing &&
|
||||
furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
while(processing) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
if(event.type == InputTypeRelease) {
|
||||
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||
|
||||
@@ -161,10 +161,11 @@ int32_t ir_scope_app(void* p) {
|
||||
state.us_per_sample = 200;
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
furi_mutex_release(state.mutex);
|
||||
}
|
||||
}
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
infrared_worker_rx_stop(worker);
|
||||
|
||||
7
applications/external/solitaire/solitaire.c
vendored
7
applications/external/solitaire/solitaire.c
vendored
@@ -497,7 +497,6 @@ int32_t solitaire_app(void* p) {
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
bool hadChange = false;
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypeLong) {
|
||||
@@ -528,7 +527,6 @@ int32_t solitaire_app(void* p) {
|
||||
game_state->state = GameStatePlay;
|
||||
init(game_state);
|
||||
} else {
|
||||
hadChange = true;
|
||||
game_state->input = event.input.key;
|
||||
}
|
||||
break;
|
||||
@@ -546,11 +544,8 @@ int32_t solitaire_app(void* p) {
|
||||
processing = game_state->processing;
|
||||
game_state->input = InputKeyMAX;
|
||||
}
|
||||
} else {
|
||||
//FURI_LOG_W(APP_NAME, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
if(hadChange || game_state->state == GameStateAnimate) view_port_update(view_port);
|
||||
view_port_update(view_port);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
typedef struct {
|
||||
uint32_t center_freq;
|
||||
uint8_t width;
|
||||
uint8_t modulation;
|
||||
uint8_t band;
|
||||
uint8_t vscroll;
|
||||
|
||||
@@ -19,6 +20,7 @@ typedef struct {
|
||||
uint32_t spacing;
|
||||
|
||||
bool mode_change;
|
||||
bool modulation_change;
|
||||
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
@@ -147,6 +149,24 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
|
||||
snprintf(tmp_str, 21, "Mode: %s", temp_mode_str);
|
||||
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
|
||||
}
|
||||
|
||||
if(model->modulation_change) {
|
||||
char temp_mod_str[12];
|
||||
switch(model->modulation) {
|
||||
case NARROW_MODULATION:
|
||||
strncpy(temp_mod_str, "NARROW", 12);
|
||||
break;
|
||||
default:
|
||||
strncpy(temp_mod_str, "DEFAULT", 12);
|
||||
break;
|
||||
}
|
||||
|
||||
// Current modulation label
|
||||
char tmp_str[27];
|
||||
snprintf(tmp_str, 27, "Modulation: %s", temp_mod_str);
|
||||
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
|
||||
}
|
||||
|
||||
// Draw cross and label
|
||||
if(model->max_rssi > PEAK_THRESHOLD) {
|
||||
// Compress height to max of 64 values (255>>2)
|
||||
@@ -194,8 +214,8 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
|
||||
|
||||
static void spectrum_analyzer_input_callback(InputEvent* input_event, void* ctx) {
|
||||
SpectrumAnalyzer* spectrum_analyzer = ctx;
|
||||
// Only handle short presses
|
||||
if(input_event->type == InputTypeShort) {
|
||||
// Handle short and long presses
|
||||
if(input_event->type == InputTypeShort || input_event->type == InputTypeLong) {
|
||||
furi_message_queue_put(spectrum_analyzer->event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
}
|
||||
@@ -376,6 +396,7 @@ SpectrumAnalyzer* spectrum_analyzer_alloc() {
|
||||
|
||||
model->center_freq = DEFAULT_FREQ;
|
||||
model->width = WIDE;
|
||||
model->modulation = DEFAULT_MODULATION;
|
||||
model->band = BAND_400;
|
||||
|
||||
model->vscroll = DEFAULT_VSCROLL;
|
||||
@@ -470,6 +491,8 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input.type) {
|
||||
case InputTypeShort:
|
||||
switch(input.key) {
|
||||
case InputKeyUp:
|
||||
model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL);
|
||||
@@ -484,13 +507,19 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
model->center_freq -= hstep;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
break;
|
||||
case InputKeyOk: {
|
||||
@@ -515,7 +544,6 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
model->mode_change = true;
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
@@ -524,7 +552,10 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
model->mode_change = false;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
FURI_LOG_D("Spectrum", "Width: %u", model->width);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
@@ -533,6 +564,37 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case InputTypeLong:
|
||||
switch(input.key) {
|
||||
case InputKeyOk:
|
||||
FURI_LOG_D("Spectrum", "InputTypeLong");
|
||||
switch(model->modulation) {
|
||||
case NARROW_MODULATION:
|
||||
model->modulation = DEFAULT_MODULATION;
|
||||
break;
|
||||
case DEFAULT_MODULATION:
|
||||
default:
|
||||
model->modulation = NARROW_MODULATION;
|
||||
break;
|
||||
}
|
||||
|
||||
model->modulation_change = true;
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
furi_delay_ms(1000);
|
||||
|
||||
model->modulation_change = false;
|
||||
spectrum_analyzer_worker_set_modulation(
|
||||
spectrum_analyzer->worker, spectrum_analyzer->model->modulation);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
furi_mutex_release(spectrum_analyzer->model_mutex);
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
@@ -78,3 +78,7 @@
|
||||
|
||||
#define UPPER(a, b, c) ((((a) - (b) + ((c) / 2)) / (c)) * (c))
|
||||
#define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c))
|
||||
|
||||
/* Modulation references */
|
||||
#define DEFAULT_MODULATION 0
|
||||
#define NARROW_MODULATION 1
|
||||
@@ -20,6 +20,7 @@ struct SpectrumAnalyzerWorker {
|
||||
uint32_t channel0_frequency;
|
||||
uint32_t spacing;
|
||||
uint8_t width;
|
||||
uint8_t modulation;
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
uint8_t max_rssi_channel;
|
||||
@@ -66,18 +67,45 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
subghz_devices_flush_rx(instance->radio_device);
|
||||
subghz_devices_set_rx(instance->radio_device);
|
||||
|
||||
const uint8_t radio_config[] = {
|
||||
// Default modulation
|
||||
const uint8_t default_modulation[] = {
|
||||
|
||||
/* Frequency Synthesizer Control */
|
||||
CC1101_FSCTRL0,
|
||||
0x00,
|
||||
CC1101_FSCTRL1,
|
||||
0x12,
|
||||
|
||||
CC1101_AGCCTRL2,
|
||||
0xC0,
|
||||
0x12, // IF = (26*10^6) / (2^10) * 0x12 = 304687.5 Hz
|
||||
|
||||
// Modem Configuration
|
||||
// CC1101_MDMCFG0,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG1,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG2,
|
||||
// 0x30, // Format ASK/OOK, No preamble/sync
|
||||
// CC1101_MDMCFG3,
|
||||
// 0x32, // Data rate is 121.399 kBaud
|
||||
CC1101_MDMCFG4,
|
||||
0x6C,
|
||||
0x6C, // Rx BW filter is 270.83 kHz
|
||||
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
// CC1101_FOCCFG,
|
||||
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
|
||||
/* Automatic Gain Control */
|
||||
// CC1101_AGCCTRL0,
|
||||
// 0x91, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
|
||||
// CC1101_AGCCTRL1,
|
||||
// 0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
CC1101_AGCCTRL2,
|
||||
0xC0, // 03 - The 3 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 000 - MAIN_TARGET 24 dB
|
||||
|
||||
/* Frontend configuration */
|
||||
// CC1101_FREND0,
|
||||
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
|
||||
// CC1101_FREND1,
|
||||
// 0xB6, //
|
||||
|
||||
CC1101_TEST2,
|
||||
0x88,
|
||||
CC1101_TEST1,
|
||||
@@ -97,8 +125,69 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00};
|
||||
|
||||
// Narrow modulation
|
||||
const uint8_t narrow_modulation[] = {
|
||||
|
||||
/* Frequency Synthesizer Control */
|
||||
CC1101_FSCTRL0,
|
||||
0x00,
|
||||
};
|
||||
CC1101_FSCTRL1,
|
||||
0x00, // IF = (26*10^6) / (2^10) * 0x00 = 0 Hz
|
||||
|
||||
// Modem Configuration
|
||||
// CC1101_MDMCFG0,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG1,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG2,
|
||||
// 0x30, // Format ASK/OOK, No preamble/sync
|
||||
// CC1101_MDMCFG3,
|
||||
// 0x32, // Data rate is 121.399 kBaud
|
||||
CC1101_MDMCFG4,
|
||||
0xFC, // Rx BW filter is 58.04 kHz
|
||||
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
// CC1101_FOCCFG,
|
||||
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
|
||||
/* Automatic Gain Control */
|
||||
CC1101_AGCCTRL0,
|
||||
0x30, // 00 - NO hysteresis, symmetric dead zone, high gain ; 11 - 32 samples agc; 00 - Normal AGC, 00 - 8dB boundary
|
||||
CC1101_AGCCTRL1,
|
||||
0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
CC1101_AGCCTRL2,
|
||||
0x84, // 02 - The 2 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 100 - MAIN_TARGET 36 dB
|
||||
|
||||
/* Frontend configuration */
|
||||
// CC1101_FREND0,
|
||||
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
|
||||
// CC1101_FREND1,
|
||||
// 0xB6, //
|
||||
|
||||
CC1101_TEST2,
|
||||
0x88,
|
||||
CC1101_TEST1,
|
||||
0x31,
|
||||
CC1101_TEST0,
|
||||
0x09,
|
||||
|
||||
/* End */
|
||||
0,
|
||||
0,
|
||||
|
||||
// ook_async_patable
|
||||
0x00,
|
||||
0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00};
|
||||
|
||||
const uint8_t* modulations[] = {default_modulation, narrow_modulation};
|
||||
|
||||
while(instance->should_work) {
|
||||
furi_delay_ms(50);
|
||||
@@ -106,7 +195,12 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
// FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop");
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_devices_load_preset(
|
||||
instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)radio_config);
|
||||
instance->radio_device,
|
||||
FuriHalSubGhzPresetCustom,
|
||||
(uint8_t*)modulations[instance->modulation]);
|
||||
//subghz_devices_load_preset(
|
||||
// instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)default_modulation);
|
||||
//furi_hal_subghz_load_custom_preset(modulations[instance->modulation]);
|
||||
|
||||
// TODO: Check filter!
|
||||
// spectrum_analyzer_worker_set_filter(instance);
|
||||
@@ -222,6 +316,15 @@ void spectrum_analyzer_worker_set_frequencies(
|
||||
instance->width = width;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_set_modulation(SpectrumAnalyzerWorker* instance, uint8_t modulation) {
|
||||
furi_assert(instance);
|
||||
|
||||
FURI_LOG_D(
|
||||
"SpectrumWorker", "spectrum_analyzer_worker_set_modulation - modulation = %u", modulation);
|
||||
|
||||
instance->modulation = modulation;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance) {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_start");
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ void spectrum_analyzer_worker_set_frequencies(
|
||||
uint32_t spacing,
|
||||
uint8_t width);
|
||||
|
||||
void spectrum_analyzer_worker_set_modulation(SpectrumAnalyzerWorker* instance, uint8_t modulation);
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
@@ -223,8 +223,8 @@ int32_t text_viewer_app(void* p) {
|
||||
text_viewer_read_file(text_viewer);
|
||||
|
||||
InputEvent input;
|
||||
while(furi_message_queue_get(text_viewer->input_queue, &input, FuriWaitForever) ==
|
||||
FuriStatusOk) {
|
||||
while(1) {
|
||||
if(furi_message_queue_get(text_viewer->input_queue, &input, 100) == FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
@@ -263,7 +263,8 @@ int32_t text_viewer_app(void* p) {
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(message, "Text Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_header(
|
||||
message, "Text Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_text_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
@@ -274,6 +275,7 @@ int32_t text_viewer_app(void* p) {
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
}
|
||||
view_port_update(text_viewer->view_port);
|
||||
}
|
||||
} while(false);
|
||||
|
||||
15
applications/external/totp/application.fam
vendored
15
applications/external/totp/application.fam
vendored
@@ -3,9 +3,19 @@ App(
|
||||
name="Authenticator",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="totp_app",
|
||||
requires=["gui", "cli", "dialogs", "storage", "input", "notification", "bt"],
|
||||
cdefines=["APP_TOTP"],
|
||||
requires=[
|
||||
"gui",
|
||||
"cli",
|
||||
"dialogs",
|
||||
"storage",
|
||||
"input",
|
||||
"notification",
|
||||
"bt"
|
||||
],
|
||||
stack_size=2 * 1024,
|
||||
order=20,
|
||||
fap_version="2.3",
|
||||
fap_author="Alexander Kopachov (@akopachov)",
|
||||
fap_description="Software-based TOTP authenticator for Flipper Zero device",
|
||||
fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
|
||||
@@ -28,5 +38,8 @@ App(
|
||||
Lib(
|
||||
name="roll_value",
|
||||
),
|
||||
Lib(
|
||||
name="fonts",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
5
applications/external/totp/cli/cli_helpers.h
vendored
5
applications/external/totp/cli/cli_helpers.h
vendored
@@ -22,10 +22,7 @@ extern const char* TOTP_CLI_COLOR_INFO;
|
||||
#define TOTP_CLI_PRINTF(format, ...) printf(format, ##__VA_ARGS__)
|
||||
|
||||
#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
|
||||
printf("\e[%s", color); \
|
||||
printf(format, ##__VA_ARGS__); \
|
||||
printf("\e[0m"); \
|
||||
fflush(stdout)
|
||||
TOTP_CLI_PRINTF("\e[%s" format "\e[0m", color, ##__VA_ARGS__)
|
||||
|
||||
#define TOTP_CLI_PRINTF_ERROR(format, ...) \
|
||||
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_ERROR, format, ##__VA_ARGS__)
|
||||
|
||||
@@ -102,15 +102,22 @@ void totp_cli_command_add_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_ALGO_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_ALGO)) " Token hashing algorithm. Must be one of: " TOTP_TOKEN_ALGO_SHA1_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA256_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA512_NAME
|
||||
", " TOTP_TOKEN_ALGO_STEAM_NAME
|
||||
" " DOCOPT_DEFAULT(TOTP_TOKEN_ALGO_SHA1_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_ALGO)) " Token hashing algorithm. Must be one of: " TOKEN_HASH_ALGO_SHA1_NAME
|
||||
", " TOKEN_HASH_ALGO_SHA256_NAME
|
||||
", " TOKEN_HASH_ALGO_SHA512_NAME
|
||||
", " TOKEN_HASH_ALGO_STEAM_NAME
|
||||
" " DOCOPT_DEFAULT(TOKEN_HASH_ALGO_SHA1_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(
|
||||
" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: 5, 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: %" PRIu8
|
||||
", %" PRIu8 ", %" PRIu8
|
||||
" " DOCOPT_DEFAULT("%" PRIu8) "\r\n",
|
||||
TokenDigitsCountFive,
|
||||
TokenDigitsCountSix,
|
||||
TokenDigitsCountEight,
|
||||
TokenDigitsCountSix);
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX,
|
||||
@@ -120,27 +127,32 @@ void totp_cli_command_add_docopt_options() {
|
||||
" " DOCOPT_DEFAULT(
|
||||
PLAIN_TOKEN_ENCODING_BASE32_NAME) "\r\n");
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_PRINTF(
|
||||
" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION)) " Token lifetime duration in seconds, between: 15 and 255 " DOCOPT_DEFAULT("30") "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_DURATION)) " Token lifetime duration in seconds, between: %" PRIu8
|
||||
" and %" PRIu8
|
||||
" " DOCOPT_DEFAULT("%" PRIu8) "\r\n",
|
||||
TokenDurationMin,
|
||||
TokenDurationMax,
|
||||
TokenDurationDefault);
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||
TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n");
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)) " Token automation features to be enabled. Must be one of: " TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
", " TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
", " TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)) " Token automation features to be enabled. Must be one of: " TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
", " TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
", " TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
" " DOCOPT_DEFAULT(
|
||||
TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
" - No features\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
TOKEN_AUTOMATION_FEATURE_NONE_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_NONE_NAME " - No features\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
" - Type <Enter> key at the end of token input automation\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
" - Type <Tab> key at the end of token input automation\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
|
||||
" - Type slower\r\n");
|
||||
}
|
||||
|
||||
|
||||
18
applications/external/totp/features_config.h
vendored
18
applications/external/totp/features_config.h
vendored
@@ -4,19 +4,21 @@
|
||||
#endif
|
||||
|
||||
// Include Bluetooth token input automation
|
||||
#ifndef TOTP_NO_BADBT_TYPE
|
||||
#define TOTP_BADBT_TYPE_ENABLED
|
||||
#endif
|
||||
|
||||
// Include token input automation icons on the main screen
|
||||
#ifndef TOTP_NO_AUTOMATION_ICONS
|
||||
#define TOTP_AUTOMATION_ICONS_ENABLED
|
||||
#endif
|
||||
|
||||
// List of compatible firmwares
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE 1
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV 2
|
||||
#define TOTP_FIRMWARE_UL_XFW 3 // XFW and UL now has same bluetooth mac/advname changing API
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE (1)
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV (2)
|
||||
#define TOTP_FIRMWARE_XTREME_UL (3)
|
||||
// End of list
|
||||
|
||||
// Target firmware to build for
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_UL_XFW
|
||||
|
||||
// Max custom fonts value
|
||||
#define MAX_CUSTOM_FONTS (9)
|
||||
#ifndef TOTP_TARGET_FIRMWARE
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_XTREME_UL
|
||||
#endif
|
||||
|
||||
@@ -931,6 +931,7 @@ const FONT_CHAR_INFO _712Serif_24ptDescriptors[] = {
|
||||
|
||||
/* Font information for 7:12 Serif 24pt */
|
||||
const FONT_INFO _712Serif_24ptFontInfo = {
|
||||
"712 Serif",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
23
applications/external/totp/lib/fonts/available_fonts.c
vendored
Normal file
23
applications/external/totp/lib/fonts/available_fonts.c
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "available_fonts.h"
|
||||
#include "712serif/712serif.h"
|
||||
#include "bedstead/bedstead.h"
|
||||
#include "dpcomic/dpcomic.h"
|
||||
#include "funclimbing/funclimbing.h"
|
||||
#include "graph35pix/graph35pix.h"
|
||||
#include "karma_future/karma_future.h"
|
||||
#include "mode_nine/mode_nine.h"
|
||||
#include "pixelflag/pixelflag.h"
|
||||
#include "redhat_mono/redhat_mono.h"
|
||||
#include "zector/zector.h"
|
||||
|
||||
const FONT_INFO* const available_fonts[AVAILABLE_FONTS_COUNT] = {
|
||||
&modeNine_15ptFontInfo,
|
||||
&_712Serif_24ptFontInfo,
|
||||
&bedstead_17ptFontInfo,
|
||||
&dPComic_18ptFontInfo,
|
||||
&funclimbingDemo_18ptFontInfo,
|
||||
&graph35pix_12ptFontInfo,
|
||||
&karmaFuture_14ptFontInfo,
|
||||
&pixelFlag_18ptFontInfo,
|
||||
&redHatMono_16ptFontInfo,
|
||||
&zector_18ptFontInfo};
|
||||
7
applications/external/totp/lib/fonts/available_fonts.h
vendored
Normal file
7
applications/external/totp/lib/fonts/available_fonts.h
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "font_info.h"
|
||||
|
||||
#define AVAILABLE_FONTS_COUNT (10)
|
||||
|
||||
extern const FONT_INFO* const available_fonts[AVAILABLE_FONTS_COUNT];
|
||||
@@ -1047,6 +1047,7 @@ const FONT_CHAR_INFO bedstead_17ptDescriptors[] = {
|
||||
|
||||
/* Font information for Bedstead 17pt */
|
||||
const FONT_INFO bedstead_17ptFontInfo = {
|
||||
"Bedstead",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -1105,6 +1105,7 @@ const FONT_CHAR_INFO dPComic_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for DPComic 18pt */
|
||||
const FONT_INFO dPComic_18ptFontInfo = {
|
||||
"DP Comic",
|
||||
17, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -14,11 +14,11 @@ typedef struct {
|
||||
|
||||
// Describes a single font
|
||||
typedef struct {
|
||||
const char* name; // Font name
|
||||
const uint8_t height; // height, in pages (8 pixels), of the font's characters
|
||||
const uint8_t startChar; // the first character in the font (e.g. in charInfo and data)
|
||||
const uint8_t endChar; // the last character in the font
|
||||
const uint8_t spacePixels; // number of pixels that a space character takes up
|
||||
const FONT_CHAR_INFO* charInfo; // pointer to array of char information
|
||||
const uint8_t* data; // pointer to generated array of character visual representation
|
||||
|
||||
} FONT_INFO;
|
||||
@@ -1163,6 +1163,7 @@ const FONT_CHAR_INFO funclimbingDemo_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for fun climbing (Demo) 18pt */
|
||||
const FONT_INFO funclimbingDemo_18ptFontInfo = {
|
||||
"Fun Climbing",
|
||||
18, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -931,6 +931,7 @@ const FONT_CHAR_INFO graph35pix_12ptDescriptors[] = {
|
||||
|
||||
/* Font information for Graph 35+ pix 12pt */
|
||||
const FONT_INFO graph35pix_12ptFontInfo = {
|
||||
"Graph 35pix",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -1163,6 +1163,7 @@ const FONT_CHAR_INFO karmaFuture_14ptDescriptors[] = {
|
||||
|
||||
/* Font information for Karma Future 14pt */
|
||||
const FONT_INFO karmaFuture_14ptFontInfo = {
|
||||
"Karma Future",
|
||||
18, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -932,6 +932,7 @@ const FONT_CHAR_INFO modeNine_15ptDescriptors[] = {
|
||||
|
||||
/* Font information for ModeNine 15pt */
|
||||
const FONT_INFO modeNine_15ptFontInfo = {
|
||||
"Mode Nine",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -1105,6 +1105,7 @@ const FONT_CHAR_INFO pixelFlag_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for {PixelFlag} 18pt */
|
||||
const FONT_INFO pixelFlag_18ptFontInfo = {
|
||||
"Pixel Flag",
|
||||
17, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -1048,6 +1048,7 @@ const FONT_CHAR_INFO redHatMono_16ptDescriptors[] = {
|
||||
|
||||
/* Font information for Red Hat Mono 16pt */
|
||||
const FONT_INFO redHatMono_16ptFontInfo = {
|
||||
"RedHat Mono",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -1047,6 +1047,7 @@ const FONT_CHAR_INFO zector_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for Zector 18pt */
|
||||
const FONT_INFO zector_18ptFontInfo = {
|
||||
"Zector",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -15,9 +15,6 @@
|
||||
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
||||
#define CONFIG_FILE_BACKUP_DIR CONFIG_FILE_DIRECTORY_PATH "/backups"
|
||||
#define CONFIG_FILE_BACKUP_BASE_PATH CONFIG_FILE_BACKUP_DIR "/totp.conf"
|
||||
#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
||||
#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
|
||||
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
|
||||
|
||||
struct ConfigFileContext {
|
||||
/**
|
||||
@@ -120,26 +117,6 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
FURI_LOG_D(
|
||||
LOGGING_TAG,
|
||||
"Directory %s doesn't exist. Will create new.",
|
||||
CONFIG_FILE_DIRECTORY_PATH);
|
||||
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
|
||||
return totp_open_config_file(storage, file);
|
||||
} else {
|
||||
FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
@@ -177,9 +154,8 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1);
|
||||
|
||||
// Default Font = 0
|
||||
tmp_uint32 = 0;
|
||||
flipper_format_write_uint32(fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1);
|
||||
flipper_format_write_uint32(fff_data_file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1);
|
||||
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
@@ -263,24 +239,6 @@ bool totp_config_file_update_automation_method(const PluginState* plugin_state)
|
||||
return update_result;
|
||||
}
|
||||
|
||||
bool totp_config_file_update_selected_font(const PluginState* plugin_state) {
|
||||
FlipperFormat* file = plugin_state->config_file_context->config_file;
|
||||
flipper_format_rewind(file);
|
||||
bool update_result = false;
|
||||
|
||||
do {
|
||||
uint32_t tmp_uint32 = plugin_state->selected_font;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = true;
|
||||
} while(false);
|
||||
|
||||
return update_result;
|
||||
}
|
||||
|
||||
bool totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
FlipperFormat* file = plugin_state->config_file_context->config_file;
|
||||
flipper_format_rewind(file);
|
||||
@@ -302,9 +260,8 @@ bool totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_uint32 = plugin_state->selected_font;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = plugin_state->active_font_index;
|
||||
if(!flipper_format_insert_or_update_uint32(file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -456,15 +413,11 @@ bool totp_config_file_load(PluginState* const plugin_state) {
|
||||
|
||||
plugin_state->automation_method = tmp_uint32;
|
||||
|
||||
// Load selected font
|
||||
flipper_format_rewind(fff_data_file);
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
if(!flipper_format_read_uint32(fff_data_file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = 0;
|
||||
}
|
||||
|
||||
plugin_state->selected_font = tmp_uint32;
|
||||
plugin_state->active_font_index = tmp_uint32;
|
||||
|
||||
plugin_state->config_file_context = malloc(sizeof(ConfigFileContext));
|
||||
furi_check(plugin_state->config_file_context != NULL);
|
||||
|
||||
@@ -44,13 +44,6 @@ bool totp_config_file_update_notification_method(const PluginState* plugin_state
|
||||
*/
|
||||
bool totp_config_file_update_automation_method(const PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Updates selected font in an application config file
|
||||
* @param plugin_state application state
|
||||
* @return Config file update result
|
||||
*/
|
||||
bool totp_config_file_update_selected_font(const PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Updates application user settings
|
||||
* @param plugin_state application state
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
||||
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (5)
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (6)
|
||||
|
||||
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
||||
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
||||
@@ -18,4 +18,4 @@
|
||||
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
|
||||
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
|
||||
#define TOTP_CONFIG_KEY_SELECTED_FONT "SelectedFont"
|
||||
#define TOTP_CONFIG_KEY_FONT "Font"
|
||||
|
||||
@@ -58,11 +58,12 @@ bool totp_config_migrate_to_latest(
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
|
||||
// Font
|
||||
|
||||
if(flipper_format_read_string(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, temp_str);
|
||||
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_FONT, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_FONT, temp_str);
|
||||
} else {
|
||||
uint32_t default_font_index = 0;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_FONT, &default_font_index, 1);
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
@@ -84,13 +85,13 @@ bool totp_config_migrate_to_latest(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str);
|
||||
|
||||
if(current_version < 5) {
|
||||
uint32_t algo_as_uint32t = SHA1;
|
||||
if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_SHA256_NAME) == 0) {
|
||||
algo_as_uint32t = SHA256;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_SHA512_NAME) == 0) {
|
||||
algo_as_uint32t = SHA512;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
|
||||
algo_as_uint32t = STEAM;
|
||||
uint32_t algo_as_uint32t = TokenHashAlgoDefault;
|
||||
if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_SHA256_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSha256;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_SHA512_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSha512;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_STEAM_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSteam;
|
||||
}
|
||||
|
||||
flipper_format_write_uint32(
|
||||
@@ -104,10 +105,10 @@ bool totp_config_migrate_to_latest(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||
} else {
|
||||
const uint32_t default_algo = SHA1;
|
||||
const uint32_t default_algo = TokenHashAlgoDefault;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, &default_algo, 1);
|
||||
const uint32_t default_digits = TotpSixDigitsCount;
|
||||
const uint32_t default_digits = TokenDigitsCountSix;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1);
|
||||
}
|
||||
@@ -118,7 +119,7 @@ bool totp_config_migrate_to_latest(
|
||||
flipper_format_write_string(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, temp_str);
|
||||
} else {
|
||||
const uint32_t default_duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
const uint32_t default_duration = TokenDurationDefault;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &default_duration, 1);
|
||||
}
|
||||
|
||||
@@ -496,19 +496,19 @@ bool totp_token_info_iterator_go_to(TokenInfoIteratorContext* context, size_t to
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_ALGO, &temp_data32, 1) ||
|
||||
!token_info_set_algo_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->algo = SHA1;
|
||||
tokenInfo->algo = TokenHashAlgoDefault;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1) ||
|
||||
!token_info_set_digits_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->digits = TotpSixDigitsCount;
|
||||
tokenInfo->digits = TokenDigitsCountSix;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &temp_data32, 1) ||
|
||||
!token_info_set_duration_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
tokenInfo->duration = TokenDurationDefault;
|
||||
}
|
||||
|
||||
if(flipper_format_read_uint32(
|
||||
|
||||
@@ -90,11 +90,8 @@ CryptoSeedIVResult
|
||||
} else {
|
||||
max_i = uid_size;
|
||||
}
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
const uint8_t* uid = furi_hal_version_uid_default();
|
||||
#else
|
||||
const uint8_t* uid = furi_hal_version_uid();
|
||||
#endif
|
||||
|
||||
const uint8_t* uid = (const uint8_t*)UID64_BASE; //-V566
|
||||
for(uint8_t i = 0; i < max_i; i++) {
|
||||
plugin_state->iv[i] = plugin_state->iv[i] ^ uid[i];
|
||||
}
|
||||
|
||||
3
applications/external/totp/totp_app.c
vendored
3
applications/external/totp/totp_app.c
vendored
@@ -116,7 +116,6 @@ static bool on_user_idle(void* context) {
|
||||
}
|
||||
|
||||
static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->selected_font = 0;
|
||||
plugin_state->gui = furi_record_open(RECORD_GUI);
|
||||
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
||||
@@ -208,7 +207,7 @@ int32_t totp_app() {
|
||||
PluginEvent event;
|
||||
bool processing = true;
|
||||
while(processing) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever);
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
if(furi_mutex_acquire(plugin_state->mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
if(event_status == FuriStatusOk) {
|
||||
|
||||
10
applications/external/totp/types/plugin_state.h
vendored
10
applications/external/totp/types/plugin_state.h
vendored
@@ -84,11 +84,6 @@ typedef struct {
|
||||
*/
|
||||
NotificationMethod notification_method;
|
||||
|
||||
/**
|
||||
* @brief Numbers Font
|
||||
*/
|
||||
uint8_t selected_font;
|
||||
|
||||
/**
|
||||
* @brief Main rendering loop mutex
|
||||
*/
|
||||
@@ -110,4 +105,9 @@ typedef struct {
|
||||
* @brief IDLE timeout context
|
||||
*/
|
||||
IdleTimeoutContext* idle_timeout_context;
|
||||
|
||||
/**
|
||||
* @brief Font index to be used to draw TOTP token
|
||||
*/
|
||||
uint8_t active_font_index;
|
||||
} PluginState;
|
||||
|
||||
75
applications/external/totp/types/token_info.c
vendored
75
applications/external/totp/types/token_info.c
vendored
@@ -69,13 +69,13 @@ bool token_info_set_secret(
|
||||
bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
||||
switch(digits) {
|
||||
case 5:
|
||||
token_info->digits = TotpFiveDigitsCount;
|
||||
token_info->digits = TokenDigitsCountFive;
|
||||
return true;
|
||||
case 6:
|
||||
token_info->digits = TotpSixDigitsCount;
|
||||
token_info->digits = TokenDigitsCountSix;
|
||||
return true;
|
||||
case 8:
|
||||
token_info->digits = TotpEightDigitsCount;
|
||||
token_info->digits = TokenDigitsCountEight;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
@@ -85,32 +85,35 @@ bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
||||
}
|
||||
|
||||
bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration) {
|
||||
if(duration >= 15) {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
if(duration >= TokenDurationMin && duration <= TokenDurationMax) { //-V560
|
||||
token_info->duration = duration;
|
||||
return true;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) {
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA1_NAME) == 0) {
|
||||
token_info->algo = SHA1;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA1_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA256_NAME) == 0) {
|
||||
token_info->algo = SHA256;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA256_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha256;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA512_NAME) == 0) {
|
||||
token_info->algo = SHA512;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA512_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha512;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
|
||||
token_info->algo = STEAM;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_STEAM_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSteam;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -119,17 +122,17 @@ bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str)
|
||||
|
||||
bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code) {
|
||||
switch(algo_code) {
|
||||
case SHA1:
|
||||
token_info->algo = SHA1;
|
||||
case TokenHashAlgoSha1:
|
||||
token_info->algo = TokenHashAlgoSha1;
|
||||
break;
|
||||
case SHA256:
|
||||
token_info->algo = SHA256;
|
||||
case TokenHashAlgoSha256:
|
||||
token_info->algo = TokenHashAlgoSha256;
|
||||
break;
|
||||
case SHA512:
|
||||
token_info->algo = SHA512;
|
||||
case TokenHashAlgoSha512:
|
||||
token_info->algo = TokenHashAlgoSha512;
|
||||
break;
|
||||
case STEAM:
|
||||
token_info->algo = STEAM;
|
||||
case TokenHashAlgoSteam:
|
||||
token_info->algo = TokenHashAlgoSteam;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@@ -138,16 +141,16 @@ bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
const char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
switch(token_info->algo) {
|
||||
case SHA1:
|
||||
return TOTP_TOKEN_ALGO_SHA1_NAME;
|
||||
case SHA256:
|
||||
return TOTP_TOKEN_ALGO_SHA256_NAME;
|
||||
case SHA512:
|
||||
return TOTP_TOKEN_ALGO_SHA512_NAME;
|
||||
case STEAM:
|
||||
return TOTP_TOKEN_ALGO_STEAM_NAME;
|
||||
case TokenHashAlgoSha1:
|
||||
return TOKEN_HASH_ALGO_SHA1_NAME;
|
||||
case TokenHashAlgoSha256:
|
||||
return TOKEN_HASH_ALGO_SHA256_NAME;
|
||||
case TokenHashAlgoSha512:
|
||||
return TOKEN_HASH_ALGO_SHA512_NAME;
|
||||
case TokenHashAlgoSteam:
|
||||
return TOKEN_HASH_ALGO_STEAM_NAME;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -156,22 +159,22 @@ char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
}
|
||||
|
||||
bool token_info_set_automation_feature_from_str(TokenInfo* token_info, const FuriString* str) {
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureEnterAtTheEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureTabAtTheEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureTypeSlower;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) {
|
||||
token_info->automation_features = TokenAutomationFeatureNone;
|
||||
return true;
|
||||
}
|
||||
@@ -195,9 +198,9 @@ TokenInfo* token_info_clone(const TokenInfo* src) {
|
||||
|
||||
void token_info_set_defaults(TokenInfo* token_info) {
|
||||
furi_check(token_info != NULL);
|
||||
token_info->algo = SHA1;
|
||||
token_info->digits = TotpSixDigitsCount;
|
||||
token_info->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
token_info->algo = TokenHashAlgoDefault;
|
||||
token_info->digits = TokenDigitsCountDefault;
|
||||
token_info->duration = TokenDurationDefault;
|
||||
token_info->automation_features = TokenAutomationFeatureNone;
|
||||
furi_string_reset(token_info->name);
|
||||
}
|
||||
77
applications/external/totp/types/token_info.h
vendored
77
applications/external/totp/types/token_info.h
vendored
@@ -4,26 +4,20 @@
|
||||
#include <stdbool.h>
|
||||
#include <furi/core/string.h>
|
||||
|
||||
#define TOTP_TOKEN_DURATION_DEFAULT (30)
|
||||
|
||||
#define TOTP_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||
#define TOTP_TOKEN_ALGO_STEAM_NAME "steam"
|
||||
#define TOTP_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||
#define TOTP_TOKEN_ALGO_SHA512_NAME "sha512"
|
||||
#define TOTP_TOKEN_MAX_LENGTH (255)
|
||||
|
||||
#define TOKEN_HASH_ALGO_SHA1_NAME "sha1"
|
||||
#define TOKEN_HASH_ALGO_STEAM_NAME "steam"
|
||||
#define TOKEN_HASH_ALGO_SHA256_NAME "sha256"
|
||||
#define TOKEN_HASH_ALGO_SHA512_NAME "sha512"
|
||||
#define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32"
|
||||
#define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64"
|
||||
|
||||
#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"
|
||||
|
||||
#define TOTP_TOKEN_DIGITS_MAX_COUNT (8)
|
||||
#define TOKEN_AUTOMATION_FEATURE_NONE_NAME "none"
|
||||
#define TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME "enter"
|
||||
#define TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME "tab"
|
||||
#define TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME "slower"
|
||||
|
||||
typedef uint8_t TokenHashAlgo;
|
||||
typedef uint8_t TokenDigitsCount;
|
||||
typedef uint8_t TokenDuration;
|
||||
typedef uint8_t TokenAutomationFeature;
|
||||
typedef uint8_t PlainTokenSecretEncoding;
|
||||
|
||||
@@ -34,22 +28,27 @@ enum TokenHashAlgos {
|
||||
/**
|
||||
* @brief SHA1 hashing algorithm
|
||||
*/
|
||||
SHA1 = 0,
|
||||
TokenHashAlgoSha1 = 0,
|
||||
|
||||
/**
|
||||
* @brief SHA256 hashing algorithm
|
||||
*/
|
||||
SHA256 = 1,
|
||||
TokenHashAlgoSha256 = 1,
|
||||
|
||||
/**
|
||||
* @brief SHA512 hashing algorithm
|
||||
*/
|
||||
SHA512 = 2,
|
||||
TokenHashAlgoSha512 = 2,
|
||||
|
||||
/**
|
||||
* @brief Algorithm used by Steam (Valve)
|
||||
*/
|
||||
STEAM = 3
|
||||
TokenHashAlgoSteam = 3,
|
||||
|
||||
/**
|
||||
* @brief Default token hashing algorithm
|
||||
*/
|
||||
TokenHashAlgoDefault = TokenHashAlgoSha1
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -59,17 +58,47 @@ enum TokenDigitsCounts {
|
||||
/**
|
||||
* @brief 5 digits
|
||||
*/
|
||||
TotpFiveDigitsCount = 5,
|
||||
TokenDigitsCountFive = 5,
|
||||
|
||||
/**
|
||||
* @brief 6 digits
|
||||
*/
|
||||
TotpSixDigitsCount = 6,
|
||||
TokenDigitsCountSix = 6,
|
||||
|
||||
/**
|
||||
* @brief 8 digits
|
||||
*/
|
||||
TotpEightDigitsCount = 8
|
||||
TokenDigitsCountEight = 8,
|
||||
|
||||
/**
|
||||
* @brief Default digits count
|
||||
*/
|
||||
TokenDigitsCountDefault = TokenDigitsCountSix,
|
||||
|
||||
/**
|
||||
* @brief Maximum digits count
|
||||
*/
|
||||
TokenDigitsCountMax = TokenDigitsCountEight
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Token durations
|
||||
*/
|
||||
enum TokenDurations {
|
||||
/**
|
||||
* @brief Default token duration
|
||||
*/
|
||||
TokenDurationDefault = 30,
|
||||
|
||||
/**
|
||||
* @brief Minimum token duration
|
||||
*/
|
||||
TokenDurationMin = 15,
|
||||
|
||||
/**
|
||||
* @brief Maximum token duration
|
||||
*/
|
||||
TokenDurationMax = UINT8_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -145,7 +174,7 @@ typedef struct {
|
||||
/**
|
||||
* @brief Desired TOTP token duration in seconds
|
||||
*/
|
||||
uint8_t duration;
|
||||
TokenDuration duration;
|
||||
|
||||
/**
|
||||
* @brief Token input automation features
|
||||
@@ -218,7 +247,7 @@ bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code);
|
||||
* @param token_info instance which token hahsing algorithm name should be returned
|
||||
* @return token hashing algorithm name as C-string
|
||||
*/
|
||||
char* token_info_get_algo_as_cstr(const TokenInfo* token_info);
|
||||
const char* token_info_get_algo_as_cstr(const TokenInfo* token_info);
|
||||
|
||||
/**
|
||||
* @brief Sets token automation feature from \c str value
|
||||
|
||||
33
applications/external/totp/ui/canvas_extensions.c
vendored
Normal file
33
applications/external/totp/ui/canvas_extensions.c
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "canvas_extensions.h"
|
||||
|
||||
void canvas_draw_str_ex(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
const char* text,
|
||||
size_t text_length,
|
||||
const FONT_INFO* const font) {
|
||||
const char* p_ch = text;
|
||||
char ch;
|
||||
size_t i = 0;
|
||||
uint8_t offset_x = x;
|
||||
uint8_t char_width = font->charInfo[0].width;
|
||||
uint8_t offset_x_inc = char_width + font->spacePixels;
|
||||
while(i < text_length && (ch = *p_ch) != 0) {
|
||||
if(ch >= font->startChar && ch <= font->endChar) {
|
||||
uint8_t char_index = ch - font->startChar;
|
||||
canvas_draw_xbm(
|
||||
canvas,
|
||||
offset_x,
|
||||
y,
|
||||
char_width,
|
||||
font->height,
|
||||
&font->data[font->charInfo[char_index].offset]);
|
||||
}
|
||||
|
||||
offset_x += offset_x_inc;
|
||||
|
||||
p_ch++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
13
applications/external/totp/ui/canvas_extensions.h
vendored
Normal file
13
applications/external/totp/ui/canvas_extensions.h
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <gui/gui.h>
|
||||
#include <font_info.h>
|
||||
|
||||
void canvas_draw_str_ex(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
const char* text,
|
||||
size_t text_length,
|
||||
const FONT_INFO* const font);
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../features_config.h"
|
||||
#include "font_info.h"
|
||||
|
||||
#include "mode_nine/mode_nine.h"
|
||||
#include "redhat_mono/redhat_mono.h"
|
||||
#include "bedstead/bedstead.h"
|
||||
#include "zector/zector.h"
|
||||
#include "712serif/712serif.h"
|
||||
#include "graph35pix/graph35pix.h"
|
||||
#include "karma_future/karma_future.h"
|
||||
#include "funclimbing/funclimbing.h"
|
||||
#include "dpcomic/dpcomic.h"
|
||||
#include "pixelflag/pixelflag.h"
|
||||
@@ -1,81 +1,52 @@
|
||||
#include "totp_input_text.h"
|
||||
#include <gui/view_i.h>
|
||||
|
||||
void view_draw(View* view, Canvas* canvas) {
|
||||
furi_assert(view);
|
||||
if(view->draw_callback) {
|
||||
void* data = view_get_model(view);
|
||||
view->draw_callback(canvas, data);
|
||||
view_unlock_model(view);
|
||||
}
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
|
||||
typedef struct {
|
||||
InputTextResult* result;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
} InputTextContext;
|
||||
|
||||
static void commit_text_input_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->user_input_length = strnlen(context->result->user_input, INPUT_BUFFER_SIZE);
|
||||
context->result->success = true;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
}
|
||||
|
||||
bool view_input(View* view, InputEvent* event) {
|
||||
furi_assert(view);
|
||||
if(view->input_callback) {
|
||||
return view->input_callback(event, view->context);
|
||||
} else {
|
||||
static bool back_event_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->success = false;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void view_unlock_model(View* view) {
|
||||
furi_assert(view);
|
||||
if(view->model_type == ViewModelTypeLocking) {
|
||||
ViewModelLocking* model = (ViewModelLocking*)(view->model);
|
||||
furi_check(furi_mutex_release(model->mutex) == FuriStatusOk);
|
||||
}
|
||||
}
|
||||
|
||||
static void commit_text_input_callback(void* context) {
|
||||
InputTextSceneState* text_input_state = (InputTextSceneState*)context;
|
||||
if(text_input_state->callback != NULL) {
|
||||
InputTextSceneCallbackResult* result = malloc(sizeof(InputTextSceneCallbackResult));
|
||||
furi_check(result != NULL);
|
||||
result->user_input_length =
|
||||
strnlen(text_input_state->text_input_buffer, INPUT_BUFFER_SIZE);
|
||||
result->user_input = malloc(result->user_input_length + 1);
|
||||
furi_check(result->user_input != NULL);
|
||||
result->callback_data = text_input_state->callback_data;
|
||||
strlcpy(
|
||||
result->user_input,
|
||||
text_input_state->text_input_buffer,
|
||||
result->user_input_length + 1);
|
||||
text_input_state->callback(result);
|
||||
}
|
||||
}
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context) {
|
||||
InputTextSceneState* text_input_state = malloc(sizeof(InputTextSceneState));
|
||||
furi_check(text_input_state != NULL);
|
||||
text_input_state->text_input = text_input_alloc();
|
||||
text_input_state->text_input_view = text_input_get_view(text_input_state->text_input);
|
||||
text_input_state->callback = context->callback;
|
||||
text_input_state->callback_data = context->callback_data;
|
||||
text_input_set_header_text(text_input_state->text_input, context->header_text);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result) {
|
||||
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
|
||||
TextInput* text_input = text_input_alloc();
|
||||
InputTextContext context = {.result = result, .view_dispatcher = view_dispatcher};
|
||||
text_input_set_header_text(text_input, header_text);
|
||||
text_input_set_result_callback(
|
||||
text_input_state->text_input,
|
||||
text_input,
|
||||
commit_text_input_callback,
|
||||
text_input_state,
|
||||
&text_input_state->text_input_buffer[0],
|
||||
&context,
|
||||
result->user_input,
|
||||
INPUT_BUFFER_SIZE,
|
||||
true);
|
||||
return text_input_state;
|
||||
}
|
||||
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state) {
|
||||
view_draw(text_input_state->text_input_view, canvas);
|
||||
}
|
||||
view_dispatcher_enable_queue(view_dispatcher);
|
||||
view_dispatcher_add_view(view_dispatcher, 0, text_input_get_view(text_input));
|
||||
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state) {
|
||||
if(event->type == EventTypeKey) {
|
||||
view_input(text_input_state->text_input_view, &event->input);
|
||||
}
|
||||
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
return true;
|
||||
}
|
||||
view_dispatcher_set_navigation_event_callback(view_dispatcher, &back_event_callback);
|
||||
view_dispatcher_set_event_callback_context(view_dispatcher, &context);
|
||||
view_dispatcher_switch_to_view(view_dispatcher, 0);
|
||||
|
||||
void totp_input_text_free(InputTextSceneState* state) {
|
||||
text_input_free(state->text_input);
|
||||
free(state);
|
||||
view_dispatcher_run(view_dispatcher);
|
||||
|
||||
view_dispatcher_remove_view(view_dispatcher, 0);
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
text_input_free(text_input);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
#define INPUT_BUFFER_SIZE (255)
|
||||
|
||||
typedef struct {
|
||||
char* user_input;
|
||||
char user_input[INPUT_BUFFER_SIZE];
|
||||
size_t user_input_length;
|
||||
void* callback_data;
|
||||
} InputTextSceneCallbackResult;
|
||||
bool success;
|
||||
} InputTextResult;
|
||||
|
||||
typedef void (*InputTextSceneCallback)(InputTextSceneCallbackResult* result);
|
||||
|
||||
typedef struct {
|
||||
InputTextSceneCallback callback;
|
||||
char* header_text;
|
||||
void* callback_data;
|
||||
} InputTextSceneContext;
|
||||
|
||||
typedef struct {
|
||||
TextInput* text_input;
|
||||
View* text_input_view;
|
||||
char text_input_buffer[INPUT_BUFFER_SIZE];
|
||||
InputTextSceneCallback callback;
|
||||
void* callback_data;
|
||||
} InputTextSceneState;
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context);
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state);
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state);
|
||||
void totp_input_text_free(InputTextSceneState* state);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
|
||||
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
|
||||
TotpFiveDigitsCount,
|
||||
TotpSixDigitsCount,
|
||||
TotpEightDigitsCount};
|
||||
TokenDigitsCountFive,
|
||||
TokenDigitsCountSix,
|
||||
TokenDigitsCountEight};
|
||||
|
||||
typedef enum {
|
||||
TokenNameTextBox,
|
||||
@@ -33,10 +33,6 @@ typedef struct {
|
||||
size_t token_secret_length;
|
||||
bool saved;
|
||||
Control selected_control;
|
||||
InputTextSceneContext* token_name_input_context;
|
||||
InputTextSceneContext* token_secret_input_context;
|
||||
InputTextSceneState* input_state;
|
||||
bool text_input_mode;
|
||||
int16_t screen_y_offset;
|
||||
TokenHashAlgo algo;
|
||||
uint8_t digits_count_index;
|
||||
@@ -51,24 +47,6 @@ struct TotpAddContext {
|
||||
|
||||
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
|
||||
|
||||
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_name);
|
||||
scene_state->token_name = result->user_input;
|
||||
scene_state->token_name_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_secret);
|
||||
scene_state->token_secret = result->user_input;
|
||||
scene_state->token_secret_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void update_duration_text(SceneState* scene_state) {
|
||||
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
|
||||
}
|
||||
@@ -95,6 +73,26 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
|
||||
return TotpIteratorUpdateTokenResultSuccess;
|
||||
}
|
||||
|
||||
static void ask_user_input(
|
||||
const PluginState* plugin_state,
|
||||
const char* header,
|
||||
char** user_input,
|
||||
size_t* user_input_length) {
|
||||
InputTextResult input_result;
|
||||
if(*user_input != NULL) {
|
||||
strlcpy(input_result.user_input, *user_input, INPUT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
totp_input_text(plugin_state->gui, header, &input_result);
|
||||
if(input_result.success) {
|
||||
if(*user_input != NULL) {
|
||||
free(*user_input);
|
||||
}
|
||||
*user_input = strdup(input_result.user_input);
|
||||
*user_input_length = input_result.user_input_length;
|
||||
}
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
SceneState* scene_state = malloc(sizeof(SceneState));
|
||||
furi_check(scene_state != NULL);
|
||||
@@ -104,34 +102,17 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
scene_state->token_secret = "Secret";
|
||||
scene_state->token_secret_length = strlen(scene_state->token_secret);
|
||||
|
||||
scene_state->token_name_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_name_input_context != NULL);
|
||||
scene_state->token_name_input_context->header_text = "Enter token name";
|
||||
scene_state->token_name_input_context->callback_data = scene_state;
|
||||
scene_state->token_name_input_context->callback = on_token_name_user_comitted;
|
||||
|
||||
scene_state->token_secret_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_secret_input_context != NULL);
|
||||
scene_state->token_secret_input_context->header_text = "Enter token secret";
|
||||
scene_state->token_secret_input_context->callback_data = scene_state;
|
||||
scene_state->token_secret_input_context->callback = on_token_secret_user_comitted;
|
||||
|
||||
scene_state->screen_y_offset = 0;
|
||||
|
||||
scene_state->digits_count_index = 1;
|
||||
|
||||
scene_state->input_state = NULL;
|
||||
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
scene_state->duration = TokenDurationDefault;
|
||||
scene_state->duration_text = furi_string_alloc();
|
||||
update_duration_text(scene_state);
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
if(scene_state->text_input_mode) {
|
||||
totp_input_text_render(canvas, scene_state->input_state);
|
||||
return;
|
||||
}
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state) {
|
||||
const SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
ui_control_text_box_render(
|
||||
canvas,
|
||||
@@ -195,31 +176,15 @@ void update_screen_y_offset(SceneState* scene_state) {
|
||||
}
|
||||
}
|
||||
|
||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state) {
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state) {
|
||||
if(event->type != EventTypeKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) {
|
||||
if(scene_state->text_input_mode) {
|
||||
scene_state->text_input_mode = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(scene_state->text_input_mode) {
|
||||
if(event->input.type == InputTypeShort && event->input.key == InputKeyBack) {
|
||||
PluginEvent long_back_cb_evt = {
|
||||
.type = event->type, .input.key = InputKeyBack, .input.type = InputTypeLong};
|
||||
return totp_input_text_handle_event(&long_back_cb_evt, scene_state->input_state);
|
||||
}
|
||||
|
||||
return totp_input_text_handle_event(event, scene_state->input_state);
|
||||
}
|
||||
|
||||
if(event->input.type == InputTypePress) {
|
||||
switch(event->input.key) {
|
||||
case InputKeyUp:
|
||||
@@ -243,7 +208,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyRight:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, 1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -256,7 +225,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, -1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
-1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -277,22 +250,18 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
|
||||
switch(scene_state->selected_control) {
|
||||
case TokenNameTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_name_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token name",
|
||||
&scene_state->token_name,
|
||||
&scene_state->token_name_length);
|
||||
break;
|
||||
case TokenSecretTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_secret_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token secret",
|
||||
&scene_state->token_secret,
|
||||
&scene_state->token_secret_length);
|
||||
break;
|
||||
case TokenAlgoSelect:
|
||||
break;
|
||||
@@ -344,18 +313,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
||||
free(scene_state->token_name);
|
||||
free(scene_state->token_secret);
|
||||
|
||||
free(scene_state->token_name_input_context->header_text);
|
||||
free(scene_state->token_name_input_context);
|
||||
|
||||
free(scene_state->token_secret_input_context->header_text);
|
||||
free(scene_state->token_secret_input_context);
|
||||
|
||||
furi_string_free(scene_state->duration_text);
|
||||
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
|
||||
free(plugin_state->current_scene_state);
|
||||
plugin_state->current_scene_state = NULL;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
void totp_scene_add_new_token_activate(PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
|
||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state);
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "totp_app_settings.h"
|
||||
#include <math.h>
|
||||
#include <totp_icons.h>
|
||||
#include <available_fonts.h>
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../scene_director.h"
|
||||
@@ -14,18 +16,20 @@
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
static const char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
static const char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
static const char* FONT_TEST_STR = "0123BCD";
|
||||
static const uint8_t FONT_TEST_STR_LENGTH = 7;
|
||||
|
||||
typedef enum {
|
||||
HoursInput,
|
||||
MinutesInput,
|
||||
Sound,
|
||||
Vibro,
|
||||
FontSelector,
|
||||
BadUsb,
|
||||
FontSelect,
|
||||
SoundSwitch,
|
||||
VibroSwitch,
|
||||
BadUsbSwitch,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
BadBt,
|
||||
BadBtSwitch,
|
||||
#endif
|
||||
ConfirmButton
|
||||
} Control;
|
||||
@@ -35,13 +39,13 @@ typedef struct {
|
||||
uint8_t tz_offset_minutes;
|
||||
bool notification_sound;
|
||||
bool notification_vibro;
|
||||
uint8_t selected_font;
|
||||
bool badusb_enabled;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
bool badbt_enabled;
|
||||
#endif
|
||||
uint8_t y_offset;
|
||||
Control selected_control;
|
||||
uint8_t active_font;
|
||||
} SceneState;
|
||||
|
||||
void totp_scene_app_settings_activate(PluginState* plugin_state) {
|
||||
@@ -56,10 +60,10 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
|
||||
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;
|
||||
scene_state->selected_font = plugin_state->selected_font;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
scene_state->badbt_enabled = plugin_state->automation_method & AutomationMethodBadBt;
|
||||
#endif
|
||||
scene_state->active_font = plugin_state->active_font_index;
|
||||
}
|
||||
|
||||
static void two_digit_to_str(int8_t num, char* str) {
|
||||
@@ -113,75 +117,87 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
&I_totp_arrow_bottom_10x5);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications / UI");
|
||||
canvas_draw_str_aligned(canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 78 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
const FONT_INFO* const font = available_fonts[scene_state->active_font];
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
71 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == Sound);
|
||||
0,
|
||||
74 - scene_state->y_offset,
|
||||
SCREEN_WIDTH,
|
||||
font->name,
|
||||
scene_state->selected_control == FontSelect);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 94 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
87 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == Vibro);
|
||||
|
||||
two_digit_to_str(scene_state->selected_font, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 110 - scene_state->y_offset, AlignLeft, AlignTop, "UI Font:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
103 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == FontSelector);
|
||||
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_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, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
|
||||
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,
|
||||
ON_OFF_LIST[scene_state->badusb_enabled],
|
||||
scene_state->selected_control == BadUsb);
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == SoundSwitch);
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
|
||||
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);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 187 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
|
||||
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 == BadBt);
|
||||
scene_state->selected_control == BadBtSwitch);
|
||||
#endif
|
||||
|
||||
ui_control_button_render(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 24,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
178 - scene_state->y_offset,
|
||||
242 - scene_state->y_offset,
|
||||
#else
|
||||
165 - scene_state->y_offset,
|
||||
229 - scene_state->y_offset,
|
||||
#endif
|
||||
48,
|
||||
13,
|
||||
@@ -206,10 +222,12 @@ bool totp_scene_app_settings_handle_event(
|
||||
HoursInput,
|
||||
ConfirmButton,
|
||||
RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > FontSelector) {
|
||||
scene_state->y_offset = 128;
|
||||
if(scene_state->selected_control > VibroSwitch) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 3;
|
||||
} else if(scene_state->selected_control > FontSelect) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 2;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
scene_state->y_offset = SCREEN_HEIGHT;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
}
|
||||
@@ -221,10 +239,12 @@ bool totp_scene_app_settings_handle_event(
|
||||
HoursInput,
|
||||
ConfirmButton,
|
||||
RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > FontSelector) {
|
||||
scene_state->y_offset = 128;
|
||||
if(scene_state->selected_control > VibroSwitch) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 3;
|
||||
} else if(scene_state->selected_control > FontSelect) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 2;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
scene_state->y_offset = SCREEN_HEIGHT;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
}
|
||||
@@ -236,22 +256,25 @@ bool totp_scene_app_settings_handle_event(
|
||||
} else if(scene_state->selected_control == MinutesInput) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == Sound) {
|
||||
} else if(scene_state->selected_control == FontSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->active_font,
|
||||
1,
|
||||
0,
|
||||
AVAILABLE_FONTS_COUNT - 1,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == SoundSwitch) {
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
else if(scene_state->selected_control == FontSelector) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->selected_font, 1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == HoursInput) {
|
||||
@@ -260,22 +283,25 @@ bool totp_scene_app_settings_handle_event(
|
||||
} else if(scene_state->selected_control == MinutesInput) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == Sound) {
|
||||
} else if(scene_state->selected_control == FontSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->active_font,
|
||||
-1,
|
||||
0,
|
||||
AVAILABLE_FONTS_COUNT - 1,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == SoundSwitch) {
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
else if(scene_state->selected_control == FontSelector) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->selected_font, -1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
break;
|
||||
@@ -302,7 +328,8 @@ bool totp_scene_app_settings_handle_event(
|
||||
plugin_state->automation_method |= scene_state->badbt_enabled ? AutomationMethodBadBt :
|
||||
AutomationMethodNone;
|
||||
#endif
|
||||
plugin_state->selected_font = scene_state->selected_font;
|
||||
|
||||
plugin_state->active_font_index = scene_state->active_font;
|
||||
|
||||
if(!totp_config_file_update_user_settings(plugin_state)) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#include <notification/notification_messages.h>
|
||||
#include <totp_icons.h>
|
||||
#include <roll_value.h>
|
||||
#include <available_fonts.h>
|
||||
#include "totp_scene_generate_token.h"
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../types/common.h"
|
||||
#include "../../constants.h"
|
||||
@@ -16,7 +18,6 @@
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
#include "../../fonts/active_font.h"
|
||||
|
||||
#define PROGRESS_BAR_MARGIN (3)
|
||||
#define PROGRESS_BAR_HEIGHT (4)
|
||||
@@ -26,18 +27,18 @@ typedef struct {
|
||||
uint8_t progress_bar_width;
|
||||
uint8_t code_total_length;
|
||||
uint8_t code_offset_x;
|
||||
uint8_t code_offset_x_inc;
|
||||
uint8_t code_offset_y;
|
||||
} UiPrecalculatedDimensions;
|
||||
|
||||
typedef struct {
|
||||
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
||||
char last_code[TokenDigitsCountMax + 1];
|
||||
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
||||
NotificationMessage const** notification_sequence_new_token;
|
||||
NotificationMessage const** notification_sequence_automation;
|
||||
FuriMutex* last_code_update_sync;
|
||||
TotpGenerateCodeWorkerContext* generate_code_worker_context;
|
||||
UiPrecalculatedDimensions ui_precalculated_dimensions;
|
||||
const FONT_INFO* active_font;
|
||||
} SceneState;
|
||||
|
||||
static const NotificationSequence*
|
||||
@@ -141,60 +142,14 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
|
||||
const TokenInfoIteratorContext* iterator_context =
|
||||
totp_config_get_token_iterator_context(plugin_state);
|
||||
uint8_t code_length = totp_token_info_iterator_get_current_token(iterator_context)->digits;
|
||||
uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x;
|
||||
const FONT_INFO* current_font;
|
||||
switch(plugin_state->selected_font) {
|
||||
case 0:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
case 1:
|
||||
current_font = &redHatMono_16ptFontInfo;
|
||||
break;
|
||||
case 2:
|
||||
current_font = &bedstead_17ptFontInfo;
|
||||
break;
|
||||
case 3:
|
||||
current_font = &zector_18ptFontInfo;
|
||||
break;
|
||||
case 4:
|
||||
current_font = &_712Serif_24ptFontInfo;
|
||||
break;
|
||||
case 5:
|
||||
current_font = &graph35pix_12ptFontInfo;
|
||||
break;
|
||||
case 6:
|
||||
current_font = &karmaFuture_14ptFontInfo;
|
||||
break;
|
||||
case 7:
|
||||
current_font = &funclimbingDemo_18ptFontInfo;
|
||||
break;
|
||||
case 8:
|
||||
current_font = &dPComic_18ptFontInfo;
|
||||
break;
|
||||
case 9:
|
||||
current_font = &pixelFlag_18ptFontInfo;
|
||||
break;
|
||||
default:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
}
|
||||
uint8_t char_width = current_font->charInfo[0].width;
|
||||
uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc;
|
||||
for(uint8_t i = 0; i < code_length; i++) {
|
||||
char ch = scene_state->last_code[i];
|
||||
if(ch >= current_font->startChar && ch <= current_font->endChar) {
|
||||
uint8_t char_index = ch - current_font->startChar;
|
||||
canvas_draw_xbm(
|
||||
canvas,
|
||||
offset_x,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y,
|
||||
char_width,
|
||||
current_font->height,
|
||||
¤t_font->data[current_font->charInfo[char_index].offset]);
|
||||
}
|
||||
|
||||
offset_x += offset_x_inc;
|
||||
}
|
||||
canvas_draw_str_ex(
|
||||
canvas,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y,
|
||||
scene_state->last_code,
|
||||
code_length,
|
||||
scene_state->active_font);
|
||||
}
|
||||
|
||||
static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
@@ -207,53 +162,15 @@ static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
const TokenInfo* current_token = totp_token_info_iterator_get_current_token(iterator_context);
|
||||
const FONT_INFO* const font = scene_state->active_font;
|
||||
|
||||
const FONT_INFO* current_font;
|
||||
switch(plugin_state->selected_font) {
|
||||
case 0:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
case 1:
|
||||
current_font = &redHatMono_16ptFontInfo;
|
||||
break;
|
||||
case 2:
|
||||
current_font = &bedstead_17ptFontInfo;
|
||||
break;
|
||||
case 3:
|
||||
current_font = &zector_18ptFontInfo;
|
||||
break;
|
||||
case 4:
|
||||
current_font = &_712Serif_24ptFontInfo;
|
||||
break;
|
||||
case 5:
|
||||
current_font = &graph35pix_12ptFontInfo;
|
||||
break;
|
||||
case 6:
|
||||
current_font = &karmaFuture_14ptFontInfo;
|
||||
break;
|
||||
case 7:
|
||||
current_font = &funclimbingDemo_18ptFontInfo;
|
||||
break;
|
||||
case 8:
|
||||
current_font = &dPComic_18ptFontInfo;
|
||||
break;
|
||||
case 9:
|
||||
current_font = &pixelFlag_18ptFontInfo;
|
||||
break;
|
||||
default:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t char_width = current_font->charInfo[0].width;
|
||||
uint8_t char_width = font->charInfo[0].width;
|
||||
scene_state->ui_precalculated_dimensions.code_total_length =
|
||||
current_token->digits * (char_width + current_font->spacePixels);
|
||||
current_token->digits * (char_width + font->spacePixels);
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x =
|
||||
(SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1;
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x_inc =
|
||||
char_width + current_font->spacePixels;
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y =
|
||||
SCREEN_HEIGHT_CENTER - (current_font->height >> 1);
|
||||
SCREEN_HEIGHT_CENTER - (font->height >> 1);
|
||||
|
||||
if(time_left) {
|
||||
notification_message(
|
||||
@@ -283,11 +200,11 @@ 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,
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
scene_state->last_code, TokenDigitsCountMax + 1, scene_state->last_code_update_sync);
|
||||
}
|
||||
|
||||
scene_state->active_font = available_fonts[plugin_state->active_font_index];
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
@@ -297,7 +214,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
totp_bt_type_code_worker_start(
|
||||
plugin_state->bt_type_code_worker_context,
|
||||
scene_state->last_code,
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
TokenDigitsCountMax + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "bt_type_code.h"
|
||||
#include <furi_hal_bt.h>
|
||||
#include <furi_hal_bt_hid.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include <bt/bt_service/bt_i.h>
|
||||
#include <furi/core/thread.h>
|
||||
#include <furi/core/mutex.h>
|
||||
#include <furi/core/string.h>
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../type_code_common.h"
|
||||
#include "../../features_config.h"
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH
|
||||
#define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
||||
#endif
|
||||
@@ -29,7 +29,7 @@ struct TotpBtTypeCodeWorkerContext {
|
||||
Bt* bt;
|
||||
bool is_advertising;
|
||||
bool is_connected;
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN];
|
||||
uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
||||
#endif
|
||||
@@ -39,7 +39,7 @@ static inline bool totp_type_code_worker_stop_requested() {
|
||||
return furi_thread_flags_get() & TotpBtTypeCodeWorkerEventStop;
|
||||
}
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||
uint8_t max_i;
|
||||
size_t uid_size = furi_hal_version_uid_size();
|
||||
@@ -49,7 +49,7 @@ static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||
max_i = TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN;
|
||||
}
|
||||
|
||||
const uint8_t* uid = furi_hal_version_uid();
|
||||
const uint8_t* uid = (const uint8_t*)UID64_BASE; //-V566
|
||||
memcpy(mac, uid, max_i);
|
||||
for(uint8_t i = max_i; i < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN; i++) {
|
||||
mac[i] = 0;
|
||||
@@ -161,7 +161,7 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
memcpy(
|
||||
&context->previous_bt_name[0],
|
||||
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
||||
@@ -184,7 +184,7 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
|
||||
furi_hal_bt_start_advertising();
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
bt_enable_peer_key_update(context->bt);
|
||||
#endif
|
||||
|
||||
@@ -211,7 +211,7 @@ void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_default_path(context->bt);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, context->previous_bt_name);
|
||||
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->previous_bt_mac);
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@ struct TotpGenerateCodeWorkerContext {
|
||||
void* on_code_lifetime_changed_handler_context;
|
||||
};
|
||||
|
||||
static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
static const char STEAM_ALGO_ALPHABET[] = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
|
||||
static void
|
||||
int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) {
|
||||
@@ -30,7 +30,7 @@ static void
|
||||
if(i_token_code == OTP_ERROR) {
|
||||
memset(str, '-', len);
|
||||
} else {
|
||||
if(algo == STEAM) {
|
||||
if(algo == TokenHashAlgoSteam) {
|
||||
char* s = str;
|
||||
for(uint8_t i = 0; i < len; i++, s++) {
|
||||
*s = STEAM_ALGO_ALPHABET[i_token_code % 26];
|
||||
@@ -48,12 +48,12 @@ static void
|
||||
|
||||
static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||
switch(algo) {
|
||||
case SHA1:
|
||||
case STEAM:
|
||||
case TokenHashAlgoSha1:
|
||||
case TokenHashAlgoSteam:
|
||||
return TOTP_ALGO_SHA1;
|
||||
case SHA256:
|
||||
case TokenHashAlgoSha256:
|
||||
return TOTP_ALGO_SHA256;
|
||||
case SHA512:
|
||||
case TokenHashAlgoSha512:
|
||||
return TOTP_ALGO_SHA512;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -11,7 +11,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
||||
|
||||
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/projectors.ir"));
|
||||
//TODO Improve Projectors universal remote
|
||||
button_panel_reserve(button_panel, 2, 2);
|
||||
button_panel_reserve(button_panel, 2, 3);
|
||||
uint32_t i = 0;
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
@@ -61,6 +61,30 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
101,
|
||||
&I_Play_25x27,
|
||||
&I_Play_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Play");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
1,
|
||||
2,
|
||||
36,
|
||||
101,
|
||||
&I_Pause_25x27,
|
||||
&I_Pause_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
||||
|
||||
button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector");
|
||||
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 14th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
# Model: Electrolux EACM-16 HP/N3
|
||||
name: Off
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 13th Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
@@ -3728,3 +3728,27 @@ type: parsed
|
||||
protocol: RC5
|
||||
address: 15 00 00 00
|
||||
command: 35 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 18 00 00 00
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 1D 00 00 00
|
||||
#
|
||||
name: Vol_up
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 12 00 00 00
|
||||
#
|
||||
name: Vol_dn
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 0A 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 13th Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: raw
|
||||
@@ -1881,3 +1881,33 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: 30 00 00 00
|
||||
command: 87 00 00 00
|
||||
#
|
||||
name: Power
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1255 435 1257 435 415 1278 1257 440 1256 435 415 1278 415 1278 415 1279 414 1279 414 1279 414 1278 1257 7176 1257 436 1256 435 415 1279 1256 438 1258 437 413 1279 414 1278 415 1278 415 1279 414 1279 414 1278 1257 7174 1256 436 1256 437 413 1278 1257 439 1257 435 415 1278 415 1278 415 1277 416 1279 414 1278 415 1278 1256 7175 1257 435 1257 435 415 1279 1256 440 1256 435 415 1278 415 1278 415 1278 415 1278 415 1280 413 1278 1257
|
||||
#
|
||||
name: Speed_up
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1284 409 1283 408 440 1253 1284 411 1285 407 441 1254 439 1253 440 1253 440 1251 442 1252 1285 409 439 7991 1285 409 1283 408 440 1253 1284 411 1285 407 441 1255 438 1253 440 1252 441 1251 442 1254 1283 407 441 7994 1283 410 1282 409 439 1254 1283 413 1283 409 439 1253 440 1253 440 1253 440 1253 440 1253 1284 407 441 7996 1284 409 1283 408 440 1253 1284 412 1284 408 440 1253 440 1253 440 1251 442 1253 440 1253 1284 409 439 7996 1284 407 1285 408 440 1254 1283 411 1285 409 439 1254 439 1253 440 1252 441 1253 440 1253 1284 408 440 7996 1284 408 1284 409 439 1255 1282 411 1285 408 440 1254 439 1252 441 1252 441 1254 439 1253 1284 407 441
|
||||
#
|
||||
name: Mode
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1251 439 1253 437 414 1282 1252 441 1255 436 415 1279 414 1280 413 1280 413 1279 1255 437 414 1279 414 8020 1253 438 1255 438 413 1281 1253 441 1255 438 413 1280 413 1279 414 1279 414 1280 1254 437 414 1280 413 8024 1253 438 1254 437 414 1281 1253 440 1256 437 414 1279 414 1279 414 1278 415 1280 1254 437 414 1280 413 8023 1254 440 1252 436 415 1279 1255 441 1255 436 415 1279 414 1279 414 1279 414 1279 1255 437 414 1279 414 8024 1253 437 1256 437 414 1280 1254 441 1255 437 414 1278 415 1280 413 1280 413 1280 1254 437 414 1279 414 8023 1254 438 1255 436 415 1280 1255 441 1255 436 415 1279 414 1279 414 1279 414 1280 1254 436 415 1280 413
|
||||
#
|
||||
name: Timer
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1252 437 1255 438 519 1174 1255 441 1255 437 518 1175 519 1173 520 1175 1253 437 518 1175 519 1175 518 7917 1253 438 1254 438 413 1281 1253 440 1256 437 414 1279 465 1228 465 1228 1254 436 415 1279 465 1227 466 7969 1253 438 1254 438 413 1280 1254 440 1256 436 415 1280 413 1278 466 1229 1254 437 414 1279 414 1278 415 8024 1252 437 1255 436 415 1279 1255 440 1256 437 414 1279 414 1279 414 1279 1255 437 414 1279 414 1278 415
|
||||
#
|
||||
name: Rotate
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1253 434 1258 435 492 1200 1258 438 1258 434 498 1194 494 1202 1257 433 494 1200 493 1200 493 1200 493 7940 1259 434 1258 433 493 1200 1259 438 1258 433 493 1199 494 1200 1259 434 492 1200 493 1200 493 1199 494 7939 1258 435 1257 434 497 1196 1258 437 1259 433 498 1196 492 1201 1258 434 497 1197 491 1200 493 1201 492 7941 1258 434 1258 435 495 1197 1258 437 1259 433 497 1197 497 1196 1259 434 496 1197 496 1197 496 1196 497 7939 1258 435 1257 434 495 1198 1258 438 1258 434 495 1198 495 1199 1257 435 494 1199 494 1197 496 1197 496
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 16th Jun, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
# ON
|
||||
name: Power
|
||||
@@ -988,3 +988,93 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: 02 00 00 00
|
||||
command: 11 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 87 4E 00 00
|
||||
command: 51 AE 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 30 00 00
|
||||
command: A8 57 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 30 00 00
|
||||
command: A9 56 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 83 55 00 00
|
||||
command: 5E A1 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 83 55 00 00
|
||||
command: 5B A4 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 00 00 00 00
|
||||
command: 93 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 00 00 00 00
|
||||
command: 93 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 15 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 15 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: B8 57 00 00
|
||||
command: 18 E7 00 00
|
||||
#
|
||||
name: Play
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.33
|
||||
data: 8981 4411 532 1616 557 1592 557 465 556 465 556 466 555 467 554 468 554 1595 554 467 554 468 554 1595 554 467 580 1569 581 1568 581 1568 581 1569 580 441 581 1569 580 442 580 1570 579 1594 555 467 555 443 579 442 580 1594 554 467 555 1594 555 467 555 468 554 1595 554 1595 528 1620 529 42169 9008 2106 531
|
||||
#
|
||||
name: Pause
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.33
|
||||
data: 8981 4411 532 1616 557 1592 557 465 556 465 556 466 555 467 554 468 554 1595 554 467 554 468 554 1595 554 467 580 1569 581 1568 581 1568 581 1569 580 441 581 1569 580 442 580 1570 579 1594 555 467 555 443 579 442 580 1594 554 467 555 1594 555 467 555 468 554 1595 554 1595 528 1620 529 42169 9008 2106 531
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 31 00 00 00
|
||||
command: 41 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 31 00 00 00
|
||||
command: 41 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 03 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
@@ -2307,3 +2307,41 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1119 528 675 1154 647 558 674 841 675 1153 675 531 673 532 673 843 673 1155 675 1153 674 531 673 12312 1120 505 672 1156 673 532 673 844 673 1155 673 532 671 534 672 842 675 1155 670 1158 673 530 674 12312 1093 532 671 1156 675 530 672 845 672 1156 673 533 671 533 670 846 672 1156 674 1154 674 529 675 12312 1093 557 646 1182 646 532 674 843 673 1181 646 534 672 532 674 842 673 1158 670 1156 674 530 673 12315 1091 530 674 1155 673 530 673 844 673 1157 644 559 673 532 672 844 670 1157 672 1158 672 532 672 12313 1093 533 671 1157 672 532 673 845 671 1157 670 558 647 532 646 871 672 1157 671 1181 646 534 671
|
||||
#
|
||||
# Daewoo TV
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 82 00 00 00
|
||||
#
|
||||
name: Vol_up
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 9F 00 00 00
|
||||
#
|
||||
name: Vol_dn
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 8B 00 00 00
|
||||
#
|
||||
name: Ch_next
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 9B 00 00 00
|
||||
#
|
||||
name: Ch_prev
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 8F 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: D0 00 00 00
|
||||
|
||||
Reference in New Issue
Block a user