From 3c75356b497222d9eca7c95896a1693296b2c558 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Sat, 7 Sep 2024 20:12:06 +0900 Subject: [PATCH 1/5] Fix detection of GProx II cards and false detection of other cards (#3869) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix detection of GProx II cards and false detection of other cards as GProx II * Fix incorrect parity starting bit Co-authored-by: あく --- lib/lfrfid/protocols/protocol_gproxii.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/lfrfid/protocols/protocol_gproxii.c b/lib/lfrfid/protocols/protocol_gproxii.c index 73cbe8f39..999e965ec 100644 --- a/lib/lfrfid/protocols/protocol_gproxii.c +++ b/lib/lfrfid/protocols/protocol_gproxii.c @@ -39,11 +39,12 @@ void protocol_gproxii_free(ProtocolGProxII* protocol) { } uint8_t* protocol_gproxii_get_data(ProtocolGProxII* proto) { - return proto->data; + return proto->decoded_data; } void protocol_gproxii_decoder_start(ProtocolGProxII* protocol) { memset(protocol->data, 0, GPROXII_ENCODED_BYTE_FULL_SIZE); + memset(protocol->decoded_data, 0, GPROXII_DATA_SIZE); protocol->last_short = false; } @@ -88,8 +89,9 @@ static bool protocol_gproxii_can_be_decoded(ProtocolGProxII* protocol) { if(bit_lib_get_bits(protocol->data, 0, 6) != 0b111110) return false; // Check always 0 parity on every 5th bit after preamble - if(bit_lib_test_parity(protocol->data, 5, GPROXII_ENCODED_BIT_SIZE, BitLibParityAlways0, 5)) + if(!bit_lib_test_parity(protocol->data, 6, GPROXII_ENCODED_BIT_SIZE, BitLibParityAlways0, 5)) { return false; + } // Start GProx II decode bit_lib_copy_bits(protocol->decoded_data, 0, GPROXII_ENCODED_BIT_SIZE, protocol->data, 6); From 266d4b3234519cc7627194ef2e4ab76732013df5 Mon Sep 17 00:00:00 2001 From: porta Date: Sat, 7 Sep 2024 14:54:23 +0300 Subject: [PATCH 2/5] [FL-3897] Happy mode (#3863) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: happy mode * feat: remove sad dolphin when powering off in happy mode * style: address review comments * Dolphin: add missing furi_checks * Komi: add missing region initialization on startup Co-authored-by: あく --- applications/services/dolphin/dolphin.c | 33 +++++++++- applications/services/dolphin/dolphin.h | 8 +++ applications/services/dolphin/dolphin_i.h | 3 + .../services/dolphin/helpers/dolphin_state.h | 4 ++ .../desktop_settings/desktop_settings_app.c | 6 ++ .../desktop_settings/desktop_settings_app.h | 3 + .../desktop_settings_custom_event.h | 26 ++++++++ .../scenes/desktop_settings_scene_config.h | 2 + .../desktop_settings_scene_happy_mode.c | 64 +++++++++++++++++++ .../scenes/desktop_settings_scene_pin_auth.c | 19 +++--- .../desktop_settings_scene_pin_disable.c | 7 +- .../scenes/desktop_settings_scene_pin_error.c | 9 ++- .../scenes/desktop_settings_scene_pin_menu.c | 17 ++--- .../scenes/desktop_settings_scene_pin_setup.c | 25 ++++---- .../desktop_settings_scene_pin_setup_done.c | 7 +- .../desktop_settings_scene_pin_setup_howto.c | 7 +- .../desktop_settings_scene_pin_setup_howto2.c | 12 ++-- .../desktop_settings_scene_quick_apps_menu.c | 12 ++-- .../scenes/desktop_settings_scene_start.c | 9 ++- .../scenes/power_settings_scene_power_off.c | 21 ++++-- targets/f18/api_symbols.csv | 4 +- targets/f18/furi_hal/furi_hal.c | 1 + targets/f7/api_symbols.csv | 4 +- 23 files changed, 231 insertions(+), 72 deletions(-) create mode 100644 applications/settings/desktop_settings/desktop_settings_custom_event.h create mode 100644 applications/settings/desktop_settings/scenes/desktop_settings_scene_happy_mode.c diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index 501e37c3c..5d8dc61cb 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -47,6 +47,26 @@ void dolphin_deed(DolphinDeed deed) { furi_record_close(RECORD_DOLPHIN); } +void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings) { + furi_check(dolphin); + furi_check(settings); + + DolphinEvent event; + event.type = DolphinEventTypeSettingsGet; + event.settings = settings; + dolphin_event_send_wait(dolphin, &event); +} + +void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings) { + furi_check(dolphin); + furi_check(settings); + + DolphinEvent event; + event.type = DolphinEventTypeSettingsSet; + event.settings = settings; + dolphin_event_send_wait(dolphin, &event); +} + DolphinStats dolphin_stats(Dolphin* dolphin) { furi_check(dolphin); @@ -211,7 +231,9 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) { } else if(event.type == DolphinEventTypeStats) { event.stats->icounter = dolphin->state->data.icounter; - event.stats->butthurt = dolphin->state->data.butthurt; + event.stats->butthurt = (dolphin->state->data.flags & DolphinFlagHappyMode) ? + 0 : + dolphin->state->data.butthurt; event.stats->timestamp = dolphin->state->data.timestamp; event.stats->level = dolphin_get_level(dolphin->state->data.icounter); event.stats->level_up_is_pending = @@ -228,6 +250,15 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) { dolphin_state_load(dolphin->state); furi_event_loop_timer_start(dolphin->butthurt_timer, BUTTHURT_INCREASE_PERIOD_TICKS); + } else if(event.type == DolphinEventTypeSettingsGet) { + event.settings->happy_mode = dolphin->state->data.flags & DolphinFlagHappyMode; + + } else if(event.type == DolphinEventTypeSettingsSet) { + dolphin->state->data.flags &= ~DolphinFlagHappyMode; + if(event.settings->happy_mode) dolphin->state->data.flags |= DolphinFlagHappyMode; + dolphin->state->dirty = true; + dolphin_state_save(dolphin->state); + } else { furi_crash(); } diff --git a/applications/services/dolphin/dolphin.h b/applications/services/dolphin/dolphin.h index 01da7f3f2..95f851a51 100644 --- a/applications/services/dolphin/dolphin.h +++ b/applications/services/dolphin/dolphin.h @@ -21,6 +21,10 @@ typedef struct { bool level_up_is_pending; } DolphinStats; +typedef struct { + bool happy_mode; +} DolphinSettings; + typedef enum { DolphinPubsubEventUpdate, } DolphinPubsubEvent; @@ -31,6 +35,10 @@ typedef enum { */ void dolphin_deed(DolphinDeed deed); +void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings); + +void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings); + /** Retrieve dolphin stats * Thread safe, blocking */ diff --git a/applications/services/dolphin/dolphin_i.h b/applications/services/dolphin/dolphin_i.h index 6a6b3dfd8..8e8d40825 100644 --- a/applications/services/dolphin/dolphin_i.h +++ b/applications/services/dolphin/dolphin_i.h @@ -13,6 +13,8 @@ typedef enum { DolphinEventTypeFlush, DolphinEventTypeLevel, DolphinEventTypeReloadState, + DolphinEventTypeSettingsGet, + DolphinEventTypeSettingsSet, } DolphinEventType; typedef struct { @@ -21,6 +23,7 @@ typedef struct { union { DolphinDeed deed; DolphinStats* stats; + DolphinSettings* settings; }; } DolphinEvent; diff --git a/applications/services/dolphin/helpers/dolphin_state.h b/applications/services/dolphin/helpers/dolphin_state.h index bdbd98d47..23a7d7b5f 100644 --- a/applications/services/dolphin/helpers/dolphin_state.h +++ b/applications/services/dolphin/helpers/dolphin_state.h @@ -5,6 +5,10 @@ #include "dolphin_deed.h" +typedef enum { + DolphinFlagHappyMode = 1, +} DolphinFlags; + typedef struct DolphinState DolphinState; typedef struct { uint8_t icounter_daily_limit[DolphinAppMAX]; diff --git a/applications/settings/desktop_settings/desktop_settings_app.c b/applications/settings/desktop_settings/desktop_settings_app.c index ab7782a7c..e8bc89957 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.c +++ b/applications/settings/desktop_settings/desktop_settings_app.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -42,6 +43,7 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) { app->pin_input_view = desktop_view_pin_input_alloc(); app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc(); app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc(); + app->dialog_ex = dialog_ex_alloc(); view_dispatcher_add_view( app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu)); @@ -63,6 +65,8 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) { app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2, desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view)); + view_dispatcher_add_view( + app->view_dispatcher, DesktopSettingsAppViewDialogEx, dialog_ex_get_view(app->dialog_ex)); return app; } @@ -75,12 +79,14 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2); + view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx); variable_item_list_free(app->variable_item_list); submenu_free(app->submenu); popup_free(app->popup); desktop_view_pin_input_free(app->pin_input_view); desktop_settings_view_pin_setup_howto_free(app->pin_setup_howto_view); desktop_settings_view_pin_setup_howto2_free(app->pin_setup_howto2_view); + dialog_ex_free(app->dialog_ex); // View dispatcher view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); diff --git a/applications/settings/desktop_settings/desktop_settings_app.h b/applications/settings/desktop_settings/desktop_settings_app.h index 348180fbf..18bc9fa28 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.h +++ b/applications/settings/desktop_settings/desktop_settings_app.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,7 @@ typedef enum { DesktopSettingsAppViewIdPinInput, DesktopSettingsAppViewIdPinSetupHowto, DesktopSettingsAppViewIdPinSetupHowto2, + DesktopSettingsAppViewDialogEx, } DesktopSettingsAppView; typedef struct { @@ -36,6 +38,7 @@ typedef struct { DesktopViewPinInput* pin_input_view; DesktopSettingsViewPinSetupHowto* pin_setup_howto_view; DesktopSettingsViewPinSetupHowto2* pin_setup_howto2_view; + DialogEx* dialog_ex; DesktopPinCode pincode_buffer; bool pincode_buffer_filled; diff --git a/applications/settings/desktop_settings/desktop_settings_custom_event.h b/applications/settings/desktop_settings/desktop_settings_custom_event.h new file mode 100644 index 000000000..87978069e --- /dev/null +++ b/applications/settings/desktop_settings/desktop_settings_custom_event.h @@ -0,0 +1,26 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + // reserve 100 for button presses, submenu selections, etc. + DesktopSettingsCustomEventExit = 100, + DesktopSettingsCustomEventDone, + + DesktopSettingsCustomEvent1stPinEntered, + DesktopSettingsCustomEventPinsEqual, + DesktopSettingsCustomEventPinsDifferent, + + DesktopSettingsCustomEventSetPin, + DesktopSettingsCustomEventChangePin, + DesktopSettingsCustomEventDisablePin, + + DesktopSettingsCustomEventSetDefault, + DesktopSettingsCustomEventSetDummy, +} DesktopSettingsCustomEvent; + +#ifdef __cplusplus +} +#endif diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h b/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h index 4a1d03701..37d845625 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h @@ -12,3 +12,5 @@ ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone) ADD_SCENE(desktop_settings, quick_apps_menu, QuickAppsMenu) ADD_SCENE(desktop_settings, quick_apps_direction_menu, QuickAppsDirectionMenu) + +ADD_SCENE(desktop_settings, happy_mode, HappyMode) diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_happy_mode.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_happy_mode.c new file mode 100644 index 000000000..31fcbfd2a --- /dev/null +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_happy_mode.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include + +#include "desktop_settings_scene.h" +#include "../desktop_settings_app.h" +#include "../desktop_settings_custom_event.h" + +static void desktop_settings_scene_happy_mode_done_callback(DialogExResult result, void* context) { + DesktopSettingsApp* app = context; + DolphinSettings settings; + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + dolphin_get_settings(dolphin, &settings); + settings.happy_mode = (result == DialogExResultRight); + dolphin_set_settings(dolphin, &settings); + furi_record_close(RECORD_DOLPHIN); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); +} + +void desktop_settings_scene_happy_mode_on_enter(void* context) { + DesktopSettingsApp* app = context; + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + DolphinSettings settings; + dolphin_get_settings(dolphin, &settings); + furi_record_close(RECORD_DOLPHIN); + + dialog_ex_set_header(app->dialog_ex, "Happy Mode", 64, 0, AlignCenter, AlignTop); + dialog_ex_set_text( + app->dialog_ex, + "I will never get angry at you\nfor not spending time with me\nas long as this mode is enabled", + 64, + 30, + AlignCenter, + AlignCenter); + dialog_ex_set_left_button_text(app->dialog_ex, settings.happy_mode ? "Disable" : "Go back"); + dialog_ex_set_right_button_text( + app->dialog_ex, settings.happy_mode ? "Keep enabled" : "Enable"); + dialog_ex_set_result_callback(app->dialog_ex, desktop_settings_scene_happy_mode_done_callback); + dialog_ex_set_context(app->dialog_ex, app); + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx); +} + +bool desktop_settings_scene_happy_mode_on_event(void* context, SceneManagerEvent event) { + DesktopSettingsApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DesktopSettingsCustomEventExit: + scene_manager_previous_scene(app->scene_manager); + consumed = true; + break; + default: + furi_crash(); + } + } + return consumed; +} + +void desktop_settings_scene_happy_mode_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c index 1e6416531..0d1543359 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c @@ -3,15 +3,12 @@ #include #include #include "../desktop_settings_app.h" +#include "../desktop_settings_custom_event.h" #include #include #include "desktop_settings_scene.h" #include "desktop_settings_scene_i.h" -#define SCENE_EVENT_EXIT (0U) -#define SCENE_EVENT_PINS_EQUAL (1U) -#define SCENE_EVENT_PINS_DIFFERENT (2U) - static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context) { furi_assert(pin_code); furi_assert(context); @@ -20,15 +17,17 @@ static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context app->pincode_buffer = *pin_code; if(desktop_pin_code_check(pin_code)) { - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL); + view_dispatcher_send_custom_event( + app->view_dispatcher, DesktopSettingsCustomEventPinsEqual); } else { - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT); + view_dispatcher_send_custom_event( + app->view_dispatcher, DesktopSettingsCustomEventPinsDifferent); } } static void pin_auth_back_callback(void* context) { DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_auth_on_enter(void* context) { @@ -54,13 +53,13 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_PINS_DIFFERENT: + case DesktopSettingsCustomEventPinsDifferent: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppScenePinError, SCENE_STATE_PIN_ERROR_WRONG); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError); consumed = true; break; - case SCENE_EVENT_PINS_EQUAL: { + case DesktopSettingsCustomEventPinsEqual: { uint32_t state = scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinAuth); if(state == SCENE_STATE_PIN_AUTH_CHANGE_PIN) { @@ -73,7 +72,7 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e consumed = true; break; } - case SCENE_EVENT_EXIT: + case DesktopSettingsCustomEventExit: scene_manager_search_and_switch_to_previous_scene( app->scene_manager, DesktopSettingsAppScenePinMenu); consumed = true; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index abcce66da..a97ce8aaa 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -3,15 +3,14 @@ #include #include "../desktop_settings_app.h" +#include "../desktop_settings_custom_event.h" #include #include "desktop_settings_scene.h" -#define SCENE_EVENT_EXIT (0U) - static void pin_disable_back_callback(void* context) { furi_assert(context); DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_disable_on_enter(void* context) { @@ -35,7 +34,7 @@ bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEven if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_EXIT: + case DesktopSettingsCustomEventExit: scene_manager_search_and_switch_to_previous_scene( app->scene_manager, DesktopSettingsAppScenePinMenu); consumed = true; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c index 711683c3f..695f431a0 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c @@ -8,20 +8,19 @@ #include "desktop_settings_scene_i.h" #include #include "../desktop_settings_app.h" - -#define SCENE_EVENT_EXIT (0U) +#include "../desktop_settings_custom_event.h" static void pin_error_back_callback(void* context) { furi_assert(context); DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } static void pin_error_done_callback(const DesktopPinCode* pin_code, void* context) { UNUSED(pin_code); furi_assert(context); DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_error_on_enter(void* context) { @@ -55,7 +54,7 @@ bool desktop_settings_scene_pin_error_on_event(void* context, SceneManagerEvent if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_EXIT: + case DesktopSettingsCustomEventExit: scene_manager_previous_scene(app->scene_manager); consumed = true; break; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c index e0c66cb28..cf8436dc9 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c @@ -4,10 +4,7 @@ #include "../desktop_settings_app.h" #include "desktop_settings_scene.h" #include "desktop_settings_scene_i.h" - -#define SCENE_EVENT_SET_PIN 0 -#define SCENE_EVENT_CHANGE_PIN 1 -#define SCENE_EVENT_DISABLE_PIN 2 +#include "../desktop_settings_custom_event.h" static void desktop_settings_scene_pin_menu_submenu_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; @@ -23,7 +20,7 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) { submenu_add_item( submenu, "Set PIN", - SCENE_EVENT_SET_PIN, + DesktopSettingsCustomEventSetPin, desktop_settings_scene_pin_menu_submenu_callback, app); @@ -31,14 +28,14 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) { submenu_add_item( submenu, "Change PIN", - SCENE_EVENT_CHANGE_PIN, + DesktopSettingsCustomEventChangePin, desktop_settings_scene_pin_menu_submenu_callback, app); submenu_add_item( submenu, "Remove PIN", - SCENE_EVENT_DISABLE_PIN, + DesktopSettingsCustomEventDisablePin, desktop_settings_scene_pin_menu_submenu_callback, app); } @@ -54,11 +51,11 @@ bool desktop_settings_scene_pin_menu_on_event(void* context, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_SET_PIN: + case DesktopSettingsCustomEventSetPin: scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto); consumed = true; break; - case SCENE_EVENT_CHANGE_PIN: + case DesktopSettingsCustomEventChangePin: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppScenePinAuth, @@ -66,7 +63,7 @@ bool desktop_settings_scene_pin_menu_on_event(void* context, SceneManagerEvent e scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth); consumed = true; break; - case SCENE_EVENT_DISABLE_PIN: + case DesktopSettingsCustomEventDisablePin: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppScenePinAuth, SCENE_STATE_PIN_AUTH_DISABLE); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c index 08f5fcb3f..95f50d2e1 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c @@ -8,11 +8,7 @@ #include "desktop_settings_scene.h" #include "desktop_settings_scene_i.h" #include - -#define SCENE_EVENT_EXIT (0U) -#define SCENE_EVENT_1ST_PIN_ENTERED (1U) -#define SCENE_EVENT_PINS_EQUAL (2U) -#define SCENE_EVENT_PINS_DIFFERENT (3U) +#include "../desktop_settings_custom_event.h" static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) { furi_assert(pin_code); @@ -22,20 +18,23 @@ static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* contex if(!app->pincode_buffer_filled) { app->pincode_buffer = *pin_code; app->pincode_buffer_filled = true; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_1ST_PIN_ENTERED); + view_dispatcher_send_custom_event( + app->view_dispatcher, DesktopSettingsCustomEvent1stPinEntered); } else { app->pincode_buffer_filled = false; if(desktop_pin_code_is_equal(&app->pincode_buffer, pin_code)) { - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL); + view_dispatcher_send_custom_event( + app->view_dispatcher, DesktopSettingsCustomEventPinsEqual); } else { - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT); + view_dispatcher_send_custom_event( + app->view_dispatcher, DesktopSettingsCustomEventPinsDifferent); } } } static void pin_setup_back_callback(void* context) { DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_setup_on_enter(void* context) { @@ -60,7 +59,7 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_1ST_PIN_ENTERED: + case DesktopSettingsCustomEvent1stPinEntered: desktop_view_pin_input_set_label_button(app->pin_input_view, "OK"); desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL); desktop_view_pin_input_set_label_secondary( @@ -69,7 +68,7 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent desktop_view_pin_input_unlock_input(app->pin_input_view); consumed = true; break; - case SCENE_EVENT_PINS_DIFFERENT: + case DesktopSettingsCustomEventPinsDifferent: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppScenePinError, @@ -77,11 +76,11 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError); consumed = true; break; - case SCENE_EVENT_PINS_EQUAL: + case DesktopSettingsCustomEventPinsEqual: scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto2); consumed = true; break; - case SCENE_EVENT_EXIT: { + case DesktopSettingsCustomEventExit: { uint32_t scene_found; scene_found = scene_manager_search_and_switch_to_previous_scene( app->scene_manager, DesktopSettingsAppScenePinMenu); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c index aa3d2214e..ad5784b55 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c @@ -5,18 +5,17 @@ #include #include "../desktop_settings_app.h" +#include "../desktop_settings_custom_event.h" #include #include #include "desktop_settings_scene.h" -#define SCENE_EVENT_DONE (0U) - static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) { furi_assert(pin_code); furi_assert(context); DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_DONE); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventDone); } void desktop_settings_scene_pin_setup_done_on_enter(void* context) { @@ -48,7 +47,7 @@ bool desktop_settings_scene_pin_setup_done_on_event(void* context, SceneManagerE if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_DONE: { + case DesktopSettingsCustomEventDone: { bool scene_found = false; scene_found = scene_manager_search_and_switch_to_previous_scene( app->scene_manager, DesktopSettingsAppScenePinMenu); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c index 31eec3871..69cdcc074 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c @@ -5,12 +5,11 @@ #include "desktop_settings_scene.h" #include "../desktop_settings_app.h" #include "../views/desktop_settings_view_pin_setup_howto.h" - -#define SCENE_EXIT_EVENT (0U) +#include "../desktop_settings_custom_event.h" static void desktop_settings_scene_pin_lock_done_callback(void* context) { DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_setup_howto_on_enter(void* context) { @@ -27,7 +26,7 @@ bool desktop_settings_scene_pin_setup_howto_on_event(void* context, SceneManager if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EXIT_EVENT: + case DesktopSettingsCustomEventExit: scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetup); consumed = true; break; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c index efa39f1f0..c67ab4c79 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c @@ -4,18 +4,16 @@ #include "desktop_settings_scene.h" #include "../desktop_settings_app.h" #include "../views/desktop_settings_view_pin_setup_howto2.h" - -#define SCENE_EXIT_EVENT (0U) -#define SCENE_DONE_EVENT (1U) +#include "../desktop_settings_custom_event.h" static void desktop_settings_scene_pin_setup_howto2_done_callback(void* context) { DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_DONE_EVENT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventDone); } static void desktop_settings_scene_pin_setup_howto2_exit_callback(void* context) { DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT); + view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit); } void desktop_settings_scene_pin_setup_howto2_on_enter(void* context) { @@ -35,12 +33,12 @@ bool desktop_settings_scene_pin_setup_howto2_on_event(void* context, SceneManage if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_DONE_EVENT: { + case DesktopSettingsCustomEventDone: { scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupDone); consumed = true; break; } - case SCENE_EXIT_EVENT: { + case DesktopSettingsCustomEventExit: { bool scene_found = false; scene_found = scene_manager_search_and_switch_to_previous_scene( app->scene_manager, DesktopSettingsAppScenePinMenu); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_quick_apps_menu.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_quick_apps_menu.c index a7000204f..baaee5c1e 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_quick_apps_menu.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_quick_apps_menu.c @@ -2,12 +2,10 @@ #include #include "../desktop_settings_app.h" +#include "../desktop_settings_custom_event.h" #include "desktop_settings_scene.h" #include "desktop_settings_scene_i.h" -#define SCENE_EVENT_SET_DEFAULT (0U) -#define SCENE_EVENT_SET_DUMMY (1U) - static void desktop_settings_scene_quick_apps_menu_submenu_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; @@ -22,14 +20,14 @@ void desktop_settings_scene_quick_apps_menu_on_enter(void* context) { submenu_add_item( submenu, "Default Mode", - SCENE_EVENT_SET_DEFAULT, + DesktopSettingsCustomEventSetDefault, desktop_settings_scene_quick_apps_menu_submenu_callback, app); submenu_add_item( submenu, "Dummy Mode", - SCENE_EVENT_SET_DUMMY, + DesktopSettingsCustomEventSetDummy, desktop_settings_scene_quick_apps_menu_submenu_callback, app); @@ -44,7 +42,7 @@ bool desktop_settings_scene_quick_apps_menu_on_event(void* context, SceneManager if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_SET_DEFAULT: + case DesktopSettingsCustomEventSetDefault: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppSceneQuickAppsDirectionMenu, @@ -53,7 +51,7 @@ bool desktop_settings_scene_quick_apps_menu_on_event(void* context, SceneManager app->scene_manager, DesktopSettingsAppSceneQuickAppsDirectionMenu); consumed = true; break; - case SCENE_EVENT_SET_DUMMY: + case DesktopSettingsCustomEventSetDummy: scene_manager_set_scene_state( app->scene_manager, DesktopSettingsAppSceneQuickAppsDirectionMenu, diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index 7b3e5b96b..95bdcdf40 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -9,6 +9,7 @@ typedef enum { DesktopSettingsAutoLockDelay, DesktopSettingsClockDisplay, DesktopSettingsFavoriteApps, + DesktopSettingsHappyMode, } DesktopSettingsEntry; #define AUTO_LOCK_DELAY_COUNT 6 @@ -77,7 +78,7 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_list, "Show Clock", CLOCK_ENABLE_COUNT, - desktop_settings_scene_start_clock_enable_changed, // + desktop_settings_scene_start_clock_enable_changed, app); value_index = @@ -87,6 +88,8 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_list_add(variable_item_list, "Set Quick Access Apps", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Happy Mode", 1, NULL, NULL); + variable_item_list_set_enter_callback( variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); @@ -107,6 +110,10 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneQuickAppsMenu); break; + case DesktopSettingsHappyMode: + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneHappyMode); + break; + default: break; } diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c index 6cd9c5c67..6328a2381 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c @@ -1,4 +1,5 @@ #include "../power_settings_app.h" +#include void power_settings_scene_power_off_dialog_callback(DialogExResult result, void* context) { furi_assert(context); @@ -9,11 +10,23 @@ void power_settings_scene_power_off_dialog_callback(DialogExResult result, void* void power_settings_scene_power_off_on_enter(void* context) { PowerSettingsApp* app = context; DialogEx* dialog = app->dialog; + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + DolphinSettings settings; + dolphin_get_settings(dolphin, &settings); + furi_record_close(RECORD_DOLPHIN); - dialog_ex_set_header(dialog, "Turn Off Device?", 64, 0, AlignCenter, AlignTop); - dialog_ex_set_text( - dialog, " I will be\nwaiting for\n you here...", 78, 14, AlignLeft, AlignTop); - dialog_ex_set_icon(dialog, 14, 10, &I_dolph_cry_49x54); + dialog_ex_set_header( + dialog, + "Turn Off Device?", + 64, + settings.happy_mode ? 32 : 0, + AlignCenter, + settings.happy_mode ? AlignCenter : AlignTop); + if(!settings.happy_mode) { + dialog_ex_set_text( + dialog, " I will be\nwaiting for\n you here...", 78, 14, AlignLeft, AlignTop); + dialog_ex_set_icon(dialog, 14, 10, &I_dolph_cry_49x54); + } dialog_ex_set_left_button_text(dialog, "Cancel"); dialog_ex_set_right_button_text(dialog, "Power Off"); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 12e5b97e1..7f3e2f396 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.3,, +Version,+,72.4,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/cli/cli.h,, @@ -869,6 +869,8 @@ Function,+,dolphin_deed_get_app_limit,uint8_t,DolphinApp Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed Function,+,dolphin_flush,void,Dolphin* Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin* +Function,+,dolphin_get_settings,void,"Dolphin*, DolphinSettings*" +Function,+,dolphin_set_settings,void,"Dolphin*, DolphinSettings*" Function,+,dolphin_stats,DolphinStats,Dolphin* Function,+,dolphin_upgrade_level,void,Dolphin* Function,-,dprintf,int,"int, const char*, ..." diff --git a/targets/f18/furi_hal/furi_hal.c b/targets/f18/furi_hal/furi_hal.c index 247c2ee2d..b28606921 100644 --- a/targets/f18/furi_hal/furi_hal.c +++ b/targets/f18/furi_hal/furi_hal.c @@ -40,6 +40,7 @@ void furi_hal_init(void) { furi_hal_interrupt_init(); furi_hal_flash_init(); furi_hal_resources_init(); + furi_hal_region_init(); furi_hal_spi_config_init(); furi_hal_spi_dma_init(); furi_hal_speaker_init(); diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 850c84fe0..c6f44f914 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.3,, +Version,+,72.4,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, @@ -956,6 +956,8 @@ Function,+,dolphin_deed_get_app_limit,uint8_t,DolphinApp Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed Function,+,dolphin_flush,void,Dolphin* Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin* +Function,+,dolphin_get_settings,void,"Dolphin*, DolphinSettings*" +Function,+,dolphin_set_settings,void,"Dolphin*, DolphinSettings*" Function,+,dolphin_stats,DolphinStats,Dolphin* Function,+,dolphin_upgrade_level,void,Dolphin* Function,-,dprintf,int,"int, const char*, ..." From 9bdf41d8ff5b769b02ce6e7240471d9475a3816e Mon Sep 17 00:00:00 2001 From: Thomas Nemer <80506610+thomasnemer@users.noreply.github.com> Date: Sat, 7 Sep 2024 14:25:13 +0200 Subject: [PATCH 3/5] feat: add linux/gnome badusb demo resource files (#3846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add linux/gnome badusb demo resource files * doc: use latest appimage package and install icon and desktop file Co-authored-by: Thomas N Co-authored-by: あく --- .../badusb/Install_qFlipper_gnome.txt | 51 +++++++++++ .../bad_usb/resources/badusb/demo_gnome.txt | 87 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 applications/main/bad_usb/resources/badusb/Install_qFlipper_gnome.txt create mode 100644 applications/main/bad_usb/resources/badusb/demo_gnome.txt diff --git a/applications/main/bad_usb/resources/badusb/Install_qFlipper_gnome.txt b/applications/main/bad_usb/resources/badusb/Install_qFlipper_gnome.txt new file mode 100644 index 000000000..ec2ec108e --- /dev/null +++ b/applications/main/bad_usb/resources/badusb/Install_qFlipper_gnome.txt @@ -0,0 +1,51 @@ +ID 1234:abcd Generic:USB Keyboard +REM Declare ourselves as a generic usb keyboard + +REM This will install qFlipper on Linux/Gnome, using the latest AppImage package + +REM Open a terminal +ALT F2 +DELAY 1000 +STRINGLN gnome-terminal --maximize +DELAY 1000 + +REM Ensure we have a folder to run executables from +STRINGLN mkdir -p $HOME/.local/bin + +REM Download the latest AppImage +STRINGLN curl -fsSL "https://update.flipperzero.one/qFlipper/release/linux-amd64/AppImage" -o "$HOME/.local/bin/qFlipper" +DELAY 1000 + +REM Make it executable +STRINGLN chmod +x $HOME/.local/bin/qFlipper + +REM Extract the appimage in /tmp to install icon and .desktop file +STRINGLN cd /tmp +STRINGLN $HOME/.local/bin/qFlipper --appimage-extract > /dev/null +STRINGLN sed "s@Exec=qFlipper@Exec=$HOME/.local/bin/qFlipper@" squashfs-root/usr/share/applications/qFlipper.desktop > $HOME/.local/share/applications/qFlipper.desktop +STRINGLN mkdir -p $HOME/.local/share/icons/hicolor/512x512/apps +STRINGLN cp squashfs-root/usr/share/icons/hicolor/512x512/apps/qFlipper.png $HOME/.local/share/icons/hicolor/512x512/apps/qFlipper.png +STRINGLN rm -rf squashfs-root +STRINGLN cd + +REM Depending on the Linux distribution and display manager +REM there might be several ways to update desktop entries +REM try all +STRINGLN xdg-desktop-menu forceupdate || true +STRINGLN update-desktop-database ~/.local/share/applications || true + +STRINGLN echo " +ENTER +REPEAT 60 +STRINGLN ========================================================================================== +STRINGLN qFlipper has been installed to $HOME/.local/bin/ +STRINGLN It should appear in your Applications menu. +STRINGLN If it does not, you might want to log out and log in again. +ENTER +STRINGLN If you prefer to run qFlipper from your terminal, either use the absolute path +STRINGLN or make sure $HOME/.local/bin/ is included in your PATH environment variable. +ENTER +STRINGLN Additional configurations might be required by your Linux distribution such as +STRINGLN group membership, udev rules or else. +STRINGLN ========================================================================================== +STRINGLN " diff --git a/applications/main/bad_usb/resources/badusb/demo_gnome.txt b/applications/main/bad_usb/resources/badusb/demo_gnome.txt new file mode 100644 index 000000000..7d91de412 --- /dev/null +++ b/applications/main/bad_usb/resources/badusb/demo_gnome.txt @@ -0,0 +1,87 @@ +ID 1234:abcd Generic:USB Keyboard +REM Declare ourselves as a generic usb keyboard +REM You can override this to use something else +REM Check the `lsusb` command to know your own devices IDs + +REM This is BadUSB demo script for Linux/Gnome + +REM Open terminal window +DELAY 1000 +ALT F2 +DELAY 500 +STRING gnome-terminal --maximize +DELAY 500 +ENTER +DELAY 750 + +REM Clear the screen in case some banner was displayed +STRING clear +ENTER + +REM Bigger shell script example +STRING cat > /dev/null << EOF +ENTER + +STRING Hello World! +ENTER + +DEFAULT_DELAY 50 + +STRING = +REPEAT 59 +ENTER +ENTER + +STRING _.-------.._ -, +ENTER +HOME +STRING .-"'''"--..,,_/ /'-, -, \ +ENTER +HOME +STRING .:" /:/ /'\ \ ,_..., '. | | +ENTER +HOME +STRING / ,----/:/ /'\ _\~'_-"' _; +ENTER +HOME +STRING ' / /'"""'\ \ \.~'_-' ,-"'/ +ENTER +HOME +STRING | | | 0 | | .-' ,/' / +ENTER +HOME +STRING | ,..\ \ ,.-"' ,/' / +ENTER +HOME +STRING ; : '/'""\' ,/--==,/-----, +ENTER +HOME +STRING | '-...| -.___-Z:_______J...---; +ENTER +HOME +STRING : ' _-' +ENTER +HOME +STRING _L_ _ ___ ___ ___ ___ ____--"' +ENTER +HOME +STRING | __|| | |_ _|| _ \| _ \| __|| _ \ +ENTER +HOME +STRING | _| | |__ | | | _/| _/| _| | / +ENTER +HOME +STRING |_| |____||___||_| |_| |___||_|_\ +ENTER +HOME +ENTER + +STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format +ENTER +STRING More information about script syntax can be found here: +ENTER +STRING https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md +ENTER + +STRING EOF +ENTER From 8672a1d94cfe891c37d8f05a5a2cbc2d8a01e799 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 7 Sep 2024 18:16:56 +0200 Subject: [PATCH 4/5] Replace all calls to strncpy with strlcpy, use strdup more, expose strlcat (#3866) strlcpy doesn't zero the buffer and ensures null termination, just like snprintf strlcat is already used by mjs and it's a safe alternative to strcat, so it should be OK to expose to apps --- .../debug/rpc_debug_app/rpc_debug_app.c | 2 +- .../rpc_debug_app_scene_input_error_code.c | 2 +- .../rpc_debug_app_scene_input_error_text.c | 2 +- ...pc_debug_app_scene_receive_data_exchange.c | 2 +- .../examples/example_thermo/example_thermo.c | 2 +- applications/main/ibutton/ibutton.c | 4 +-- applications/main/ibutton/ibutton_i.h | 4 +-- applications/main/infrared/infrared_app_i.h | 4 +-- .../scenes/infrared_scene_edit_rename.c | 4 +-- .../subghz/scenes/subghz_scene_save_name.c | 6 ++-- .../desktop/animations/animation_storage.c | 10 ++---- applications/services/rpc/rpc_storage.c | 4 +-- .../scenes/desktop_settings_scene_favorite.c | 4 +-- lib/mjs/common/frozen/frozen.c | 31 ++++++++++++------- lib/mjs/mjs_json.c | 3 +- targets/f18/api_symbols.csv | 4 +-- targets/f7/api_symbols.csv | 4 +-- targets/f7/furi_hal/furi_hal_version.c | 2 +- 18 files changed, 47 insertions(+), 47 deletions(-) diff --git a/applications/debug/rpc_debug_app/rpc_debug_app.c b/applications/debug/rpc_debug_app/rpc_debug_app.c index 1536b8918..1affeae29 100644 --- a/applications/debug/rpc_debug_app/rpc_debug_app.c +++ b/applications/debug/rpc_debug_app/rpc_debug_app.c @@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) { static void rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) { if(data == NULL || data_size == 0) { - strncpy(buf, "", buf_size); + strlcpy(buf, "", buf_size); return; } diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c index be7774881..09d58c2c9 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c @@ -26,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context) void rpc_debug_app_scene_input_error_code_on_enter(void* context) { RpcDebugApp* app = context; - strncpy(app->text_store, "666", TEXT_STORE_SIZE); + strlcpy(app->text_store, "666", TEXT_STORE_SIZE); text_input_set_header_text(app->text_input, "Enter error code"); text_input_set_validator( app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL); diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c index b07f8f4af..cca293b66 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c @@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context) void rpc_debug_app_scene_input_error_text_on_enter(void* context) { RpcDebugApp* app = context; - strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE); + strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE); text_input_set_header_text(app->text_input, "Enter error text"); text_input_set_result_callback( app->text_input, diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c index 10d5e36f6..686a6f95d 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c @@ -2,7 +2,7 @@ void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) { RpcDebugApp* app = context; - strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE); + strlcpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE); text_box_set_text(app->text_box, app->text_store); text_box_set_font(app->text_box, TextBoxFontHex); diff --git a/applications/examples/example_thermo/example_thermo.c b/applications/examples/example_thermo/example_thermo.c index 895f05ce7..e5af819e9 100644 --- a/applications/examples/example_thermo/example_thermo.c +++ b/applications/examples/example_thermo/example_thermo.c @@ -257,7 +257,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) { snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units); } else { /* Or show a message that no data is available */ - strncpy(text_store, "-- No data --", TEXT_STORE_SIZE); + strlcpy(text_store, "-- No data --", TEXT_STORE_SIZE); } canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store); diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 765d53612..eff44c6de 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -183,7 +183,7 @@ bool ibutton_load_key(iButton* ibutton, bool show_error) { FuriString* tmp = furi_string_alloc(); path_extract_filename(ibutton->file_path, tmp, true); - strncpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE); + strlcpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE); furi_string_free(tmp); } else if(show_error) { @@ -243,7 +243,7 @@ bool ibutton_delete_key(iButton* ibutton) { } void ibutton_reset_key(iButton* ibutton) { - memset(ibutton->key_name, 0, IBUTTON_KEY_NAME_SIZE + 1); + ibutton->key_name[0] = '\0'; furi_string_reset(ibutton->file_path); ibutton_key_reset(ibutton->key); } diff --git a/applications/main/ibutton/ibutton_i.h b/applications/main/ibutton/ibutton_i.h index fc2324c63..73f108080 100644 --- a/applications/main/ibutton/ibutton_i.h +++ b/applications/main/ibutton/ibutton_i.h @@ -32,7 +32,7 @@ #define IBUTTON_APP_FILENAME_PREFIX "iBtn" #define IBUTTON_APP_FILENAME_EXTENSION ".ibtn" -#define IBUTTON_KEY_NAME_SIZE 22 +#define IBUTTON_KEY_NAME_SIZE 23 typedef enum { iButtonWriteModeInvalid, @@ -56,7 +56,7 @@ struct iButton { iButtonWriteMode write_mode; FuriString* file_path; - char key_name[IBUTTON_KEY_NAME_SIZE + 1]; + char key_name[IBUTTON_KEY_NAME_SIZE]; Submenu* submenu; ByteInput* byte_input; diff --git a/applications/main/infrared/infrared_app_i.h b/applications/main/infrared/infrared_app_i.h index 721771ef0..692cc9671 100644 --- a/applications/main/infrared/infrared_app_i.h +++ b/applications/main/infrared/infrared_app_i.h @@ -43,8 +43,8 @@ #define INFRARED_TEXT_STORE_NUM 2 #define INFRARED_TEXT_STORE_SIZE 128 -#define INFRARED_MAX_BUTTON_NAME_LENGTH 22 -#define INFRARED_MAX_REMOTE_NAME_LENGTH 22 +#define INFRARED_MAX_BUTTON_NAME_LENGTH 23 +#define INFRARED_MAX_REMOTE_NAME_LENGTH 23 #define INFRARED_APP_FOLDER EXT_PATH("infrared") #define INFRARED_APP_EXTENSION ".ir" diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename.c b/applications/main/infrared/scenes/infrared_scene_edit_rename.c index 301e936d9..ea49080a1 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_rename.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_rename.c @@ -39,7 +39,7 @@ void infrared_scene_edit_rename_on_enter(void* context) { furi_check(current_button_index != InfraredButtonIndexNone); enter_name_length = INFRARED_MAX_BUTTON_NAME_LENGTH; - strncpy( + strlcpy( infrared->text_store[0], infrared_remote_get_signal_name(remote, current_button_index), enter_name_length); @@ -47,7 +47,7 @@ void infrared_scene_edit_rename_on_enter(void* context) { } else if(edit_target == InfraredEditTargetRemote) { text_input_set_header_text(text_input, "Name the remote"); enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH; - strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length); + strlcpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length); FuriString* folder_path; folder_path = furi_string_alloc(); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 08ba0ba82..cdf218aca 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -6,7 +6,7 @@ #include #include -#define MAX_TEXT_INPUT_LEN 22 +#define MAX_TEXT_INPUT_LEN 23 void subghz_scene_save_name_text_input_callback(void* context) { furi_assert(context); @@ -39,7 +39,7 @@ void subghz_scene_save_name_on_enter(void* context) { FuriString* dir_name = furi_string_alloc(); if(!subghz_path_is_file(subghz->file_path)) { - char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; + char file_name_buf[SUBGHZ_MAX_LEN_NAME]; name_generator_make_auto(file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX); @@ -62,7 +62,7 @@ void subghz_scene_save_name_on_enter(void* context) { furi_string_set(subghz->file_path, dir_name); } - strncpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); + strlcpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); text_input_set_header_text(text_input, "Name signal"); text_input_set_result_callback( text_input, diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index 9ee85727b..a05525776 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -52,8 +52,7 @@ static bool animation_storage_load_single_manifest_info( if(furi_string_cmp_str(read_string, name)) break; flipper_format_set_strict_mode(file, true); - manifest_info->name = malloc(furi_string_size(read_string) + 1); - strcpy((char*)manifest_info->name, furi_string_get_cstr(read_string)); + manifest_info->name = strdup(furi_string_get_cstr(read_string)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; manifest_info->min_butthurt = u32value; @@ -105,9 +104,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis storage_animation->manifest_info.name = NULL; if(!flipper_format_read_string(file, "Name", read_string)) break; - storage_animation->manifest_info.name = malloc(furi_string_size(read_string) + 1); - strcpy( - (char*)storage_animation->manifest_info.name, furi_string_get_cstr(read_string)); + storage_animation->manifest_info.name = strdup(furi_string_get_cstr(read_string)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; storage_animation->manifest_info.min_butthurt = u32value; @@ -401,8 +398,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo furi_string_replace_all(str, "\\n", "\n"); - FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(furi_string_size(str) + 1)); - strcpy((char*)bubble->bubble.text, furi_string_get_cstr(str)); + FURI_CONST_ASSIGN_PTR(bubble->bubble.text, strdup(furi_string_get_cstr(str))); if(!flipper_format_read_string(ff, "AlignH", str)) break; if(!animation_storage_cast_align(str, (Align*)&bubble->bubble.align_h)) break; diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index aedcf8c94..163535f9a 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -226,9 +226,7 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context) response.content.storage_list_response.file[i].data = NULL; response.content.storage_list_response.file[i].size = 0; response.content.storage_list_response.file[i].type = PB_Storage_File_FileType_DIR; - char* str = malloc(strlen(hard_coded_dirs[i]) + 1); - strcpy(str, hard_coded_dirs[i]); - response.content.storage_list_response.file[i].name = str; + response.content.storage_list_response.file[i].name = strdup(hard_coded_dirs[i]); } rpc_send_and_release(session, &response); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index 74d09b2ac..17ef88358 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -209,7 +209,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene - strncpy( + strlcpy( curr_favorite_app->name_or_path, furi_string_get_cstr(temp_path), sizeof(curr_favorite_app->name_or_path)); @@ -219,7 +219,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e size_t app_index = event.event - 2; const char* name = favorite_fap_get_app_name(app_index); if(name) - strncpy( + strlcpy( curr_favorite_app->name_or_path, name, sizeof(curr_favorite_app->name_or_path)); diff --git a/lib/mjs/common/frozen/frozen.c b/lib/mjs/common/frozen/frozen.c index 923e6a556..7646864c0 100644 --- a/lib/mjs/common/frozen/frozen.c +++ b/lib/mjs/common/frozen/frozen.c @@ -37,7 +37,7 @@ #ifdef _WIN32 #undef snprintf #undef vsnprintf -#define snprintf cs_win_snprintf +#define snprintf cs_win_snprintf #define vsnprintf cs_win_vsnprintf int cs_win_snprintf(char* str, size_t size, const char* format, ...); int cs_win_vsnprintf(char* str, size_t size, const char* format, va_list ap); @@ -150,7 +150,8 @@ static int json_isspace(int ch) { } static void json_skip_whitespaces(struct frozen* f) { - while(f->cur < f->end && json_isspace(*f->cur)) f->cur++; + while(f->cur < f->end && json_isspace(*f->cur)) + f->cur++; } static int json_cur(struct frozen* f) { @@ -263,15 +264,18 @@ static int json_parse_number(struct frozen* f) { f->cur += 2; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); - while(f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; + while(f->cur < f->end && json_isxdigit(f->cur[0])) + f->cur++; } else { EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + while(f->cur < f->end && json_isdigit(f->cur[0])) + f->cur++; if(f->cur < f->end && f->cur[0] == '.') { f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + while(f->cur < f->end && json_isdigit(f->cur[0])) + f->cur++; } if(f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { f->cur++; @@ -279,7 +283,8 @@ static int json_parse_number(struct frozen* f) { if((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + while(f->cur < f->end && json_isdigit(f->cur[0])) + f->cur++; } } json_truncate_path(f, fstate.path_len); @@ -639,8 +644,7 @@ int json_vprintf(struct json_out* out, const char* fmt, va_list xap) { int need_len, size = sizeof(buf); char fmt2[20]; va_list ap_copy; - strncpy(fmt2, fmt, n + 1 > (int)sizeof(fmt2) ? sizeof(fmt2) : (size_t)n + 1); - fmt2[n + 1] = '\0'; + strlcpy(fmt2, fmt, sizeof(fmt2)); va_copy(ap_copy, ap); need_len = vsnprintf(pbuf, size, fmt2, ap_copy); @@ -1047,7 +1051,7 @@ int json_vscanf(const char* s, int len, const char* fmt, va_list ap) { while(fmt[i] != '\0') { if(fmt[i] == '{') { - strcat(path, "."); + strlcat(path, ".", sizeof(path)); i++; } else if(fmt[i] == '}') { if((p = strrchr(path, '.')) != NULL) *p = '\0'; @@ -1160,7 +1164,8 @@ struct json_setf_data { static int get_matched_prefix_len(const char* s1, const char* s2) { int i = 0; - while(s1[i] && s2[i] && s1[i] == s2[i]) i++; + while(s1[i] && s2[i] && s1[i] == s2[i]) + i++; return i; } @@ -1235,7 +1240,8 @@ int json_vsetf( /* Trim comma after the value that begins at object/array start */ if(s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { int i = data.end; - while(i < len && json_isspace(s[i])) i++; + while(i < len && json_isspace(s[i])) + i++; if(s[i] == ',') data.end = i + 1; /* Point after comma */ } json_printf(out, "%.*s", len - data.end, s + data.end); @@ -1305,7 +1311,8 @@ struct prettify_data { }; static void indent(struct json_out* out, int level) { - while(level-- > 0) out->printer(out, " ", 2); + while(level-- > 0) + out->printer(out, " ", 2); } static void print_key(struct prettify_data* pd, const char* path, const char* name, int name_len) { diff --git a/lib/mjs/mjs_json.c b/lib/mjs/mjs_json.c index 829b3b4c0..654eeb3d6 100644 --- a/lib/mjs/mjs_json.c +++ b/lib/mjs/mjs_json.c @@ -138,8 +138,7 @@ MJS_PRIVATE mjs_err_t to_json_or_debug( vp < mjs->json_visited_stack.buf + mjs->json_visited_stack.len; vp += sizeof(mjs_val_t)) { if(*(mjs_val_t*)vp == v) { - strncpy(buf, "[Circular]", size); - len = 10; + len = strlcpy(buf, "[Circular]", size); goto clean; } } diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 7f3e2f396..a8da2b366 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.4,, +Version,+,72.5,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/cli/cli.h,, @@ -2598,7 +2598,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t" Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t" Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t" -Function,-,strlcat,size_t,"char*, const char*, size_t" +Function,+,strlcat,size_t,"char*, const char*, size_t" Function,+,strlcpy,size_t,"char*, const char*, size_t" Function,+,strlen,size_t,const char* Function,-,strlwr,char*,char* diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index c6f44f914..c294a3b7d 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.4,, +Version,+,72.5,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, @@ -3275,7 +3275,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t" Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t" Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t" -Function,-,strlcat,size_t,"char*, const char*, size_t" +Function,+,strlcat,size_t,"char*, const char*, size_t" Function,+,strlcpy,size_t,"char*, const char*, size_t" Function,+,strlen,size_t,const char* Function,-,strlwr,char*,char* diff --git a/targets/f7/furi_hal/furi_hal_version.c b/targets/f7/furi_hal/furi_hal_version.c index bd449e599..2859ae362 100644 --- a/targets/f7/furi_hal/furi_hal_version.c +++ b/targets/f7/furi_hal/furi_hal_version.c @@ -99,7 +99,7 @@ static void furi_hal_version_set_name(const char* name) { "xFlipper %s", furi_hal_version.name); } else { - snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper"); + strlcpy(furi_hal_version.device_name, "xFlipper", FURI_HAL_VERSION_DEVICE_NAME_LENGTH); } furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; From 8c2223df5dfc9c5b1119adee634e53610ca504d1 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 7 Sep 2024 20:18:51 +0200 Subject: [PATCH 5/5] Threading, Timers improvements (#3865) * FuriTimer: Use a local variable to wait for deletion This combines the current synchronous behaviour (as we could have deferred the free call too) with a smaller FuriTimer - it's safe to pass a pointer to a local variable to this pending timer call, because we know it'll be finished before the caller returns * Tighten the use of FuriThread* vs FuriThreadId Event loop and Loader mixed those two, but the fact those are aliases should be an implementation detail. For this reason, thread.c is still allowed to mix them freely. --- applications/services/loader/loader.c | 2 +- furi/core/event_loop.c | 34 +++++++++++++++++---------- furi/core/event_loop_timer.c | 5 +++- furi/core/thread.c | 21 +++++++++-------- furi/core/timer.c | 14 ++++++----- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 0f4cc4a0c..b76b38c25 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -717,7 +717,7 @@ static bool loader_do_signal(Loader* loader, uint32_t signal, void* arg) { static bool loader_do_get_application_name(Loader* loader, FuriString* name) { if(loader_is_application_running(loader)) { - furi_string_set(name, furi_thread_get_name(loader->app.thread)); + furi_string_set(name, furi_thread_get_name(furi_thread_get_id(loader->app.thread))); return true; } diff --git a/furi/core/event_loop.c b/furi/core/event_loop.c index 2a6cd51d3..f4f008a71 100644 --- a/furi/core/event_loop.c +++ b/furi/core/event_loop.c @@ -71,9 +71,9 @@ FuriEventLoop* furi_event_loop_alloc(void) { PendingQueue_init(instance->pending_queue); // Clear notification state and value - xTaskNotifyStateClearIndexed(instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX); - ulTaskNotifyValueClearIndexed( - instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF); + TaskHandle_t task = (TaskHandle_t)instance->thread_id; + xTaskNotifyStateClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX); + ulTaskNotifyValueClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF); return instance; } @@ -178,7 +178,7 @@ static void furi_event_loop_process_waiting_list(FuriEventLoop* instance) { static void furi_event_loop_restore_flags(FuriEventLoop* instance, uint32_t flags) { if(flags) { xTaskNotifyIndexed( - instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits); + (TaskHandle_t)instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits); } } @@ -186,10 +186,11 @@ void furi_event_loop_run(FuriEventLoop* instance) { furi_check(instance); furi_check(instance->thread_id == furi_thread_get_current_id()); + FuriThread* thread = furi_thread_get_current(); + // Set the default signal callback if none was previously set - if(furi_thread_get_signal_callback(instance->thread_id) == NULL) { - furi_thread_set_signal_callback( - instance->thread_id, furi_event_loop_signal_callback, instance); + if(furi_thread_get_signal_callback(thread) == NULL) { + furi_thread_set_signal_callback(thread, furi_event_loop_signal_callback, instance); } furi_event_loop_init_tick(instance); @@ -233,8 +234,8 @@ void furi_event_loop_run(FuriEventLoop* instance) { } // Disable the default signal callback - if(furi_thread_get_signal_callback(instance->thread_id) == furi_event_loop_signal_callback) { - furi_thread_set_signal_callback(instance->thread_id, NULL, NULL); + if(furi_thread_get_signal_callback(thread) == furi_event_loop_signal_callback) { + furi_thread_set_signal_callback(thread, NULL, NULL); } } @@ -242,7 +243,10 @@ void furi_event_loop_stop(FuriEventLoop* instance) { furi_check(instance); xTaskNotifyIndexed( - instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagStop, eSetBits); + (TaskHandle_t)instance->thread_id, + FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, + FuriEventLoopFlagStop, + eSetBits); } /* @@ -265,7 +269,10 @@ void furi_event_loop_pend_callback( PendingQueue_push_front(instance->pending_queue, item); xTaskNotifyIndexed( - instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagPending, eSetBits); + (TaskHandle_t)instance->thread_id, + FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, + FuriEventLoopFlagPending, + eSetBits); } /* @@ -473,7 +480,10 @@ static void furi_event_loop_item_notify(FuriEventLoopItem* instance) { FURI_CRITICAL_EXIT(); xTaskNotifyIndexed( - owner->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagEvent, eSetBits); + (TaskHandle_t)owner->thread_id, + FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, + FuriEventLoopFlagEvent, + eSetBits); } static bool furi_event_loop_item_is_waiting(FuriEventLoopItem* instance) { diff --git a/furi/core/event_loop_timer.c b/furi/core/event_loop_timer.c index 03b6c5132..f4a79bb4f 100644 --- a/furi/core/event_loop_timer.c +++ b/furi/core/event_loop_timer.c @@ -65,7 +65,10 @@ static void furi_event_loop_timer_enqueue_request( TimerQueue_push_back(instance->timer_queue, timer); xTaskNotifyIndexed( - instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagTimer, eSetBits); + (TaskHandle_t)instance->thread_id, + FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, + FuriEventLoopFlagTimer, + eSetBits); } /* diff --git a/furi/core/thread.c b/furi/core/thread.c index 69c6b0f04..60cc628ac 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -97,7 +97,7 @@ static void furi_thread_body(void* context) { furi_thread_set_state(thread, FuriThreadStateRunning); if(thread->heap_trace_enabled == true) { - memmgr_heap_enable_thread_trace(thread); + memmgr_heap_enable_thread_trace((FuriThreadId)thread); } thread->ret = thread->callback(thread->context); @@ -106,14 +106,14 @@ static void furi_thread_body(void* context) { if(thread->heap_trace_enabled == true) { furi_delay_ms(33); - thread->heap_size = memmgr_heap_get_thread_memory(thread); + thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)thread); furi_log_print_format( thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo, TAG, "%s allocation balance: %zu", thread->name ? thread->name : "Thread", thread->heap_size); - memmgr_heap_disable_thread_trace(thread); + memmgr_heap_disable_thread_trace((FuriThreadId)thread); } furi_check(thread->state == FuriThreadStateRunning); @@ -275,7 +275,7 @@ void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) { FuriThreadPriority furi_thread_get_priority(FuriThread* thread) { furi_check(thread); - TaskHandle_t hTask = furi_thread_get_id(thread); + TaskHandle_t hTask = (TaskHandle_t)thread; return (FuriThreadPriority)uxTaskPriorityGet(hTask); } @@ -390,7 +390,7 @@ bool furi_thread_join(FuriThread* thread) { FuriThreadId furi_thread_get_id(FuriThread* thread) { furi_check(thread); - return thread; + return (FuriThreadId)thread; } void furi_thread_enable_heap_trace(FuriThread* thread) { @@ -418,7 +418,7 @@ int32_t furi_thread_get_return_code(FuriThread* thread) { } FuriThreadId furi_thread_get_current_id(void) { - return xTaskGetCurrentTaskHandle(); + return (FuriThreadId)xTaskGetCurrentTaskHandle(); } FuriThread* furi_thread_get_current(void) { @@ -624,15 +624,16 @@ bool furi_thread_enumerate(FuriThreadList* thread_list) { FuriThreadListItem* item = furi_thread_list_get_or_insert(thread_list, (FuriThread*)task[i].xHandle); - item->thread = (FuriThreadId)task[i].xHandle; - item->app_id = furi_thread_get_appid(item->thread); + FuriThreadId thread_id = (FuriThreadId)task[i].xHandle; + item->thread = (FuriThread*)thread_id; + item->app_id = furi_thread_get_appid(thread_id); item->name = task[i].pcTaskName; item->priority = task[i].uxCurrentPriority; item->stack_address = (uint32_t)tcb->pxStack; - size_t thread_heap = memmgr_heap_get_thread_memory(item->thread); + size_t thread_heap = memmgr_heap_get_thread_memory(thread_id); item->heap = thread_heap == MEMMGR_HEAP_UNKNOWN ? 0u : thread_heap; item->stack_size = (tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t); - item->stack_min_free = furi_thread_get_stack_space(item->thread); + item->stack_min_free = furi_thread_get_stack_space(thread_id); item->state = furi_thread_state_name(task[i].eCurrentState); item->counter_previous = item->counter_current; item->counter_current = task[i].ulRunTimeCounter; diff --git a/furi/core/timer.c b/furi/core/timer.c index 1ca56f0fa..4ed913958 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -9,7 +9,6 @@ struct FuriTimer { StaticTimer_t container; FuriTimerCallback cb_func; void* cb_context; - volatile bool can_be_removed; }; // IMPORTANT: container MUST be the FIRST struct member @@ -42,9 +41,8 @@ static void furi_timer_epilogue(void* context, uint32_t arg) { furi_assert(context); UNUSED(arg); - FuriTimer* instance = context; - - instance->can_be_removed = true; + volatile bool* can_be_removed = context; + *can_be_removed = true; } void furi_timer_free(FuriTimer* instance) { @@ -53,9 +51,13 @@ void furi_timer_free(FuriTimer* instance) { TimerHandle_t hTimer = (TimerHandle_t)instance; furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); - furi_check(xTimerPendFunctionCall(furi_timer_epilogue, instance, 0, portMAX_DELAY) == pdPASS); - while(!instance->can_be_removed) { + volatile bool can_be_removed = false; + furi_check( + xTimerPendFunctionCall(furi_timer_epilogue, (void*)&can_be_removed, 0, portMAX_DELAY) == + pdPASS); + + while(!can_be_removed) { furi_delay_tick(2); }