From 4bf29827f8f0bbfc1444107e26e4a382c2762da0 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Thu, 6 Oct 2022 01:15:23 +1000 Subject: [PATCH 01/49] M*LIB: non-inlined strings, FuriString primitive (#1795) * Quicksave 1 * Header stage complete * Source stage complete * Lint & merge fixes * Includes * Documentation step 1 * FBT: output free size considering BT STACK * Documentation step 2 * py lint * Fix music player plugin * unit test stage 1: string allocator, mem, getters, setters, appends, compare, search. * unit test: string equality * unit test: string replace * unit test: string start_with, end_with * unit test: string trim * unit test: utf-8 * Rename * Revert fw_size changes * Simplify CLI backspace handling * Simplify CLI character insert * Merge fixes * Furi: correct filenaming and spelling * Bt: remove furi string include Co-authored-by: Aleksandr Kutuzov --- .../debug/bt_debug_app/views/bt_test.c | 12 +- .../debug/display_test/display_test.c | 10 +- .../file_browser_test/file_browser_app.c | 5 +- .../file_browser_test/file_browser_app_i.h | 2 +- .../scenes/file_browser_scene_browser.c | 5 +- .../scenes/file_browser_scene_result.c | 11 +- .../scenes/file_browser_scene_start.c | 2 +- applications/debug/uart_echo/uart_echo.c | 18 +- .../flipper_format_string_test.c | 26 +- .../flipper_format/flipper_format_test.c | 28 +- .../debug/unit_tests/furi/furi_string_test.c | 469 +++++++++++ .../debug/unit_tests/infrared/infrared_test.c | 88 ++- applications/debug/unit_tests/nfc/nfc_test.c | 19 +- .../debug/unit_tests/storage/dirwalk_test.c | 48 +- .../debug/unit_tests/storage/storage_test.c | 28 +- .../debug/unit_tests/stream/stream_test.c | 36 +- .../debug/unit_tests/subghz/subghz_test.c | 21 +- applications/debug/unit_tests/test_index.c | 10 +- applications/main/archive/archive.c | 5 +- applications/main/archive/archive_i.h | 2 +- .../main/archive/helpers/archive_browser.c | 47 +- .../main/archive/helpers/archive_browser.h | 2 +- .../main/archive/helpers/archive_favorites.c | 110 +-- .../main/archive/helpers/archive_files.c | 28 +- .../main/archive/helpers/archive_files.h | 12 +- .../archive/scenes/archive_scene_browser.c | 8 +- .../archive/scenes/archive_scene_delete.c | 9 +- .../archive/scenes/archive_scene_rename.c | 22 +- .../main/archive/views/archive_browser_view.c | 43 +- .../main/archive/views/archive_browser_view.h | 2 +- applications/main/bad_usb/bad_usb_app.c | 11 +- applications/main/bad_usb/bad_usb_app_i.h | 2 +- applications/main/bad_usb/bad_usb_script.c | 46 +- applications/main/bad_usb/bad_usb_script.h | 3 +- .../main/bad_usb/scenes/bad_usb_scene_work.c | 9 +- .../main/bad_usb/views/bad_usb_view.c | 38 +- applications/main/fap_loader/fap_loader_app.c | 51 +- applications/main/ibutton/ibutton.c | 33 +- applications/main/ibutton/ibutton_cli.c | 56 +- applications/main/ibutton/ibutton_i.h | 4 +- .../ibutton/scenes/ibutton_scene_add_type.c | 3 +- .../scenes/ibutton_scene_delete_confirm.c | 8 +- .../ibutton/scenes/ibutton_scene_emulate.c | 12 +- .../main/ibutton/scenes/ibutton_scene_info.c | 8 +- .../main/ibutton/scenes/ibutton_scene_read.c | 2 +- .../main/ibutton/scenes/ibutton_scene_rpc.c | 18 +- .../ibutton/scenes/ibutton_scene_save_name.c | 23 +- .../main/ibutton/scenes/ibutton_scene_start.c | 2 +- .../main/ibutton/scenes/ibutton_scene_write.c | 13 +- applications/main/infrared/infrared.c | 89 ++- .../main/infrared/infrared_brute_force.c | 27 +- applications/main/infrared/infrared_cli.c | 83 +- applications/main/infrared/infrared_i.h | 2 +- applications/main/infrared/infrared_remote.c | 49 +- applications/main/infrared/infrared_remote.h | 2 +- .../main/infrared/infrared_remote_button.c | 11 +- applications/main/infrared/infrared_signal.c | 37 +- applications/main/infrared/infrared_signal.h | 4 +- .../scenes/infrared_scene_edit_rename.c | 12 +- .../main/infrared/scenes/infrared_scene_rpc.c | 2 +- .../infrared/scenes/infrared_scene_start.c | 2 +- .../infrared/views/infrared_progress_view.c | 1 - applications/main/lfrfid/lfrfid.c | 34 +- applications/main/lfrfid/lfrfid_cli.c | 131 ++-- applications/main/lfrfid/lfrfid_i.h | 12 +- .../scenes/lfrfid_scene_delete_confirm.c | 18 +- .../main/lfrfid/scenes/lfrfid_scene_emulate.c | 4 +- .../scenes/lfrfid_scene_extra_actions.c | 2 +- .../lfrfid/scenes/lfrfid_scene_raw_info.c | 4 +- .../lfrfid/scenes/lfrfid_scene_raw_name.c | 6 +- .../lfrfid/scenes/lfrfid_scene_raw_read.c | 18 +- .../main/lfrfid/scenes/lfrfid_scene_read.c | 2 +- .../scenes/lfrfid_scene_read_key_menu.c | 2 +- .../lfrfid/scenes/lfrfid_scene_read_success.c | 28 +- .../main/lfrfid/scenes/lfrfid_scene_rpc.c | 5 +- .../lfrfid/scenes/lfrfid_scene_save_name.c | 27 +- .../lfrfid/scenes/lfrfid_scene_save_type.c | 15 +- .../lfrfid/scenes/lfrfid_scene_saved_info.c | 24 +- .../main/lfrfid/scenes/lfrfid_scene_start.c | 4 +- .../main/lfrfid/scenes/lfrfid_scene_write.c | 4 +- .../main/nfc/helpers/nfc_emv_parser.c | 40 +- .../main/nfc/helpers/nfc_emv_parser.h | 7 +- applications/main/nfc/nfc.c | 4 +- applications/main/nfc/nfc_cli.c | 20 +- applications/main/nfc/nfc_i.h | 2 +- .../main/nfc/scenes/nfc_scene_delete.c | 28 +- .../main/nfc/scenes/nfc_scene_device_info.c | 37 +- .../main/nfc/scenes/nfc_scene_emulate_uid.c | 30 +- .../nfc/scenes/nfc_scene_emv_read_success.c | 32 +- .../main/nfc/scenes/nfc_scene_generate_info.c | 12 +- .../scenes/nfc_scene_mf_classic_keys_delete.c | 14 +- .../scenes/nfc_scene_mf_classic_keys_list.c | 8 +- .../nfc_scene_mf_classic_read_success.c | 20 +- .../nfc/scenes/nfc_scene_mf_desfire_app.c | 6 +- .../nfc/scenes/nfc_scene_mf_desfire_data.c | 6 +- .../nfc_scene_mf_desfire_read_success.c | 25 +- .../nfc/scenes/nfc_scene_mf_ultralight_data.c | 8 +- ...nfc_scene_mf_ultralight_read_auth_result.c | 24 +- .../nfc_scene_mf_ultralight_read_success.c | 20 +- .../nfc/scenes/nfc_scene_mfkey_nonces_info.c | 12 +- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 53 +- .../nfc/scenes/nfc_scene_nfca_read_success.c | 18 +- .../nfc/scenes/nfc_scene_read_card_success.c | 16 +- .../main/nfc/scenes/nfc_scene_save_name.c | 15 +- .../main/nfc/scenes/nfc_scene_set_type.c | 3 +- applications/main/nfc/views/dict_attack.c | 14 +- .../main/subghz/helpers/subghz_types.h | 3 +- .../main/subghz/scenes/subghz_scene_delete.c | 32 +- .../subghz/scenes/subghz_scene_delete_raw.c | 32 +- .../subghz/scenes/subghz_scene_more_raw.c | 2 +- .../subghz/scenes/subghz_scene_read_raw.c | 54 +- .../subghz/scenes/subghz_scene_receiver.c | 48 +- .../scenes/subghz_scene_receiver_config.c | 2 +- .../scenes/subghz_scene_receiver_info.c | 28 +- .../main/subghz/scenes/subghz_scene_rpc.c | 10 +- .../subghz/scenes/subghz_scene_save_name.c | 43 +- .../subghz/scenes/subghz_scene_set_type.c | 6 +- .../subghz/scenes/subghz_scene_show_error.c | 4 +- .../scenes/subghz_scene_show_error_sub.c | 4 +- .../subghz/scenes/subghz_scene_transmitter.c | 26 +- applications/main/subghz/subghz.c | 23 +- applications/main/subghz/subghz_cli.c | 229 +++--- applications/main/subghz/subghz_history.c | 67 +- applications/main/subghz/subghz_history.h | 8 +- applications/main/subghz/subghz_i.c | 128 +-- applications/main/subghz/subghz_i.h | 10 +- applications/main/subghz/subghz_setting.c | 34 +- applications/main/subghz/views/receiver.c | 63 +- .../main/subghz/views/subghz_read_raw.c | 56 +- applications/main/subghz/views/transmitter.c | 36 +- applications/main/u2f/u2f_data.c | 24 +- .../plugins/music_player/music_player.c | 14 +- .../plugins/music_player/music_player_cli.c | 10 +- .../music_player/music_player_worker.c | 25 +- .../plugins/picopass/picopass_device.c | 77 +- .../plugins/picopass/picopass_device.h | 2 +- applications/plugins/picopass/picopass_i.h | 2 +- .../scenes/picopass_scene_device_info.c | 30 +- .../scenes/picopass_scene_read_card_success.c | 44 +- .../scenes/picopass_scene_save_name.c | 15 +- applications/services/bt/bt_cli.c | 36 +- applications/services/bt/bt_service/bt.c | 8 +- applications/services/cli/cli.c | 140 ++-- applications/services/cli/cli.h | 5 +- applications/services/cli/cli_command_gpio.c | 52 +- applications/services/cli/cli_command_gpio.h | 2 +- applications/services/cli/cli_commands.c | 84 +- applications/services/cli/cli_i.h | 8 +- applications/services/crypto/crypto_cli.c | 65 +- .../desktop/animations/animation_manager.c | 21 +- .../desktop/animations/animation_storage.c | 88 ++- .../desktop/animations/animation_storage.h | 1 - applications/services/dialogs/dialogs.h | 5 +- applications/services/dialogs/dialogs_api.c | 5 +- .../services/dialogs/dialogs_message.h | 5 +- applications/services/gui/elements.c | 45 +- applications/services/gui/elements.h | 4 +- .../services/gui/modules/button_menu.c | 16 +- .../services/gui/modules/file_browser.c | 60 +- .../services/gui/modules/file_browser.h | 12 +- .../gui/modules/file_browser_worker.c | 118 +-- .../gui/modules/file_browser_worker.h | 10 +- applications/services/gui/modules/submenu.c | 8 +- applications/services/gui/modules/text_box.c | 19 +- .../services/gui/modules/text_input.c | 10 +- .../services/gui/modules/text_input.h | 3 +- .../services/gui/modules/validators.c | 12 +- .../services/gui/modules/validators.h | 3 +- .../services/gui/modules/variable_item_list.c | 12 +- .../widget_elements/widget_element_button.c | 13 +- .../widget_elements/widget_element_string.c | 11 +- .../widget_element_string_multiline.c | 11 +- .../widget_elements/widget_element_text_box.c | 11 +- .../widget_element_text_scroll.c | 45 +- applications/services/input/input_cli.c | 42 +- applications/services/input/input_i.h | 3 +- applications/services/loader/loader.c | 30 +- applications/services/power/power_cli.c | 48 +- applications/services/rpc/rpc.c | 1 - applications/services/rpc/rpc_cli.c | 2 +- applications/services/rpc/rpc_debug.c | 147 ++-- applications/services/rpc/rpc_i.h | 2 +- applications/services/storage/storage.h | 5 +- applications/services/storage/storage_cli.c | 155 ++-- .../services/storage/storage_external_api.c | 133 ++-- applications/services/storage/storage_glue.c | 20 +- applications/services/storage/storage_glue.h | 11 +- .../services/storage/storage_internal_api.c | 1 - .../services/storage/storage_processing.c | 40 +- .../services/storage/storage_test_app.c | 33 +- .../services/storage/storages/storage_int.c | 9 +- applications/settings/about/about.c | 27 +- .../scenes/storage_settings_scene_benchmark.c | 12 +- .../storage_settings_scene_factory_reset.c | 6 +- .../storage_settings_scene_internal_info.c | 6 +- .../scenes/storage_settings_scene_sd_info.c | 6 +- .../storage_settings/storage_settings.c | 4 +- .../storage_settings/storage_settings.h | 2 +- .../storage_move_to_sd/storage_move_to_sd.c | 26 +- applications/system/updater/cli/updater_cli.c | 39 +- .../updater/scenes/updater_scene_loadcfg.c | 8 +- applications/system/updater/updater.c | 8 +- applications/system/updater/updater_i.h | 4 +- .../system/updater/util/update_task.c | 54 +- .../system/updater/util/update_task.h | 3 +- .../system/updater/util/update_task_i.h | 4 +- .../updater/util/update_task_worker_backup.c | 53 +- .../system/updater/views/updater_main.c | 14 +- firmware/targets/f7/Src/update.c | 45 +- firmware/targets/f7/api_symbols.csv | 134 +++- .../targets/f7/ble_glue/dev_info_service.c | 14 +- firmware/targets/f7/furi_hal/furi_hal_bt.c | 6 +- .../targets/f7/furi_hal/furi_hal_console.c | 9 +- firmware/targets/f7/furi_hal/furi_hal_info.c | 136 ++-- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 4 +- firmware/targets/f7/furi_hal/furi_hal_power.c | 46 +- .../targets/furi_hal_include/furi_hal_bt.h | 6 +- .../targets/furi_hal_include/furi_hal_power.h | 1 - furi/core/check.c | 1 + furi/core/kernel.h | 2 +- furi/core/log.c | 16 +- furi/core/record.c | 1 - furi/core/string.c | 302 +++++++ furi/core/string.h | 738 ++++++++++++++++++ furi/core/thread.c | 18 +- furi/furi.h | 1 + lib/flipper_application/elf/elf_file.c | 77 +- lib/flipper_format/flipper_format.c | 23 +- lib/flipper_format/flipper_format.h | 23 +- lib/flipper_format/flipper_format_stream.c | 96 +-- lib/flipper_format/flipper_format_stream.h | 1 - lib/lfrfid/lfrfid_dict_file.c | 12 +- lib/lfrfid/lfrfid_raw_worker.c | 14 +- lib/lfrfid/lfrfid_worker_modes.c | 12 +- lib/lfrfid/protocols/protocol_awid.c | 20 +- lib/lfrfid/protocols/protocol_em4100.c | 13 +- lib/lfrfid/protocols/protocol_fdx_a.c | 4 +- lib/lfrfid/protocols/protocol_fdx_b.c | 22 +- lib/lfrfid/protocols/protocol_gallagher.c | 6 +- lib/lfrfid/protocols/protocol_h10301.c | 6 +- .../protocols/protocol_hid_ex_generic.c | 4 +- lib/lfrfid/protocols/protocol_hid_generic.c | 22 +- lib/lfrfid/protocols/protocol_indala26.c | 13 +- lib/lfrfid/protocols/protocol_io_prox_xsf.c | 8 +- lib/lfrfid/protocols/protocol_jablotron.c | 4 +- lib/lfrfid/protocols/protocol_keri.c | 4 +- lib/lfrfid/protocols/protocol_pac_stanley.c | 48 +- lib/lfrfid/protocols/protocol_paradox.c | 14 +- lib/lfrfid/protocols/protocol_pyramid.c | 8 +- lib/lfrfid/protocols/protocol_viking.c | 4 +- lib/nfc/helpers/mf_classic_dict.c | 124 +-- lib/nfc/helpers/mf_classic_dict.h | 10 +- lib/nfc/helpers/mfkey32.c | 22 +- lib/nfc/helpers/mfkey32.h | 3 +- lib/nfc/helpers/nfc_debug_log.c | 13 +- lib/nfc/nfc_device.c | 566 +++++++------- lib/nfc/nfc_device.h | 4 +- lib/nfc/parsers/all_in_one.c | 2 +- lib/nfc/parsers/nfc_supported_card.h | 2 - lib/nfc/parsers/plantain_4k_parser.c | 26 +- lib/nfc/parsers/plantain_parser.c | 39 +- lib/nfc/parsers/plantain_parser.h | 2 +- lib/nfc/parsers/troika_4k_parser.c | 3 +- lib/nfc/parsers/troika_parser.c | 2 +- lib/nfc/parsers/two_cities.c | 26 +- lib/nfc/protocols/mifare_desfire.c | 76 +- lib/nfc/protocols/mifare_desfire.h | 17 +- lib/nfc/protocols/mifare_ultralight.c | 56 +- lib/subghz/blocks/generic.c | 23 +- lib/subghz/blocks/generic.h | 2 +- lib/subghz/protocols/base.c | 2 +- lib/subghz/protocols/base.h | 7 +- lib/subghz/protocols/bett.c | 4 +- lib/subghz/protocols/bett.h | 2 +- lib/subghz/protocols/came.c | 4 +- lib/subghz/protocols/came.h | 2 +- lib/subghz/protocols/came_atomo.c | 4 +- lib/subghz/protocols/came_atomo.h | 2 +- lib/subghz/protocols/came_twee.c | 4 +- lib/subghz/protocols/came_twee.h | 2 +- lib/subghz/protocols/chamberlain_code.c | 10 +- lib/subghz/protocols/chamberlain_code.h | 2 +- lib/subghz/protocols/clemsa.c | 4 +- lib/subghz/protocols/clemsa.h | 2 +- lib/subghz/protocols/doitrand.c | 4 +- lib/subghz/protocols/doitrand.h | 2 +- lib/subghz/protocols/faac_slh.c | 4 +- lib/subghz/protocols/faac_slh.h | 2 +- lib/subghz/protocols/gate_tx.c | 4 +- lib/subghz/protocols/gate_tx.h | 2 +- lib/subghz/protocols/holtek.c | 8 +- lib/subghz/protocols/holtek.h | 2 +- lib/subghz/protocols/honeywell_wdb.c | 4 +- lib/subghz/protocols/honeywell_wdb.h | 2 +- lib/subghz/protocols/hormann.c | 4 +- lib/subghz/protocols/hormann.h | 2 +- lib/subghz/protocols/ido.c | 4 +- lib/subghz/protocols/ido.h | 2 +- lib/subghz/protocols/intertechno_v3.c | 10 +- lib/subghz/protocols/intertechno_v3.h | 2 +- lib/subghz/protocols/keeloq.c | 33 +- lib/subghz/protocols/keeloq.h | 2 +- lib/subghz/protocols/keeloq_common.c | 1 - lib/subghz/protocols/kia.c | 4 +- lib/subghz/protocols/kia.h | 2 +- lib/subghz/protocols/linear.c | 4 +- lib/subghz/protocols/linear.h | 2 +- lib/subghz/protocols/magellen.c | 8 +- lib/subghz/protocols/magellen.h | 2 +- lib/subghz/protocols/marantec.c | 4 +- lib/subghz/protocols/marantec.h | 2 +- lib/subghz/protocols/megacode.c | 4 +- lib/subghz/protocols/megacode.h | 2 +- lib/subghz/protocols/nero_radio.c | 4 +- lib/subghz/protocols/nero_radio.h | 2 +- lib/subghz/protocols/nero_sketch.c | 4 +- lib/subghz/protocols/nero_sketch.h | 2 +- lib/subghz/protocols/nice_flo.c | 4 +- lib/subghz/protocols/nice_flo.h | 2 +- lib/subghz/protocols/nice_flor_s.c | 4 +- lib/subghz/protocols/nice_flor_s.h | 2 +- lib/subghz/protocols/oregon2.c | 15 +- lib/subghz/protocols/phoenix_v2.c | 4 +- lib/subghz/protocols/phoenix_v2.h | 2 +- lib/subghz/protocols/power_smart.c | 4 +- lib/subghz/protocols/power_smart.h | 2 +- lib/subghz/protocols/princeton.c | 4 +- lib/subghz/protocols/princeton.h | 2 +- lib/subghz/protocols/raw.c | 47 +- lib/subghz/protocols/raw.h | 2 +- lib/subghz/protocols/scher_khan.c | 4 +- lib/subghz/protocols/scher_khan.h | 2 +- lib/subghz/protocols/secplus_v1.c | 24 +- lib/subghz/protocols/secplus_v1.h | 2 +- lib/subghz/protocols/secplus_v2.c | 4 +- lib/subghz/protocols/secplus_v2.h | 2 +- lib/subghz/protocols/somfy_keytis.c | 4 +- lib/subghz/protocols/somfy_keytis.h | 2 +- lib/subghz/protocols/somfy_telis.c | 4 +- lib/subghz/protocols/somfy_telis.h | 2 +- lib/subghz/protocols/star_line.c | 17 +- lib/subghz/protocols/star_line.h | 2 +- lib/subghz/subghz_file_encoder_worker.c | 24 +- lib/subghz/subghz_keystore.c | 32 +- lib/subghz/subghz_keystore.h | 4 +- lib/subghz/types.h | 2 +- lib/toolbox/args.c | 44 +- lib/toolbox/args.h | 14 +- lib/toolbox/dir_walk.c | 30 +- lib/toolbox/dir_walk.h | 2 +- lib/toolbox/m_cstr_dup.h | 3 +- lib/toolbox/path.c | 81 +- lib/toolbox/path.h | 17 +- lib/toolbox/protocols/protocol.h | 4 +- lib/toolbox/protocols/protocol_dict.c | 4 +- lib/toolbox/protocols/protocol_dict.h | 4 +- lib/toolbox/stream/file_stream.c | 19 +- lib/toolbox/stream/stream.c | 35 +- lib/toolbox/stream/stream.h | 9 +- lib/toolbox/stream/string_stream.c | 34 +- lib/toolbox/stream/string_stream.h | 1 - lib/toolbox/tar/tar_archive.c | 48 +- lib/toolbox/tar/tar_archive.h | 1 - lib/update_util/lfs_backup.c | 8 +- lib/update_util/resources/manifest.c | 36 +- lib/update_util/resources/manifest.h | 3 +- lib/update_util/update_manifest.c | 36 +- lib/update_util/update_manifest.h | 14 +- lib/update_util/update_operation.c | 34 +- lib/update_util/update_operation.h | 5 +- 370 files changed, 5597 insertions(+), 3963 deletions(-) create mode 100644 applications/debug/unit_tests/furi/furi_string_test.c create mode 100644 furi/core/string.c create mode 100644 furi/core/string.h diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index 70f57c12..9f2830d3 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -3,14 +3,13 @@ #include #include #include -#include #include #include struct BtTestParam { const char* label; uint8_t current_value_index; - string_t current_value_text; + FuriString* current_value_text; uint8_t values_count; BtTestParamChangeCallback change_callback; void* context; @@ -85,7 +84,8 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str(canvas, 50, param_text_y, "<"); } - canvas_draw_str(canvas, 61, param_text_y, string_get_cstr(param->current_value_text)); + canvas_draw_str( + canvas, 61, param_text_y, furi_string_get_cstr(param->current_value_text)); if(param->current_value_index < (param->values_count - 1)) { canvas_draw_str(canvas, 113, param_text_y, ">"); @@ -322,7 +322,7 @@ void bt_test_free(BtTest* bt_test) { BtTestParamArray_it_t it; for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); BtTestParamArray_next(it)) { - string_clear(BtTestParamArray_ref(it)->current_value_text); + furi_string_free(BtTestParamArray_ref(it)->current_value_text); } BtTestParamArray_clear(model->params); return false; @@ -354,7 +354,7 @@ BtTestParam* bt_test_param_add( param->change_callback = change_callback; param->context = context; param->current_value_index = 0; - string_init(param->current_value_text); + param->current_value_text = furi_string_alloc(); return true; }); @@ -410,7 +410,7 @@ void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_i } void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) { - string_set_str(param->current_value_text, current_value_text); + furi_string_set(param->current_value_text, current_value_text); } uint8_t bt_test_get_current_value_index(BtTestParam* param) { diff --git a/applications/debug/display_test/display_test.c b/applications/debug/display_test/display_test.c index 947e4dc8..e7f366cb 100644 --- a/applications/debug/display_test/display_test.c +++ b/applications/debug/display_test/display_test.c @@ -113,11 +113,11 @@ static void display_config_set_regulation_ratio(VariableItem* item) { static void display_config_set_contrast(VariableItem* item) { DisplayTest* instance = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - string_t temp; - string_init(temp); - string_cat_printf(temp, "%d", index); - variable_item_set_current_value_text(item, string_get_cstr(temp)); - string_clear(temp); + FuriString* temp; + temp = furi_string_alloc(); + furi_string_cat_printf(temp, "%d", index); + variable_item_set_current_value_text(item, furi_string_get_cstr(temp)); + furi_string_free(temp); instance->config_contrast = index; display_test_reload_config(instance); } diff --git a/applications/debug/file_browser_test/file_browser_app.c b/applications/debug/file_browser_test/file_browser_app.c index c7f461d4..5c7b93bc 100644 --- a/applications/debug/file_browser_test/file_browser_app.c +++ b/applications/debug/file_browser_test/file_browser_app.c @@ -1,7 +1,6 @@ #include "assets_icons.h" #include "file_browser_app_i.h" #include "gui/modules/file_browser.h" -#include "m-string.h" #include #include #include @@ -47,7 +46,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { app->widget = widget_alloc(); - string_init(app->file_path); + app->file_path = furi_string_alloc(); app->file_browser = file_browser_alloc(app->file_path); file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true); @@ -84,7 +83,7 @@ void file_browser_app_free(FileBrowserApp* app) { furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); - string_clear(app->file_path); + furi_string_free(app->file_path); free(app); } diff --git a/applications/debug/file_browser_test/file_browser_app_i.h b/applications/debug/file_browser_test/file_browser_app_i.h index 6e8412c9..20f4c3a0 100644 --- a/applications/debug/file_browser_test/file_browser_app_i.h +++ b/applications/debug/file_browser_test/file_browser_app_i.h @@ -22,7 +22,7 @@ struct FileBrowserApp { Widget* widget; FileBrowser* file_browser; - string_t file_path; + FuriString* file_path; }; typedef enum { diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c b/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c index d9bd1ac5..0bf70e9c 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c @@ -1,8 +1,5 @@ #include "../file_browser_app_i.h" -#include -#include -#include "furi_hal.h" -#include "m-string.h" +#include #define DEFAULT_PATH "/" #define EXTENSION "*" diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_result.c b/applications/debug/file_browser_test/scenes/file_browser_scene_result.c index 53576cef..4c68d80f 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_result.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_result.c @@ -1,6 +1,5 @@ #include "../file_browser_app_i.h" -#include "furi_hal.h" -#include "m-string.h" +#include void file_browser_scene_result_ok_callback(InputType type, void* context) { furi_assert(context); @@ -24,7 +23,13 @@ void file_browser_scene_result_on_enter(void* context) { FileBrowserApp* app = context; widget_add_string_multiline_element( - app->widget, 64, 10, AlignCenter, AlignTop, FontSecondary, string_get_cstr(app->file_path)); + app->widget, + 64, + 10, + AlignCenter, + AlignTop, + FontSecondary, + furi_string_get_cstr(app->file_path)); view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewResult); } diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_start.c b/applications/debug/file_browser_test/scenes/file_browser_scene_start.c index b3381f0a..9eb26944 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_start.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_start.c @@ -19,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt")); + furi_string_set(app->file_path, ANY_PATH("badusb/demo_windows.txt")); scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser); consumed = true; } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 7a0f5c39..03b6a31a 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -25,7 +24,7 @@ typedef struct { } UartEchoApp; typedef struct { - string_t text; + FuriString* text; } ListElement; struct UartDumpModel { @@ -64,10 +63,11 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) { canvas, 0, (i + 1) * (canvas_current_font_height(canvas) - 1), - string_get_cstr(model->list[i]->text)); + furi_string_get_cstr(model->list[i]->text)); if(i == model->line) { - uint8_t width = canvas_string_width(canvas, string_get_cstr(model->list[i]->text)); + uint8_t width = + canvas_string_width(canvas, furi_string_get_cstr(model->list[i]->text)); canvas_draw_box( canvas, @@ -113,7 +113,7 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) { model->escape = true; } else if((data >= ' ' && data <= '~') || (data == '\n' || data == '\r')) { bool new_string_needed = false; - if(string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) { + if(furi_string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) { new_string_needed = true; } else if((data == '\n' || data == '\r')) { // pack line breaks @@ -132,13 +132,13 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) { model->list[i - 1] = model->list[i]; } - string_reset(first->text); + furi_string_reset(first->text); model->list[model->line] = first; } } if(data != '\n' && data != '\r') { - string_push_back(model->list[model->line]->text, data); + furi_string_push_back(model->list[model->line]->text, data); } } model->last_char = data; @@ -208,7 +208,7 @@ static UartEchoApp* uart_echo_app_alloc() { model->line = 0; model->escape = false; model->list[i] = malloc(sizeof(ListElement)); - string_init(model->list[i]->text); + model->list[i]->text = furi_string_alloc(); } return true; }); @@ -247,7 +247,7 @@ static void uart_echo_app_free(UartEchoApp* app) { with_view_model( app->view, (UartDumpModel * model) { for(size_t i = 0; i < LINES_ON_SCREEN; i++) { - string_clear(model->list[i]->text); + furi_string_free(model->list[i]->text); free(model->list[i]); } return true; diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c index b22b333a..920a22a4 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c @@ -58,7 +58,7 @@ static const char* test_data_win = "Filetype: Flipper Format test\r\n" #define ARRAY_W_BSIZE(x) (x), (sizeof(x)) MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { - string_t tmpstr; + FuriString* tmpstr; uint32_t version; uint32_t uint32_data[COUNT_OF(test_uint_data)]; int32_t int32_data[COUNT_OF(test_int_data)]; @@ -101,14 +101,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format))); // read test - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_data), count); @@ -133,7 +133,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // update data mu_check(flipper_format_rewind(flipper_format)); @@ -155,14 +155,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)]; mu_check(flipper_format_rewind(flipper_format)); - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_updated_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_updated_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_updated_data), count); @@ -190,7 +190,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // update data mu_check(flipper_format_rewind(flipper_format)); @@ -214,14 +214,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { uint8_t hex_new_data[COUNT_OF(test_hex_new_data)]; mu_check(flipper_format_rewind(flipper_format)); - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_updated_2_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_updated_2_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_updated_2_data), count); @@ -255,7 +255,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // delete key test mu_check(flipper_format_rewind(flipper_format)); diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 86e2df21..ccd5e751 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -102,8 +102,8 @@ static bool test_read(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; void* scratchpad = malloc(512); @@ -111,11 +111,11 @@ static bool test_read(const char* file_name) { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; if(!flipper_format_read_string(file, test_string_key, string_value)) break; - if(string_cmp_str(string_value, test_string_data) != 0) break; + if(furi_string_cmp_str(string_value, test_string_data) != 0) break; if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break; if(uint32_value != COUNT_OF(test_int_data)) break; @@ -150,7 +150,7 @@ static bool test_read(const char* file_name) { } while(false); free(scratchpad); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); @@ -164,8 +164,8 @@ static bool test_read_updated(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; void* scratchpad = malloc(512); @@ -173,11 +173,11 @@ static bool test_read_updated(const char* file_name) { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; if(!flipper_format_read_string(file, test_string_key, string_value)) break; - if(string_cmp_str(string_value, test_string_updated_data) != 0) break; + if(furi_string_cmp_str(string_value, test_string_updated_data) != 0) break; if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break; if(uint32_value != COUNT_OF(test_int_updated_data)) break; @@ -228,7 +228,7 @@ static bool test_read_updated(const char* file_name) { } while(false); free(scratchpad); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); @@ -401,14 +401,14 @@ static bool test_read_multikey(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; do { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; bool error = false; @@ -429,7 +429,7 @@ static bool test_read_multikey(const char* file_name) { result = true; } while(false); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); furi_record_close(RECORD_STORAGE); diff --git a/applications/debug/unit_tests/furi/furi_string_test.c b/applications/debug/unit_tests/furi/furi_string_test.c new file mode 100644 index 00000000..3ea95b92 --- /dev/null +++ b/applications/debug/unit_tests/furi/furi_string_test.c @@ -0,0 +1,469 @@ +#include +#include "../minunit.h" + +static void test_setup(void) { +} + +static void test_teardown(void) { +} + +static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) { + va_list args; + va_start(args, format); + FuriString* string = furi_string_alloc_vprintf(format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_alloc_free) { + FuriString* tmp; + FuriString* string; + + // test alloc and free + string = furi_string_alloc(); + mu_check(string != NULL); + mu_check(furi_string_empty(string)); + furi_string_free(string); + + // test furi_string_alloc_set_str and free + string = furi_string_alloc_set_str("test"); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test") == 0); + furi_string_free(string); + + // test furi_string_alloc_set and free + tmp = furi_string_alloc_set("more"); + string = furi_string_alloc_set(tmp); + furi_string_free(tmp); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "more") == 0); + furi_string_free(string); + + // test alloc_printf and free + string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0); + furi_string_free(string); + + // test alloc_vprintf and free + string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0); + furi_string_free(string); + + // test alloc_move and free + tmp = furi_string_alloc_set("move"); + string = furi_string_alloc_move(tmp); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "move") == 0); + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_mem) { + FuriString* string = furi_string_alloc_set("test"); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + + // TODO: how to test furi_string_reserve? + + // test furi_string_reset + furi_string_reset(string); + mu_check(furi_string_empty(string)); + + // test furi_string_swap + furi_string_set(string, "test"); + FuriString* swap_string = furi_string_alloc_set("swap"); + furi_string_swap(string, swap_string); + mu_check(furi_string_cmp(string, "swap") == 0); + mu_check(furi_string_cmp(swap_string, "test") == 0); + furi_string_free(swap_string); + + // test furi_string_move + FuriString* move_string = furi_string_alloc_set("move"); + furi_string_move(string, move_string); + mu_check(furi_string_cmp(string, "move") == 0); + // move_string is now empty + // and tested by leaked memory check at the end of the tests + + furi_string_set(string, "abracadabra"); + + // test furi_string_hash + mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string)); + + // test furi_string_size + mu_assert_int_eq(11, furi_string_size(string)); + + // test furi_string_empty + mu_check(!furi_string_empty(string)); + furi_string_reset(string); + mu_check(furi_string_empty(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_getters) { + FuriString* string = furi_string_alloc_set("test"); + + // test furi_string_get_char + mu_check(furi_string_get_char(string, 0) == 't'); + mu_check(furi_string_get_char(string, 1) == 'e'); + mu_check(furi_string_get_char(string, 2) == 's'); + mu_check(furi_string_get_char(string, 3) == 't'); + + // test furi_string_get_cstr + mu_assert_string_eq("test", furi_string_get_cstr(string)); + furi_string_free(string); +} + +static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) { + va_list args; + va_start(args, format); + furi_string_vprintf(string, format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_setters) { + FuriString* tmp; + FuriString* string = furi_string_alloc(); + + // test furi_string_set_str + furi_string_set_str(string, "test"); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + + // test furi_string_set + tmp = furi_string_alloc_set("more"); + furi_string_set(string, tmp); + furi_string_free(tmp); + mu_assert_string_eq("more", furi_string_get_cstr(string)); + + // test furi_string_set_strn + furi_string_set_strn(string, "test", 2); + mu_assert_string_eq("te", furi_string_get_cstr(string)); + + // test furi_string_set_char + furi_string_set_char(string, 0, 'a'); + furi_string_set_char(string, 1, 'b'); + mu_assert_string_eq("ab", furi_string_get_cstr(string)); + + // test furi_string_set_n + tmp = furi_string_alloc_set("dodecahedron"); + furi_string_set_n(string, tmp, 4, 5); + furi_string_free(tmp); + mu_assert_string_eq("cahed", furi_string_get_cstr(string)); + + // test furi_string_printf + furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string)); + + // test furi_string_vprintf + furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) { + va_list args; + va_start(args, format); + furi_string_cat_vprintf(string, format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_appends) { + FuriString* tmp; + FuriString* string = furi_string_alloc(); + + // test furi_string_push_back + furi_string_push_back(string, 't'); + furi_string_push_back(string, 'e'); + furi_string_push_back(string, 's'); + furi_string_push_back(string, 't'); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + furi_string_push_back(string, '!'); + mu_assert_string_eq("test!", furi_string_get_cstr(string)); + + // test furi_string_cat_str + furi_string_cat_str(string, "test"); + mu_assert_string_eq("test!test", furi_string_get_cstr(string)); + + // test furi_string_cat + tmp = furi_string_alloc_set("more"); + furi_string_cat(string, tmp); + furi_string_free(tmp); + mu_assert_string_eq("test!testmore", furi_string_get_cstr(string)); + + // test furi_string_cat_printf + furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string)); + + // test furi_string_cat_vprintf + furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_assert_string_eq( + "test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_compare) { + FuriString* string_1 = furi_string_alloc_set("string_1"); + FuriString* string_2 = furi_string_alloc_set("string_2"); + + // test furi_string_cmp + mu_assert_int_eq(0, furi_string_cmp(string_1, string_1)); + mu_assert_int_eq(0, furi_string_cmp(string_2, string_2)); + mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2)); + mu_assert_int_eq(1, furi_string_cmp(string_2, string_1)); + + // test furi_string_cmp_str + mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1")); + mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2")); + mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2")); + mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1")); + + // test furi_string_cmpi + furi_string_set(string_1, "string"); + furi_string_set(string_2, "StrIng"); + mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1)); + mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2)); + mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2)); + mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1)); + furi_string_set(string_1, "string_1"); + furi_string_set(string_2, "StrIng_2"); + mu_assert_int_eq(32, furi_string_cmp(string_1, string_2)); + mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1)); + mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2)); + mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1)); + + // test furi_string_cmpi_str + furi_string_set(string_1, "string"); + mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING")); + + furi_string_free(string_1); + furi_string_free(string_2); +} + +MU_TEST(mu_test_furi_string_search) { + // 012345678901234567 + FuriString* haystack = furi_string_alloc_set("test321test123test"); + FuriString* needle = furi_string_alloc_set("test"); + + // test furi_string_search + mu_assert_int_eq(0, furi_string_search(haystack, needle)); + mu_assert_int_eq(7, furi_string_search(haystack, needle, 1)); + mu_assert_int_eq(14, furi_string_search(haystack, needle, 8)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15)); + + FuriString* tmp = furi_string_alloc_set("testnone"); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp)); + furi_string_free(tmp); + + // test furi_string_search_str + mu_assert_int_eq(0, furi_string_search_str(haystack, "test")); + mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1)); + mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8)); + mu_assert_int_eq(4, furi_string_search_str(haystack, "321")); + mu_assert_int_eq(11, furi_string_search_str(haystack, "123")); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone")); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15)); + + // test furi_string_search_char + mu_assert_int_eq(0, furi_string_search_char(haystack, 't')); + mu_assert_int_eq(1, furi_string_search_char(haystack, 'e')); + mu_assert_int_eq(2, furi_string_search_char(haystack, 's')); + mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1)); + mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x')); + + // test furi_string_search_rchar + mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't')); + mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e')); + mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's')); + mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3')); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x')); + + furi_string_free(haystack); + furi_string_free(needle); +} + +MU_TEST(mu_test_furi_string_equality) { + FuriString* string = furi_string_alloc_set("test"); + FuriString* string_eq = furi_string_alloc_set("test"); + FuriString* string_neq = furi_string_alloc_set("test2"); + + // test furi_string_equal + mu_check(furi_string_equal(string, string_eq)); + mu_check(!furi_string_equal(string, string_neq)); + + // test furi_string_equal_str + mu_check(furi_string_equal_str(string, "test")); + mu_check(!furi_string_equal_str(string, "test2")); + mu_check(furi_string_equal_str(string_neq, "test2")); + mu_check(!furi_string_equal_str(string_neq, "test")); + + furi_string_free(string); + furi_string_free(string_eq); + furi_string_free(string_neq); +} + +MU_TEST(mu_test_furi_string_replace) { + FuriString* needle = furi_string_alloc_set("test"); + FuriString* replace = furi_string_alloc_set("replace"); + FuriString* string = furi_string_alloc_set("test123test"); + + // test furi_string_replace_at + furi_string_replace_at(string, 4, 3, "!biglongword!"); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + // test furi_string_replace + mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1)); + mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string)); + mu_assert_int_eq(0, furi_string_replace(string, needle, replace)); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace)); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + + // test furi_string_replace_str + mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1)); + mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string)); + mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test")); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test")); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + // test furi_string_replace_all + furi_string_replace_all(string, needle, replace); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + + // test furi_string_replace_all_str + furi_string_replace_all_str(string, "replace", "test"); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + furi_string_free(string); + furi_string_free(needle); + furi_string_free(replace); +} + +MU_TEST(mu_test_furi_string_start_end) { + FuriString* string = furi_string_alloc_set("start_end"); + FuriString* start = furi_string_alloc_set("start"); + FuriString* end = furi_string_alloc_set("end"); + + // test furi_string_start_with + mu_check(furi_string_start_with(string, start)); + mu_check(!furi_string_start_with(string, end)); + + // test furi_string_start_with_str + mu_check(furi_string_start_with_str(string, "start")); + mu_check(!furi_string_start_with_str(string, "end")); + + // test furi_string_end_with + mu_check(furi_string_end_with(string, end)); + mu_check(!furi_string_end_with(string, start)); + + // test furi_string_end_with_str + mu_check(furi_string_end_with_str(string, "end")); + mu_check(!furi_string_end_with_str(string, "start")); + + furi_string_free(string); + furi_string_free(start); + furi_string_free(end); +} + +MU_TEST(mu_test_furi_string_trim) { + FuriString* string = furi_string_alloc_set("biglongstring"); + + // test furi_string_left + furi_string_left(string, 7); + mu_assert_string_eq("biglong", furi_string_get_cstr(string)); + + // test furi_string_right + furi_string_right(string, 3); + mu_assert_string_eq("long", furi_string_get_cstr(string)); + + // test furi_string_mid + furi_string_mid(string, 1, 2); + mu_assert_string_eq("on", furi_string_get_cstr(string)); + + // test furi_string_trim + furi_string_set(string, " \n\r\tbiglongstring \n\r\t "); + furi_string_trim(string); + mu_assert_string_eq("biglongstring", furi_string_get_cstr(string)); + furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa"); + furi_string_trim(string, "ab"); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_utf8) { + FuriString* utf8_string = furi_string_alloc_set("イルカ"); + + // test furi_string_utf8_length + mu_assert_int_eq(9, furi_string_size(utf8_string)); + mu_assert_int_eq(3, furi_string_utf8_length(utf8_string)); + + // test furi_string_utf8_decode + const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC}; + FuriStringUTF8State state = FuriStringUTF8StateStarting; + FuriStringUnicodeValue value = 0; + furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding3, state); + furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding2, state); + furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding1, state); + furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateStarting, state); + mu_assert_int_eq(0x1F42C, value); + + // test furi_string_utf8_push + furi_string_set(utf8_string, ""); + furi_string_utf8_push(utf8_string, value); + mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string)); + + furi_string_free(utf8_string); +} + +MU_TEST_SUITE(test_suite) { + MU_SUITE_CONFIGURE(&test_setup, &test_teardown); + + MU_RUN_TEST(mu_test_furi_string_alloc_free); + MU_RUN_TEST(mu_test_furi_string_mem); + MU_RUN_TEST(mu_test_furi_string_getters); + MU_RUN_TEST(mu_test_furi_string_setters); + MU_RUN_TEST(mu_test_furi_string_appends); + MU_RUN_TEST(mu_test_furi_string_compare); + MU_RUN_TEST(mu_test_furi_string_search); + MU_RUN_TEST(mu_test_furi_string_equality); + MU_RUN_TEST(mu_test_furi_string_replace); + MU_RUN_TEST(mu_test_furi_string_start_end); + MU_RUN_TEST(mu_test_furi_string_trim); + MU_RUN_TEST(mu_test_furi_string_utf8); +} + +int run_minunit_test_furi_string() { + MU_RUN_SUITE(test_suite); + + return MU_EXIT_CODE; +} \ No newline at end of file diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index 32266c48..d861f266 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -11,7 +11,7 @@ typedef struct { InfraredDecoderHandler* decoder_handler; InfraredEncoderHandler* encoder_handler; - string_t file_path; + FuriString* file_path; FlipperFormat* ff; } InfraredTest; @@ -23,7 +23,7 @@ static void infrared_test_alloc() { test->decoder_handler = infrared_alloc_decoder(); test->encoder_handler = infrared_alloc_encoder(); test->ff = flipper_format_buffered_file_alloc(storage); - string_init(test->file_path); + test->file_path = furi_string_alloc(); } static void infrared_test_free() { @@ -31,18 +31,18 @@ static void infrared_test_free() { infrared_free_decoder(test->decoder_handler); infrared_free_encoder(test->encoder_handler); flipper_format_free(test->ff); - string_clear(test->file_path); + furi_string_free(test->file_path); furi_record_close(RECORD_STORAGE); free(test); test = NULL; } static bool infrared_test_prepare_file(const char* protocol_name) { - string_t file_type; - string_init(file_type); + FuriString* file_type; + file_type = furi_string_alloc(); bool success = false; - string_printf( + furi_string_printf( test->file_path, "%s%s%s%s", IR_TEST_FILES_DIR, @@ -52,14 +52,15 @@ static bool infrared_test_prepare_file(const char* protocol_name) { do { uint32_t format_version; - if(!flipper_format_buffered_file_open_existing(test->ff, string_get_cstr(test->file_path))) + if(!flipper_format_buffered_file_open_existing( + test->ff, furi_string_get_cstr(test->file_path))) break; if(!flipper_format_read_header(test->ff, file_type, &format_version)) break; - if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break; + if(furi_string_cmp_str(file_type, "IR tests file") || format_version != 1) break; success = true; } while(false); - string_clear(file_type); + furi_string_free(file_type); return success; } @@ -68,18 +69,18 @@ static bool infrared_test_load_raw_signal( const char* signal_name, uint32_t** timings, uint32_t* timings_count) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { bool is_name_found = false; for(; !is_name_found && flipper_format_read_string(ff, "name", buf); - is_name_found = !string_cmp_str(buf, signal_name)) + is_name_found = !furi_string_cmp(buf, signal_name)) ; if(!is_name_found) break; - if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "raw")) break; + if(!flipper_format_read_string(ff, "type", buf) || furi_string_cmp_str(buf, "raw")) break; if(!flipper_format_get_value_count(ff, "data", timings_count)) break; if(!*timings_count) break; @@ -91,18 +92,18 @@ static bool infrared_test_load_raw_signal( success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* message) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { if(!flipper_format_read_string(ff, "protocol", buf)) break; - message->protocol = infrared_get_protocol_by_name(string_get_cstr(buf)); + message->protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); if(!infrared_is_protocol_valid(message->protocol)) break; if(!flipper_format_read_hex(ff, "address", (uint8_t*)&message->address, sizeof(uint32_t))) break; @@ -112,7 +113,7 @@ static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* messa success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } @@ -121,18 +122,19 @@ static bool infrared_test_load_messages( const char* signal_name, InfraredMessage** messages, uint32_t* messages_count) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { bool is_name_found = false; for(; !is_name_found && flipper_format_read_string(ff, "name", buf); - is_name_found = !string_cmp_str(buf, signal_name)) + is_name_found = !furi_string_cmp(buf, signal_name)) ; if(!is_name_found) break; - if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "parsed_array")) + if(!flipper_format_read_string(ff, "type", buf) || + furi_string_cmp_str(buf, "parsed_array")) break; if(!flipper_format_read_uint32(ff, "count", messages_count, 1)) break; if(!*messages_count) break; @@ -151,7 +153,7 @@ static bool infrared_test_load_messages( success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } @@ -213,26 +215,26 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i InfraredMessage* input_messages; uint32_t input_messages_count; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - string_printf(buf, "encoder_input%d", test_index); + furi_string_printf(buf, "encoder_input%d", test_index); mu_assert( infrared_test_load_messages( - test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); - string_printf(buf, "encoder_expected%d", test_index); + furi_string_printf(buf, "encoder_expected%d", test_index); mu_assert( infrared_test_load_raw_signal( - test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count), + test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count), "Failed to load raw signal from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); uint32_t j = 0; timings = malloc(sizeof(uint32_t) * timings_count); @@ -267,22 +269,22 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_ uint32_t input_messages_count; bool level = false; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); timings = malloc(sizeof(uint32_t) * timings_count); const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - string_printf(buf, "encoder_decoder_input%d", test_index); + furi_string_printf(buf, "encoder_decoder_input%d", test_index); mu_assert( infrared_test_load_messages( - test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) { const InfraredMessage* message_encoded = &input_messages[message_counter]; @@ -327,25 +329,27 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i InfraredMessage* messages; uint32_t messages_count; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); mu_assert( infrared_test_prepare_file(infrared_get_protocol_name(protocol)), "Failed to prepare test file"); - string_printf(buf, "decoder_input%d", test_index); + furi_string_printf(buf, "decoder_input%d", test_index); mu_assert( - infrared_test_load_raw_signal(test->ff, string_get_cstr(buf), &timings, &timings_count), + infrared_test_load_raw_signal( + test->ff, furi_string_get_cstr(buf), &timings, &timings_count), "Failed to load raw signal from file"); - string_printf(buf, "decoder_expected%d", test_index); + furi_string_printf(buf, "decoder_expected%d", test_index); mu_assert( - infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count), + infrared_test_load_messages( + test->ff, furi_string_get_cstr(buf), &messages, &messages_count), "Failed to load messages from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); InfraredMessage message_decoded_check_local; bool level = 0; diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 580943f2..c1468c86 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -53,14 +53,15 @@ static bool nfc_test_read_signal_from_file(const char* file_name) { bool success = false; FlipperFormat* file = flipper_format_file_alloc(nfc_test->storage); - string_t file_type; - string_init(file_type); + FuriString* file_type; + file_type = furi_string_alloc(); uint32_t file_version = 0; do { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, file_type, &file_version)) break; - if(string_cmp_str(file_type, nfc_test_file_type) || file_version != nfc_test_file_version) + if(furi_string_cmp_str(file_type, nfc_test_file_type) || + file_version != nfc_test_file_version) break; if(!flipper_format_read_uint32(file, "Data length", &nfc_test->test_data_len, 1)) break; if(nfc_test->test_data_len > NFC_TEST_DATA_MAX_LEN) break; @@ -76,7 +77,7 @@ static bool nfc_test_read_signal_from_file(const char* file_name) { success = true; } while(false); - string_clear(file_type); + furi_string_free(file_type); flipper_format_free(file); return success; @@ -174,8 +175,8 @@ MU_TEST(nfc_digital_signal_test) { MU_TEST(mf_classic_dict_test) { MfClassicDict* instance = NULL; uint64_t key = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest); mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n"); @@ -184,7 +185,7 @@ MU_TEST(mf_classic_dict_test) { mf_classic_dict_get_total_keys(instance) == 0, "mf_classic_dict_get_total_keys == 0 assert failed\r\n"); - string_set(temp_str, "2196FAD8115B"); + furi_string_set(temp_str, "2196FAD8115B"); mu_assert( mf_classic_dict_add_key_str(instance, temp_str), "mf_classic_dict_add_key == true assert failed\r\n"); @@ -199,7 +200,7 @@ MU_TEST(mf_classic_dict_test) { mf_classic_dict_get_key_at_index_str(instance, temp_str, 0), "mf_classic_dict_get_key_at_index_str == true assert failed\r\n"); mu_assert( - string_cmp(temp_str, "2196FAD8115B") == 0, + furi_string_cmp(temp_str, "2196FAD8115B") == 0, "string_cmp(temp_str, \"2196FAD8115B\") == 0 assert failed\r\n"); mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n"); @@ -216,7 +217,7 @@ MU_TEST(mf_classic_dict_test) { "mf_classic_dict_delete_index == true assert failed\r\n"); mf_classic_dict_free(instance); - string_clear(temp_str); + furi_string_free(temp_str); } MU_TEST_SUITE(nfc) { diff --git a/applications/debug/unit_tests/storage/dirwalk_test.c b/applications/debug/unit_tests/storage/dirwalk_test.c index db3d91a9..97aaa358 100644 --- a/applications/debug/unit_tests/storage/dirwalk_test.c +++ b/applications/debug/unit_tests/storage/dirwalk_test.c @@ -75,7 +75,7 @@ typedef struct { bool visited; } StorageTestPath; -DICT_DEF2(StorageTestPathDict, string_t, STRING_OPLIST, StorageTestPath, M_POD_OPLIST) +DICT_DEF2(StorageTestPathDict, FuriString*, FURI_STRING_OPLIST, StorageTestPath, M_POD_OPLIST) static StorageTestPathDict_t* storage_test_paths_alloc(const StorageTestPathDesc paths[], size_t paths_count) { @@ -83,15 +83,15 @@ static StorageTestPathDict_t* StorageTestPathDict_init(*data); for(size_t i = 0; i < paths_count; i++) { - string_t key; - string_init_set(key, paths[i].path); + FuriString* key; + key = furi_string_alloc_set(paths[i].path); StorageTestPath value = { .is_dir = paths[i].is_dir, .visited = false, }; StorageTestPathDict_set_at(*data, key, value); - string_clear(key); + furi_string_free(key); } return data; @@ -102,7 +102,7 @@ static void storage_test_paths_free(StorageTestPathDict_t* data) { free(data); } -static bool storage_test_paths_mark(StorageTestPathDict_t* data, string_t path, bool is_dir) { +static bool storage_test_paths_mark(StorageTestPathDict_t* data, FuriString* path, bool is_dir) { bool found = false; StorageTestPath* record = StorageTestPathDict_get(*data, path); @@ -148,27 +148,27 @@ static bool write_file_13DA(Storage* storage, const char* path) { } static void storage_dirs_create(Storage* storage, const char* base) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); storage_common_mkdir(storage, base); for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_paths); i++) { - string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]); - storage_common_mkdir(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]); + storage_common_mkdir(storage, furi_string_get_cstr(path)); } for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_files); i++) { - string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]); - write_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]); + write_file_13DA(storage, furi_string_get_cstr(path)); } - string_clear(path); + furi_string_free(path); } MU_TEST_1(test_dirwalk_full, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = @@ -178,12 +178,12 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); @@ -191,8 +191,8 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) { } MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = storage_test_paths_alloc( @@ -203,12 +203,12 @@ MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); @@ -230,8 +230,8 @@ static bool test_dirwalk_filter_no_folder_ext(const char* name, FileInfo* filein } MU_TEST_1(test_dirwalk_filter, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = storage_test_paths_alloc( @@ -242,12 +242,12 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); diff --git a/applications/debug/unit_tests/storage/storage_test.c b/applications/debug/unit_tests/storage/storage_test.c index 099be0d5..7c1c669f 100644 --- a/applications/debug/unit_tests/storage/storage_test.c +++ b/applications/debug/unit_tests/storage/storage_test.c @@ -211,22 +211,22 @@ static bool check_file_13DA(Storage* storage, const char* path) { } static void storage_dir_create(Storage* storage, const char* base) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); storage_common_mkdir(storage, base); for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); - storage_common_mkdir(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + storage_common_mkdir(storage, furi_string_get_cstr(path)); } for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_files[i]); - write_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + write_file_13DA(storage, furi_string_get_cstr(path)); } - string_clear(path); + furi_string_free(path); } static void storage_dir_remove(Storage* storage, const char* base) { @@ -235,15 +235,15 @@ static void storage_dir_remove(Storage* storage, const char* base) { static bool storage_dir_rename_check(Storage* storage, const char* base) { bool result = false; - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); result = (storage_common_stat(storage, base, NULL) == FSE_OK); if(result) { for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); - result = (storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK); + furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + result = (storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK); if(!result) { break; } @@ -252,15 +252,15 @@ static bool storage_dir_rename_check(Storage* storage, const char* base) { if(result) { for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_files[i]); - result = check_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + result = check_file_13DA(storage, furi_string_get_cstr(path)); if(!result) { break; } } } - string_clear(path); + furi_string_free(path); return result; } diff --git a/applications/debug/unit_tests/stream/stream_test.c b/applications/debug/unit_tests/stream/stream_test.c index b5a2d398..c04e119c 100644 --- a/applications/debug/unit_tests/stream/stream_test.c +++ b/applications/debug/unit_tests/stream/stream_test.c @@ -18,8 +18,8 @@ static const char* stream_test_right_data = MU_TEST_1(stream_composite_subtest, Stream* stream) { const size_t data_size = 128; uint8_t data[data_size]; - string_t string_lee; - string_init_set(string_lee, "lee"); + FuriString* string_lee; + string_lee = furi_string_alloc_set("lee"); // test that stream is empty // "" -> "" @@ -267,7 +267,7 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) { mu_assert_int_eq(9, stream_tell(stream)); mu_check(stream_eof(stream)); - string_clear(string_lee); + furi_string_free(string_lee); } MU_TEST(stream_composite_test) { @@ -416,10 +416,10 @@ MU_TEST(stream_buffered_write_after_read_test) { } MU_TEST(stream_buffered_large_file_test) { - string_t input_data; - string_t output_data; - string_init(input_data); - string_init(output_data); + FuriString* input_data; + FuriString* output_data; + input_data = furi_string_alloc(); + output_data = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); @@ -429,7 +429,7 @@ MU_TEST(stream_buffered_large_file_test) { const size_t rep_count = data_size / line_size + 1; for(size_t i = 0; i < rep_count; ++i) { - string_cat_printf(input_data, "%s\n", stream_test_data); + furi_string_cat_printf(input_data, "%s\n", stream_test_data); } // write test data to file @@ -437,8 +437,8 @@ MU_TEST(stream_buffered_large_file_test) { mu_check(buffered_file_stream_open( stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); mu_assert_int_eq(0, stream_size(stream)); - mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data)); - mu_assert_int_eq(string_size(input_data), stream_size(stream)); + mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data)); + mu_assert_int_eq(furi_string_size(input_data), stream_size(stream)); const size_t substr_start = 8; const size_t substr_len = 11; @@ -475,23 +475,23 @@ MU_TEST(stream_buffered_large_file_test) { // read the whole file mu_check(stream_rewind(stream)); - string_t tmp; - string_init(tmp); + FuriString* tmp; + tmp = furi_string_alloc(); while(stream_read_line(stream, tmp)) { - string_cat(output_data, tmp); + furi_string_cat(output_data, tmp); } - string_clear(tmp); + furi_string_free(tmp); // check against generated data - mu_assert_int_eq(string_size(input_data), string_size(output_data)); - mu_check(string_equal_p(input_data, output_data)); + mu_assert_int_eq(furi_string_size(input_data), furi_string_size(output_data)); + mu_check(furi_string_equal(input_data, output_data)); mu_check(stream_eof(stream)); stream_free(stream); furi_record_close(RECORD_STORAGE); - string_clear(input_data); - string_clear(output_data); + furi_string_free(input_data); + furi_string_free(output_data); } MU_TEST_SUITE(stream_suite) { diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 36f5b94c..210d3770 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -28,12 +28,12 @@ static void subghz_test_rx_callback( void* context) { UNUSED(receiver); UNUSED(context); - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); subghz_protocol_decoder_base_get_string(decoder_base, text); subghz_receiver_reset(receiver_handler); - FURI_LOG_T(TAG, "\r\n%s", string_get_cstr(text)); - string_clear(text); + FURI_LOG_T(TAG, "\r\n%s", furi_string_get_cstr(text)); + furi_string_free(text); subghz_test_decoder_count++; } @@ -141,8 +141,8 @@ static bool subghz_decode_random_test(const char* path) { static bool subghz_encoder_test(const char* path) { subghz_test_decoder_count = 0; uint32_t test_start = furi_get_tick(); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool file_load = false; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -167,11 +167,11 @@ static bool subghz_encoder_test(const char* path) { } while(false); if(file_load) { SubGhzTransmitter* transmitter = - subghz_transmitter_alloc_init(environment_handler, string_get_cstr(temp_str)); + subghz_transmitter_alloc_init(environment_handler, furi_string_get_cstr(temp_str)); subghz_transmitter_deserialize(transmitter, fff_data_file); SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name( - receiver_handler, string_get_cstr(temp_str)); + receiver_handler, furi_string_get_cstr(temp_str)); if(decoder) { LevelDuration level_duration; @@ -192,10 +192,11 @@ static bool subghz_encoder_test(const char* path) { flipper_format_free(fff_data_file); FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); if(furi_get_tick() - test_start > TEST_TIMEOUT) { - printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str)); + printf( + "\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", furi_string_get_cstr(temp_str)); subghz_test_decoder_count = 0; } - string_clear(temp_str); + furi_string_free(temp_str); return subghz_test_decoder_count ? true : false; } diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index 81d891b2..2009d4a5 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -1,5 +1,3 @@ -#include "m-string.h" - #include #include #include @@ -11,6 +9,7 @@ #define TAG "UnitTests" int run_minunit_test_furi(); +int run_minunit_test_furi_string(); int run_minunit_test_infrared(); int run_minunit_test_rpc(); int run_minunit_test_flipper_format(); @@ -33,6 +32,7 @@ typedef struct { const UnitTest unit_tests[] = { {.name = "furi", .entry = run_minunit_test_furi}, + {.name = "furi_string", .entry = run_minunit_test_furi_string}, {.name = "storage", .entry = run_minunit_test_storage}, {.name = "stream", .entry = run_minunit_test_stream}, {.name = "dirwalk", .entry = run_minunit_test_dirwalk}, @@ -63,7 +63,7 @@ void minunit_print_fail(const char* str) { printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str); } -void unit_tests_cli(Cli* cli, string_t args, void* context) { +void unit_tests_cli(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -91,8 +91,8 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { break; } - if(string_size(args)) { - if(string_cmp_str(args, unit_tests[i].name) == 0) { + if(furi_string_size(args)) { + if(furi_string_cmp_str(args, unit_tests[i].name) == 0) { failed_tests += unit_tests[i].entry(); } else { printf("Skipping %s\r\n", unit_tests[i].name); diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index bbe532c8..b8609cf2 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,5 +1,4 @@ #include "archive_i.h" -#include "m-string.h" bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -18,7 +17,7 @@ ArchiveApp* archive_alloc() { archive->gui = furi_record_open(RECORD_GUI); archive->text_input = text_input_alloc(); - string_init(archive->fav_move_str); + archive->fav_move_str = furi_string_alloc(); archive->view_dispatcher = view_dispatcher_alloc(); archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive); @@ -58,7 +57,7 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_free(archive->view_dispatcher); scene_manager_free(archive->scene_manager); browser_free(archive->browser); - string_clear(archive->fav_move_str); + furi_string_free(archive->fav_move_str); text_input_free(archive->text_input); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 865e837d..d444aef8 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -28,7 +28,7 @@ struct ArchiveApp { TextInput* text_input; Widget* widget; FuriPubSubSubscription* loader_stop_subscription; - string_t fav_move_str; + FuriString* fav_move_str; char text_store[MAX_NAME_LEN]; char file_extension[MAX_EXT_LEN + 1]; }; diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 00bb6b06..1f4ca0f7 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -5,7 +5,6 @@ #include #include #include "gui/modules/file_browser_worker.h" -#include "m-string.h" #include static void @@ -19,7 +18,7 @@ static void if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) { archive_switch_tab(browser, browser->last_tab_switch_dir); - } else if(!string_start_with_str_p(browser->path, "/app:")) { + } else if(!furi_string_start_with_str(browser->path, "/app:")) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { files_array_reset(model->files); @@ -51,12 +50,13 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) { }); } -static void archive_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last) { +static void + archive_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) { furi_assert(context); ArchiveBrowserView* browser = (ArchiveBrowserView*)context; if(!is_last) { - archive_add_file_item(browser, is_folder, string_get_cstr(item_path)); + archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { @@ -79,7 +79,7 @@ static void archive_long_load_cb(void* context) { static void archive_file_browser_set_path( ArchiveBrowserView* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets) { furi_assert(browser); @@ -133,7 +133,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) { furi_assert(browser); furi_assert(target); - archive_get_items(browser, string_get_cstr(browser->path)); + archive_get_items(browser, furi_string_get_cstr(browser->path)); if(!archive_file_get_array_size(browser) && archive_is_home(browser)) { archive_switch_tab(browser, TAB_RIGHT); @@ -143,7 +143,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) { uint16_t idx = 0; while(idx < files_array_size(model->files)) { ArchiveFile_t* current = files_array_get(model->files, idx); - if(!string_search(current->path, target)) { + if(!furi_string_search(current->path, target)) { model->item_idx = idx + model->array_offset; break; } @@ -315,12 +315,12 @@ bool archive_is_home(ArchiveBrowserView* browser) { } const char* default_path = archive_get_default_path(archive_get_tab(browser)); - return (string_cmp_str(browser->path, default_path) == 0); + return (furi_string_cmp_str(browser->path, default_path) == 0); } const char* archive_get_name(ArchiveBrowserView* browser) { ArchiveFile_t* selected = archive_get_current_file(browser); - return string_get_cstr(selected->path); + return furi_string_get_cstr(selected->path); } void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) { @@ -339,7 +339,7 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { ArchiveFile_t item; ArchiveFile_t_init(&item); - string_set_str(item.path, name); + furi_string_set(item.path, name); archive_set_file_type(&item, name, false, true); with_view_model( @@ -358,8 +358,8 @@ void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const ch ArchiveFile_t item; ArchiveFile_t_init(&item); - string_init_set_str(item.path, name); - archive_set_file_type(&item, string_get_cstr(browser->path), is_folder, false); + item.path = furi_string_alloc_set(name); + archive_set_file_type(&item, furi_string_get_cstr(browser->path), is_folder, false); with_view_model( browser->view, (ArchiveBrowserViewModel * model) { @@ -379,7 +379,8 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) { model->menu_idx = 0; ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); - selected->fav = archive_is_favorite("%s", string_get_cstr(selected->path)); + selected->fav = + archive_is_favorite("%s", furi_string_get_cstr(selected->path)); } } else { model->menu = false; @@ -400,14 +401,14 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) { }); } -static bool archive_is_dir_exists(string_t path) { - if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) { +static bool archive_is_dir_exists(FuriString* path) { + if(furi_string_equal(path, STORAGE_ANY_PATH_PREFIX)) { return true; } bool state = false; FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { state = true; } @@ -431,16 +432,16 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { browser->is_root = true; archive_set_tab(browser, tab); - string_set_str(browser->path, archive_get_default_path(tab)); + furi_string_set(browser->path, archive_get_default_path(tab)); bool tab_empty = true; if(tab == ArchiveTabFavorites) { if(archive_favorites_count(browser) > 0) { tab_empty = false; } - } else if(string_start_with_str_p(browser->path, "/app:")) { - char* app_name = strchr(string_get_cstr(browser->path), ':'); + } else if(furi_string_start_with_str(browser->path, "/app:")) { + char* app_name = strchr(furi_string_get_cstr(browser->path), ':'); if(app_name != NULL) { - if(archive_app_is_available(browser, string_get_cstr(browser->path))) { + if(archive_app_is_available(browser, furi_string_get_cstr(browser->path))) { tab_empty = false; } } @@ -463,12 +464,12 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { model->array_offset = 0; return false; }); - archive_get_items(browser, string_get_cstr(browser->path)); + archive_get_items(browser, furi_string_get_cstr(browser->path)); archive_update_offset(browser); } } -void archive_enter_dir(ArchiveBrowserView* browser, string_t path) { +void archive_enter_dir(ArchiveBrowserView* browser, FuriString* path) { furi_assert(browser); furi_assert(path); @@ -480,7 +481,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t path) { return false; }); - string_set(browser->path, path); + furi_string_set(browser->path, path); file_browser_worker_folder_enter(browser->worker, path, idx_temp); } diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h index ad64a984..c9e3bfa3 100644 --- a/applications/main/archive/helpers/archive_browser.h +++ b/applications/main/archive/helpers/archive_browser.h @@ -84,6 +84,6 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show); void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active); void archive_switch_tab(ArchiveBrowserView* browser, InputKey key); -void archive_enter_dir(ArchiveBrowserView* browser, string_t name); +void archive_enter_dir(ArchiveBrowserView* browser, FuriString* name); void archive_leave_dir(ArchiveBrowserView* browser); void archive_refresh_dir(ArchiveBrowserView* browser); diff --git a/applications/main/archive/helpers/archive_favorites.c b/applications/main/archive/helpers/archive_favorites.c index 4d5b555f..86a294f7 100644 --- a/applications/main/archive/helpers/archive_favorites.c +++ b/applications/main/archive/helpers/archive_favorites.c @@ -6,8 +6,8 @@ #define ARCHIVE_FAV_FILE_BUF_LEN 32 -static bool archive_favorites_read_line(File* file, string_t str_result) { - string_reset(str_result); +static bool archive_favorites_read_line(File* file, FuriString* str_result) { + furi_string_reset(str_result); uint8_t buffer[ARCHIVE_FAV_FILE_BUF_LEN]; bool result = false; @@ -34,7 +34,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) { result = true; break; } else { - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); } } @@ -52,8 +52,8 @@ uint16_t archive_favorites_count(void* context) { Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); uint16_t lines = 0; @@ -63,7 +63,7 @@ uint16_t archive_favorites_count(void* context) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; // Skip empty lines } ++lines; @@ -72,7 +72,7 @@ uint16_t archive_favorites_count(void* context) { storage_file_close(file); - string_clear(buffer); + furi_string_free(buffer); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -80,8 +80,8 @@ uint16_t archive_favorites_count(void* context) { } static bool archive_favourites_rescan() { - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); @@ -91,23 +91,25 @@ static bool archive_favourites_rescan() { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, "/app:") == 0) { - if(archive_app_is_available(NULL, string_get_cstr(buffer))) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(furi_string_search(buffer, "/app:") == 0) { + if(archive_app_is_available(NULL, furi_string_get_cstr(buffer))) { + archive_file_append( + ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } else { - if(storage_file_exists(storage, string_get_cstr(buffer))) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(storage_file_exists(storage, furi_string_get_cstr(buffer))) { + archive_file_append( + ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } } } - string_clear(buffer); + furi_string_free(buffer); storage_file_close(file); storage_common_remove(storage, ARCHIVE_FAV_PATH); @@ -127,9 +129,9 @@ bool archive_favorites_read(void* context) { Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); - string_t buffer; + FuriString* buffer; FileInfo file_info; - string_init(buffer); + buffer = furi_string_alloc(); bool need_refresh = false; uint16_t file_count = 0; @@ -143,33 +145,33 @@ bool archive_favorites_read(void* context) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, "/app:") == 0) { - if(archive_app_is_available(browser, string_get_cstr(buffer))) { - archive_add_app_item(browser, string_get_cstr(buffer)); + if(furi_string_search(buffer, "/app:") == 0) { + if(archive_app_is_available(browser, furi_string_get_cstr(buffer))) { + archive_add_app_item(browser, furi_string_get_cstr(buffer)); file_count++; } else { need_refresh = true; } } else { - if(storage_file_exists(storage, string_get_cstr(buffer))) { - storage_common_stat(storage, string_get_cstr(buffer), &file_info); + if(storage_file_exists(storage, furi_string_get_cstr(buffer))) { + storage_common_stat(storage, furi_string_get_cstr(buffer), &file_info); archive_add_file_item( - browser, (file_info.flags & FSF_DIRECTORY), string_get_cstr(buffer)); + browser, (file_info.flags & FSF_DIRECTORY), furi_string_get_cstr(buffer)); file_count++; } else { need_refresh = true; } } - string_reset(buffer); + furi_string_reset(buffer); } } storage_file_close(file); - string_clear(buffer); + furi_string_free(buffer); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -183,14 +185,14 @@ bool archive_favorites_read(void* context) { } bool archive_favorites_delete(const char* format, ...) { - string_t buffer; - string_t filename; + FuriString* buffer; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); - string_init(buffer); + buffer = furi_string_alloc(); Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); @@ -201,18 +203,18 @@ bool archive_favorites_delete(const char* format, ...) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, filename)) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(furi_string_search(buffer, filename)) { + archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } } - string_clear(buffer); - string_clear(filename); + furi_string_free(buffer); + furi_string_free(filename); storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); @@ -226,14 +228,14 @@ bool archive_favorites_delete(const char* format, ...) { } bool archive_is_favorite(const char* format, ...) { - string_t buffer; - string_t filename; + FuriString* buffer; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); - string_init(buffer); + buffer = furi_string_alloc(); Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); @@ -245,10 +247,10 @@ bool archive_is_favorite(const char* format, ...) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(!string_search(buffer, filename)) { + if(!furi_string_search(buffer, filename)) { found = true; break; } @@ -256,8 +258,8 @@ bool archive_is_favorite(const char* format, ...) { } storage_file_close(file); - string_clear(buffer); - string_clear(filename); + furi_string_free(buffer); + furi_string_free(filename); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -271,13 +273,13 @@ bool archive_favorites_rename(const char* src, const char* dst) { Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - string_t path; - string_t buffer; + FuriString* path; + FuriString* buffer; - string_init(buffer); - string_init(path); + buffer = furi_string_alloc(); + path = furi_string_alloc(); - string_printf(path, "%s", src); + furi_string_printf(path, "%s", src); bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { @@ -285,19 +287,19 @@ bool archive_favorites_rename(const char* src, const char* dst) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } archive_file_append( ARCHIVE_FAV_TEMP_PATH, "%s\n", - string_search(buffer, path) ? string_get_cstr(buffer) : dst); + furi_string_search(buffer, path) ? furi_string_get_cstr(buffer) : dst); } } - string_clear(buffer); - string_clear(path); + furi_string_free(buffer); + furi_string_free(path); storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); @@ -325,7 +327,7 @@ void archive_favorites_save(void* context) { for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { ArchiveFile_t* item = archive_get_file_at(browser, i); - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(item->path)); + archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(item->path)); } storage_common_remove(fs_api, ARCHIVE_FAV_PATH); diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 9f8b4ee1..87265a45 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -15,10 +15,10 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder } else { for(size_t i = 0; i < COUNT_OF(known_ext); i++) { if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue; - if(string_search_str(file->path, known_ext[i], 0) != STRING_FAILURE) { + if(furi_string_search(file->path, known_ext[i], 0) != FURI_STRING_FAILURE) { if(i == ArchiveFileTypeBadUsb) { - if(string_search_str(file->path, archive_get_default_path(ArchiveTabBadUsb)) == - 0) { + if(furi_string_search( + file->path, archive_get_default_path(ArchiveTabBadUsb)) == 0) { file->type = i; return; // *.txt file is a BadUSB script only if it is in BadUSB folder } @@ -54,10 +54,10 @@ bool archive_get_items(void* context, const char* path) { void archive_file_append(const char* path, const char* format, ...) { furi_assert(path); - string_t string; + FuriString* string; va_list args; va_start(args, format); - string_init_vprintf(string, format, args); + string = furi_string_alloc_vprintf(format, args); va_end(args); Storage* fs_api = furi_record_open(RECORD_STORAGE); @@ -66,7 +66,7 @@ void archive_file_append(const char* path, const char* format, ...) { bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); if(res) { - storage_file_write(file, string_get_cstr(string), string_size(string)); + storage_file_write(file, furi_string_get_cstr(string), furi_string_size(string)); } storage_file_close(file); @@ -77,35 +77,35 @@ void archive_file_append(const char* path, const char* format, ...) { void archive_delete_file(void* context, const char* format, ...) { furi_assert(context); - string_t filename; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); ArchiveBrowserView* browser = context; Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; - storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo); + storage_common_stat(fs_api, furi_string_get_cstr(filename), &fileinfo); bool res = false; if(fileinfo.flags & FSF_DIRECTORY) { - res = storage_simply_remove_recursive(fs_api, string_get_cstr(filename)); + res = storage_simply_remove_recursive(fs_api, furi_string_get_cstr(filename)); } else { - res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK); + res = (storage_common_remove(fs_api, furi_string_get_cstr(filename)) == FSE_OK); } furi_record_close(RECORD_STORAGE); - if(archive_is_favorite("%s", string_get_cstr(filename))) { - archive_favorites_delete("%s", string_get_cstr(filename)); + if(archive_is_favorite("%s", furi_string_get_cstr(filename))) { + archive_favorites_delete("%s", furi_string_get_cstr(filename)); } if(res) { archive_file_array_rm_selected(browser); } - string_clear(filename); + furi_string_free(filename); } diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 84b7e24a..a50a1d53 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include typedef enum { @@ -19,7 +19,7 @@ typedef enum { } ArchiveFileTypeEnum; typedef struct { - string_t path; + FuriString* path; ArchiveFileTypeEnum type; bool fav; bool is_app; @@ -29,25 +29,25 @@ static void ArchiveFile_t_init(ArchiveFile_t* obj) { obj->type = ArchiveFileTypeUnknown; obj->is_app = false; obj->fav = false; - string_init(obj->path); + obj->path = furi_string_alloc(); } static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { obj->type = src->type; obj->is_app = src->is_app; obj->fav = src->fav; - string_init_set(obj->path, src->path); + obj->path = furi_string_alloc_set(src->path); } static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { obj->type = src->type; obj->is_app = src->is_app; obj->fav = src->fav; - string_set(obj->path, src->path); + furi_string_set(obj->path, src->path); } static void ArchiveFile_t_clear(ArchiveFile_t* obj) { - string_clear(obj->path); + furi_string_free(obj->path); } ARRAY_DEF( diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index e22ac792..b4fd0482 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -40,14 +40,14 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec LoaderStatus status; if(selected->is_app) { - char* param = strrchr(string_get_cstr(selected->path), '/'); + char* param = strrchr(furi_string_get_cstr(selected->path), '/'); if(param != NULL) { param++; } status = loader_start(loader, flipper_app_name[selected->type], param); } else { status = loader_start( - loader, flipper_app_name[selected->type], string_get_cstr(selected->path)); + loader, flipper_app_name[selected->type], furi_string_get_cstr(selected->path)); } if(status != LoaderStatusOk) { @@ -159,13 +159,13 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case ArchiveBrowserEventEnterFavMove: - string_set(archive->fav_move_str, selected->path); + furi_string_set(archive->fav_move_str, selected->path); archive_show_file_menu(browser, false); archive_favorites_move_mode(archive->browser, true); consumed = true; break; case ArchiveBrowserEventExitFavMove: - archive_update_focus(browser, string_get_cstr(archive->fav_move_str)); + archive_update_focus(browser, furi_string_get_cstr(archive->fav_move_str)); archive_favorites_move_mode(archive->browser, false); consumed = true; break; diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index d882fd06..d3964d0f 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -4,7 +4,6 @@ #include "../helpers/archive_apps.h" #include "../helpers/archive_browser.h" #include "toolbox/path.h" -#include "m-string.h" #define SCENE_DELETE_CUSTOM_EVENT (0UL) #define MAX_TEXT_INPUT_LEN 22 @@ -26,18 +25,18 @@ void archive_scene_delete_on_enter(void* context) { widget_add_button_element( app->widget, GuiButtonTypeRight, "Delete", archive_scene_delete_widget_callback, app); - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); ArchiveFile_t* current = archive_get_current_file(app->browser); path_extract_filename(current->path, filename, false); char delete_str[64]; - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(filename)); + snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(filename)); widget_add_text_box_element( app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); - string_clear(filename); + furi_string_free(filename); view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget); } diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 293fa89a..1451428b 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -19,10 +19,10 @@ void archive_scene_rename_on_enter(void* context) { TextInput* text_input = archive->text_input; ArchiveFile_t* current = archive_get_current_file(archive->browser); - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(current->path, filename, true); - strlcpy(archive->text_store, string_get_cstr(filename), MAX_NAME_LEN); + strlcpy(archive->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); @@ -37,10 +37,10 @@ void archive_scene_rename_on_enter(void* context) { false); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(archive->browser->path), archive->file_extension, ""); + furi_string_get_cstr(archive->browser->path), archive->file_extension, ""); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(filename); + furi_string_free(filename); view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput); } @@ -56,19 +56,19 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { const char* path_src = archive_get_name(archive->browser); ArchiveFile_t* file = archive_get_current_file(archive->browser); - string_t path_dst; - string_init(path_dst); + FuriString* path_dst; + path_dst = furi_string_alloc(); path_extract_dirname(path_src, path_dst); - string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); + furi_string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); - storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); + storage_common_rename(fs_api, path_src, furi_string_get_cstr(path_dst)); furi_record_close(RECORD_STORAGE); if(file->fav) { - archive_favorites_rename(path_src, string_get_cstr(path_dst)); + archive_favorites_rename(path_src, furi_string_get_cstr(path_dst)); } - string_clear(path_dst); + furi_string_free(path_dst); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); consumed = true; diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index ddd6637d..4a0f2f3c 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -47,35 +47,35 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorBlack); elements_slightly_rounded_frame(canvas, 70, 16, 58, 48); - string_t menu[MENU_ITEMS]; + FuriString* menu[MENU_ITEMS]; - string_init_set_str(menu[0], "Run in app"); - string_init_set_str(menu[1], "Pin"); - string_init_set_str(menu[2], "Rename"); - string_init_set_str(menu[3], "Delete"); + menu[0] = furi_string_alloc_set("Run in app"); + menu[1] = furi_string_alloc_set("Pin"); + menu[2] = furi_string_alloc_set("Rename"); + menu[3] = furi_string_alloc_set("Delete"); ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { - string_set_str(menu[1], "Unpin"); + furi_string_set(menu[1], "Unpin"); } if(!archive_is_known_app(selected->type)) { - string_set_str(menu[0], "---"); - string_set_str(menu[1], "---"); - string_set_str(menu[2], "---"); + furi_string_set(menu[0], "---"); + furi_string_set(menu[1], "---"); + furi_string_set(menu[2], "---"); } else { if(model->tab_idx == ArchiveTabFavorites) { - string_set_str(menu[2], "Move"); - string_set_str(menu[3], "---"); + furi_string_set(menu[2], "Move"); + furi_string_set(menu[3], "---"); } else if(selected->is_app) { - string_set_str(menu[2], "---"); + furi_string_set(menu[2], "---"); } } for(size_t i = 0; i < MENU_ITEMS; i++) { - canvas_draw_str(canvas, 82, 27 + i * 11, string_get_cstr(menu[i])); - string_clear(menu[i]); + canvas_draw_str(canvas, 82, 27 + i * 11, furi_string_get_cstr(menu[i])); + furi_string_free(menu[i]); } canvas_draw_icon(canvas, 74, 20 + model->menu_idx * 11, &I_ButtonRight_4x7); @@ -118,8 +118,8 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { bool scrollbar = model->item_cnt > 4; for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) { - string_t str_buf; - string_init(str_buf); + FuriString* str_buf; + str_buf = furi_string_alloc(); int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0; @@ -131,7 +131,7 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); file_type = file->type; } else { - string_set_str(str_buf, "---"); + furi_string_set(str_buf, "---"); } elements_string_fit_width( @@ -144,9 +144,10 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { } canvas_draw_icon(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]); - canvas_draw_str(canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, string_get_cstr(str_buf)); + canvas_draw_str( + canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buf)); - string_clear(str_buf); + furi_string_free(str_buf); } if(scrollbar) { @@ -361,7 +362,7 @@ ArchiveBrowserView* browser_alloc() { view_set_draw_callback(browser->view, archive_view_render); view_set_input_callback(browser->view, archive_view_input); - string_init_set_str(browser->path, archive_get_default_path(TAB_DEFAULT)); + browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT)); with_view_model( browser->view, (ArchiveBrowserViewModel * model) { @@ -386,7 +387,7 @@ void browser_free(ArchiveBrowserView* browser) { return false; }); - string_clear(browser->path); + furi_string_free(browser->path); view_free(browser->view); free(browser); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 5c649c38..447cb0e1 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -77,7 +77,7 @@ struct ArchiveBrowserView { bool worker_running; ArchiveBrowserViewCallback callback; void* context; - string_t path; + FuriString* path; InputKey last_tab_switch_dir; bool is_root; }; diff --git a/applications/main/bad_usb/bad_usb_app.c b/applications/main/bad_usb/bad_usb_app.c index 09d7d346..6fd29cd7 100644 --- a/applications/main/bad_usb/bad_usb_app.c +++ b/applications/main/bad_usb/bad_usb_app.c @@ -1,5 +1,4 @@ #include "bad_usb_app_i.h" -#include "m-string.h" #include #include #include @@ -26,10 +25,10 @@ static void bad_usb_app_tick_event_callback(void* context) { BadUsbApp* bad_usb_app_alloc(char* arg) { BadUsbApp* app = malloc(sizeof(BadUsbApp)); - string_init(app->file_path); + app->file_path = furi_string_alloc(); if(arg && strlen(arg)) { - string_set_str(app->file_path, arg); + furi_string_set(app->file_path, arg); } app->gui = furi_record_open(RECORD_GUI); @@ -64,10 +63,10 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { app->error = BadUsbAppErrorCloseRpc; scene_manager_next_scene(app->scene_manager, BadUsbSceneError); } else { - if(!string_empty_p(app->file_path)) { + if(!furi_string_empty(app->file_path)) { scene_manager_next_scene(app->scene_manager, BadUsbSceneWork); } else { - string_set_str(app->file_path, BAD_USB_APP_PATH_FOLDER); + furi_string_set(app->file_path, BAD_USB_APP_PATH_FOLDER); scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect); } } @@ -95,7 +94,7 @@ void bad_usb_app_free(BadUsbApp* app) { furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); - string_clear(app->file_path); + furi_string_free(app->file_path); free(app); } diff --git a/applications/main/bad_usb/bad_usb_app_i.h b/applications/main/bad_usb/bad_usb_app_i.h index 6378bddf..85fd56ff 100644 --- a/applications/main/bad_usb/bad_usb_app_i.h +++ b/applications/main/bad_usb/bad_usb_app_i.h @@ -31,7 +31,7 @@ struct BadUsbApp { Widget* widget; BadUsbAppError error; - string_t file_path; + FuriString* file_path; BadUsb* bad_usb_view; BadUsbScript* bad_usb_script; }; diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 9d9d3e39..4166642b 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -26,16 +26,16 @@ typedef enum { struct BadUsbScript { FuriHalUsbHidConfig hid_cfg; BadUsbState st; - string_t file_path; + FuriString* file_path; uint32_t defdelay; FuriThread* thread; uint8_t file_buf[FILE_BUFFER_LEN + 1]; uint8_t buf_start; uint8_t buf_len; bool file_end; - string_t line; + FuriString* line; - string_t line_prev; + FuriString* line_prev; uint32_t repeat_cnt; }; @@ -230,9 +230,9 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) { return 0; } -static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) { - uint32_t line_len = string_size(line); - const char* line_tmp = string_get_cstr(line); +static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { + uint32_t line_len = furi_string_size(line); + const char* line_tmp = furi_string_get_cstr(line); bool state = false; for(uint32_t i = 0; i < line_len; i++) { @@ -337,7 +337,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; - string_reset(bad_usb->line); + furi_string_reset(bad_usb->line); do { ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN); @@ -347,7 +347,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { line_len = 0; } else { if(bad_usb->st.line_nb == 0) { // Save first line - string_push_back(bad_usb->line, bad_usb->file_buf[i]); + furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]); } line_len++; } @@ -360,7 +360,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } } while(ret > 0); - const char* line_tmp = string_get_cstr(bad_usb->line); + const char* line_tmp = furi_string_get_cstr(bad_usb->line); bool id_set = false; // Looking for ID command at first line if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { id_set = ducky_set_usb_id(bad_usb, &line_tmp[strlen(ducky_cmd_id) + 1]); @@ -373,7 +373,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } storage_file_seek(script_file, 0, true); - string_reset(bad_usb->line); + furi_string_reset(bad_usb->line); return true; } @@ -395,8 +395,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil } } - string_set(bad_usb->line_prev, bad_usb->line); - string_reset(bad_usb->line); + furi_string_set(bad_usb->line_prev, bad_usb->line); + furi_string_reset(bad_usb->line); while(1) { if(bad_usb->buf_len == 0) { @@ -413,7 +413,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil if(bad_usb->buf_len == 0) return SCRIPT_STATE_END; } for(uint8_t i = bad_usb->buf_start; i < (bad_usb->buf_start + bad_usb->buf_len); i++) { - if(bad_usb->file_buf[i] == '\n' && string_size(bad_usb->line) > 0) { + if(bad_usb->file_buf[i] == '\n' && furi_string_size(bad_usb->line) > 0) { bad_usb->st.line_cur++; bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1); bad_usb->buf_start = i + 1; @@ -426,7 +426,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return (delay_val + bad_usb->defdelay); } } else { - string_push_back(bad_usb->line, bad_usb->file_buf[i]); + furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]); } } bad_usb->buf_len = 0; @@ -456,8 +456,8 @@ static int32_t bad_usb_worker(void* context) { FURI_LOG_I(WORKER_TAG, "Init"); File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - string_init(bad_usb->line); - string_init(bad_usb->line_prev); + bad_usb->line = furi_string_alloc(); + bad_usb->line_prev = furi_string_alloc(); furi_hal_hid_set_state_callback(bad_usb_hid_state_callback, bad_usb); @@ -465,7 +465,7 @@ static int32_t bad_usb_worker(void* context) { if(worker_state == BadUsbStateInit) { // State: initialization if(storage_file_open( script_file, - string_get_cstr(bad_usb->file_path), + furi_string_get_cstr(bad_usb->file_path), FSAM_READ, FSOM_OPEN_EXISTING)) { if((ducky_script_preload(bad_usb, script_file)) && (bad_usb->st.line_nb > 0)) { @@ -577,20 +577,20 @@ static int32_t bad_usb_worker(void* context) { storage_file_close(script_file); storage_file_free(script_file); - string_clear(bad_usb->line); - string_clear(bad_usb->line_prev); + furi_string_free(bad_usb->line); + furi_string_free(bad_usb->line_prev); FURI_LOG_I(WORKER_TAG, "End"); return 0; } -BadUsbScript* bad_usb_script_open(string_t file_path) { +BadUsbScript* bad_usb_script_open(FuriString* file_path) { furi_assert(file_path); BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript)); - string_init(bad_usb->file_path); - string_set(bad_usb->file_path, file_path); + bad_usb->file_path = furi_string_alloc(); + furi_string_set(bad_usb->file_path, file_path); bad_usb->st.state = BadUsbStateInit; @@ -609,7 +609,7 @@ void bad_usb_script_close(BadUsbScript* bad_usb) { furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtEnd); furi_thread_join(bad_usb->thread); furi_thread_free(bad_usb->thread); - string_clear(bad_usb->file_path); + furi_string_free(bad_usb->file_path); free(bad_usb); } diff --git a/applications/main/bad_usb/bad_usb_script.h b/applications/main/bad_usb/bad_usb_script.h index 88921de3..5fee6505 100644 --- a/applications/main/bad_usb/bad_usb_script.h +++ b/applications/main/bad_usb/bad_usb_script.h @@ -5,7 +5,6 @@ extern "C" { #endif #include -#include typedef struct BadUsbScript BadUsbScript; @@ -28,7 +27,7 @@ typedef struct { uint16_t error_line; } BadUsbState; -BadUsbScript* bad_usb_script_open(string_t file_path); +BadUsbScript* bad_usb_script_open(FuriString* file_path); void bad_usb_script_close(BadUsbScript* bad_usb); diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_work.c b/applications/main/bad_usb/scenes/bad_usb_scene_work.c index 516cbde3..689f3b4e 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_work.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_work.c @@ -2,7 +2,6 @@ #include "../bad_usb_app_i.h" #include "../views/bad_usb_view.h" #include "furi_hal.h" -#include "m-string.h" #include "toolbox/path.h" void bad_usb_scene_work_ok_callback(InputType type, void* context) { @@ -27,14 +26,14 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) { void bad_usb_scene_work_on_enter(void* context) { BadUsbApp* app = context; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(app->file_path, file_name, true); - bad_usb_set_file_name(app->bad_usb_view, string_get_cstr(file_name)); + bad_usb_set_file_name(app->bad_usb_view, furi_string_get_cstr(file_name)); app->bad_usb_script = bad_usb_script_open(app->file_path); - string_clear(file_name); + furi_string_free(file_name); bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script)); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 0679669f..4e025b99 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -19,12 +19,12 @@ typedef struct { static void bad_usb_draw_callback(Canvas* canvas, void* _model) { BadUsbModel* model = _model; - string_t disp_str; - string_init_set_str(disp_str, model->file_name); + FuriString* disp_str; + disp_str = furi_string_alloc_set(model->file_name); elements_string_fit_width(canvas, disp_str, 128 - 2); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 8, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas_draw_str(canvas, 2, 8, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 22, 20, &I_UsbTree_48x22); @@ -49,10 +49,10 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:"); canvas_set_font(canvas, FontSecondary); - string_printf(disp_str, "line %u", model->state.error_line); + furi_string_printf(disp_str, "line %u", model->state.error_line); canvas_draw_str_aligned( - canvas, 127, 46, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); } else if(model->state.state == BadUsbStateIdle) { canvas_draw_icon(canvas, 4, 22, &I_Smile_18x18); canvas_set_font(canvas, FontBigNumbers); @@ -65,16 +65,17 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 4, 19, &I_EviSmile2_18x21); } canvas_set_font(canvas, FontBigNumbers); - string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); + furi_string_printf( + disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); canvas_draw_str_aligned( - canvas, 114, 36, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 114, 36, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); } else if(model->state.state == BadUsbStateDone) { canvas_draw_icon(canvas, 4, 19, &I_EviSmile1_18x21); canvas_set_font(canvas, FontBigNumbers); canvas_draw_str_aligned(canvas, 114, 36, AlignRight, AlignBottom, "100"); - string_reset(disp_str); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); } else if(model->state.state == BadUsbStateDelay) { if(model->anim_frame == 0) { @@ -83,21 +84,22 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 4, 19, &I_EviWaiting2_18x21); } canvas_set_font(canvas, FontBigNumbers); - string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); + furi_string_printf( + disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); canvas_draw_str_aligned( - canvas, 114, 36, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 114, 36, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); canvas_set_font(canvas, FontSecondary); - string_printf(disp_str, "delay %us", model->state.delay_remain); + furi_string_printf(disp_str, "delay %us", model->state.delay_remain); canvas_draw_str_aligned( - canvas, 127, 46, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); } else { canvas_draw_icon(canvas, 4, 22, &I_Clock_18x18); } - string_clear(disp_str); + furi_string_free(disp_str); } static bool bad_usb_input_callback(InputEvent* event, void* context) { diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index c0f60cec..1486cc1a 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -14,21 +14,24 @@ typedef struct { Storage* storage; DialogsApp* dialogs; Gui* gui; - string_t fap_path; + FuriString* fap_path; ViewDispatcher* view_dispatcher; Loading* loading; } FapLoader; -static bool - fap_loader_item_callback(string_t path, void* context, uint8_t** icon_ptr, string_t item_name) { +static bool fap_loader_item_callback( + FuriString* path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { FapLoader* loader = context; furi_assert(loader); FlipperApplication* app = flipper_application_alloc(loader->storage, &hashtable_api_interface); FlipperApplicationPreloadStatus preload_res = - flipper_application_preload_manifest(app, string_get_cstr(path)); + flipper_application_preload_manifest(app, furi_string_get_cstr(path)); bool load_success = false; @@ -37,10 +40,10 @@ static bool if(manifest->has_icon) { memcpy(*icon_ptr, manifest->icon, FAP_MANIFEST_MAX_ICON_SIZE); } - string_set_str(item_name, manifest->name); + furi_string_set(item_name, manifest->name); load_success = true; } else { - FURI_LOG_E(TAG, "FAP Loader failed to preload %s", string_get_cstr(path)); + FURI_LOG_E(TAG, "FAP Loader failed to preload %s", furi_string_get_cstr(path)); load_success = false; } @@ -51,9 +54,9 @@ static bool static bool fap_loader_run_selected_app(FapLoader* loader) { furi_assert(loader); - string_t error_message; + FuriString* error_message; - string_init_set(error_message, "unknown error"); + error_message = furi_string_alloc_set("unknown error"); bool file_selected = false; bool show_error = true; @@ -61,17 +64,17 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { file_selected = true; loader->app = flipper_application_alloc(loader->storage, &hashtable_api_interface); - FURI_LOG_I(TAG, "FAP Loader is loading %s", string_get_cstr(loader->fap_path)); + FURI_LOG_I(TAG, "FAP Loader is loading %s", furi_string_get_cstr(loader->fap_path)); FlipperApplicationPreloadStatus preload_res = - flipper_application_preload(loader->app, string_get_cstr(loader->fap_path)); + flipper_application_preload(loader->app, furi_string_get_cstr(loader->fap_path)); if(preload_res != FlipperApplicationPreloadStatusSuccess) { const char* err_msg = flipper_application_preload_status_to_string(preload_res); - string_printf(error_message, "Preload failed: %s", err_msg); + furi_string_printf(error_message, "Preload failed: %s", err_msg); FURI_LOG_E( TAG, "FAP Loader failed to preload %s: %s", - string_get_cstr(loader->fap_path), + furi_string_get_cstr(loader->fap_path), err_msg); break; } @@ -80,11 +83,11 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(loader->app); if(load_status != FlipperApplicationLoadStatusSuccess) { const char* err_msg = flipper_application_load_status_to_string(load_status); - string_printf(error_message, "Load failed: %s", err_msg); + furi_string_printf(error_message, "Load failed: %s", err_msg); FURI_LOG_E( TAG, "FAP Loader failed to map to memory %s: %s", - string_get_cstr(loader->fap_path), + furi_string_get_cstr(loader->fap_path), err_msg); break; } @@ -106,19 +109,19 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop); dialog_message_set_buttons(message, NULL, NULL, NULL); - string_t buffer; - string_init(buffer); - string_printf(buffer, "%s", string_get_cstr(error_message)); - string_replace_str(buffer, ":", "\n"); + FuriString* buffer; + buffer = furi_string_alloc(); + furi_string_printf(buffer, "%s", furi_string_get_cstr(error_message)); + furi_string_replace(buffer, ":", "\n"); dialog_message_set_text( - message, string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter); + message, furi_string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter); dialog_message_show(loader->dialogs, message); dialog_message_free(message); - string_clear(buffer); + furi_string_free(buffer); } - string_clear(error_message); + furi_string_free(error_message); if(file_selected) { flipper_application_free(loader->app); @@ -155,10 +158,10 @@ int32_t fap_loader_app(void* p) { view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading)); if(p) { - string_init_set(loader->fap_path, (const char*)p); + loader->fap_path = furi_string_alloc_set((const char*)p); fap_loader_run_selected_app(loader); } else { - string_init_set(loader->fap_path, EXT_PATH("apps")); + loader->fap_path = furi_string_alloc_set(EXT_PATH("apps")); while(fap_loader_select_app(loader)) { view_dispatcher_switch_to_view(loader->view_dispatcher, 0); @@ -170,7 +173,7 @@ int32_t fap_loader_app(void* p) { loading_free(loader->loading); view_dispatcher_free(loader->view_dispatcher); - string_clear(loader->fap_path); + furi_string_free(loader->fap_path); furi_record_close(RECORD_GUI); furi_record_close(RECORD_DIALOGS); furi_record_close(RECORD_STORAGE); diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index e9ec614e..887fb3e7 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -2,7 +2,6 @@ #include "assets_icons.h" #include "ibutton_i.h" #include "ibutton/scenes/ibutton_scene.h" -#include "m-string.h" #include #include #include @@ -39,25 +38,25 @@ static void ibutton_make_app_folder(iButton* ibutton) { } } -bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) { +bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog) { FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); bool result = false; - string_t data; - string_init(data); + FuriString* data; + data = furi_string_alloc(); do { - if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(key_path))) break; // header uint32_t version; if(!flipper_format_read_header(file, data, &version)) break; - if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; + if(furi_string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; if(version != 1) break; // key type iButtonKeyType type; if(!flipper_format_read_string(file, "Key type", data)) break; - if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; + if(!ibutton_key_get_type_by_string(furi_string_get_cstr(data), &type)) break; // key data uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; @@ -71,7 +70,7 @@ bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog } while(false); flipper_format_free(file); - string_clear(data); + furi_string_free(data); if((!result) && (show_dialog)) { dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file"); @@ -119,7 +118,7 @@ void ibutton_tick_event_callback(void* context) { iButton* ibutton_alloc() { iButton* ibutton = malloc(sizeof(iButton)); - string_init(ibutton->file_path); + ibutton->file_path = furi_string_alloc(); ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton); @@ -210,7 +209,7 @@ void ibutton_free(iButton* ibutton) { ibutton_worker_free(ibutton->key_worker); ibutton_key_free(ibutton->key); - string_clear(ibutton->file_path); + furi_string_free(ibutton->file_path); free(ibutton); } @@ -240,19 +239,19 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { do { // Check if we has old key - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { // First remove old key ibutton_delete_key(ibutton); // Remove old key name from path - size_t filename_start = string_search_rchar(ibutton->file_path, '/'); - string_left(ibutton->file_path, filename_start); + size_t filename_start = furi_string_search_rchar(ibutton->file_path, '/'); + furi_string_left(ibutton->file_path, filename_start); } - string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION); + furi_string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION); // Open file for write - if(!flipper_format_file_open_always(file, string_get_cstr(ibutton->file_path))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(ibutton->file_path))) break; // Write header if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break; @@ -286,7 +285,7 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { bool ibutton_delete_key(iButton* ibutton) { bool result = false; - result = storage_simply_remove(ibutton->storage, string_get_cstr(ibutton->file_path)); + result = storage_simply_remove(ibutton->storage, furi_string_get_cstr(ibutton->file_path)); return result; } @@ -326,7 +325,7 @@ int32_t ibutton_app(void* p) { rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton); rpc_system_app_send_started(ibutton->rpc_ctx); } else { - string_set_str(ibutton->file_path, (const char*)p); + furi_string_set(ibutton->file_path, (const char*)p); if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) { key_loaded = true; // TODO: Display an error if the key from p could not be loaded diff --git a/applications/main/ibutton/ibutton_cli.c b/applications/main/ibutton/ibutton_cli.c index d36d3dff..fab1ccf0 100644 --- a/applications/main/ibutton/ibutton_cli.c +++ b/applications/main/ibutton/ibutton_cli.c @@ -6,8 +6,8 @@ #include #include -static void ibutton_cli(Cli* cli, string_t args, void* context); -static void onewire_cli(Cli* cli, string_t args, void* context); +static void ibutton_cli(Cli* cli, FuriString* args, void* context); +static void onewire_cli(Cli* cli, FuriString* args, void* context); // app cli function void ibutton_on_system_start() { @@ -34,16 +34,16 @@ void ibutton_cli_print_usage() { printf("\t are hex-formatted\r\n"); }; -bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) { +bool ibutton_cli_get_key_type(FuriString* data, iButtonKeyType* type) { bool result = false; - if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) { + if(furi_string_cmp_str(data, "Dallas") == 0 || furi_string_cmp_str(data, "dallas") == 0) { result = true; *type = iButtonKeyDS1990; - } else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) { + } else if(furi_string_cmp_str(data, "Cyfral") == 0 || furi_string_cmp_str(data, "cyfral") == 0) { result = true; *type = iButtonKeyCyfral; - } else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) { + } else if(furi_string_cmp_str(data, "Metakom") == 0 || furi_string_cmp_str(data, "metakom") == 0) { result = true; *type = iButtonKeyMetakom; } @@ -123,17 +123,17 @@ static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult furi_event_flag_set(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE); } -void ibutton_cli_write(Cli* cli, string_t args) { +void ibutton_cli_write(Cli* cli, FuriString* args) { iButtonKey* key = ibutton_key_alloc(); iButtonWorker* worker = ibutton_worker_alloc(); iButtonKeyType type; iButtonWriteContext write_context; uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; - string_t data; + FuriString* data; write_context.event = furi_event_flag_alloc(); - string_init(data); + data = furi_string_alloc(); ibutton_worker_start_thread(worker); ibutton_worker_write_set_callback(worker, ibutton_cli_worker_write_cb, &write_context); @@ -186,7 +186,7 @@ void ibutton_cli_write(Cli* cli, string_t args) { ibutton_worker_stop(worker); } while(false); - string_clear(data); + furi_string_free(data); ibutton_worker_stop_thread(worker); ibutton_worker_free(worker); ibutton_key_free(key); @@ -194,14 +194,14 @@ void ibutton_cli_write(Cli* cli, string_t args) { furi_event_flag_free(write_context.event); }; -void ibutton_cli_emulate(Cli* cli, string_t args) { +void ibutton_cli_emulate(Cli* cli, FuriString* args) { iButtonKey* key = ibutton_key_alloc(); iButtonWorker* worker = ibutton_worker_alloc(); iButtonKeyType type; uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; - string_t data; + FuriString* data; - string_init(data); + data = furi_string_alloc(); ibutton_worker_start_thread(worker); do { @@ -234,34 +234,34 @@ void ibutton_cli_emulate(Cli* cli, string_t args) { ibutton_worker_stop(worker); } while(false); - string_clear(data); + furi_string_free(data); ibutton_worker_stop_thread(worker); ibutton_worker_free(worker); ibutton_key_free(key); }; -static void ibutton_cli(Cli* cli, string_t args, void* context) { +static void ibutton_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); ibutton_cli_print_usage(); return; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { ibutton_cli_read(cli); - } else if(string_cmp_str(cmd, "write") == 0) { + } else if(furi_string_cmp_str(cmd, "write") == 0) { ibutton_cli_write(cli, args); - } else if(string_cmp_str(cmd, "emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "emulate") == 0) { ibutton_cli_emulate(cli, args); } else { ibutton_cli_print_usage(); } - string_clear(cmd); + furi_string_free(cmd); } void onewire_cli_print_usage() { @@ -299,20 +299,20 @@ static void onewire_cli_search(Cli* cli) { onewire_host_free(onewire); } -void onewire_cli(Cli* cli, string_t args, void* context) { +void onewire_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); onewire_cli_print_usage(); return; } - if(string_cmp_str(cmd, "search") == 0) { + if(furi_string_cmp_str(cmd, "search") == 0) { onewire_cli_search(cli); } - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/main/ibutton/ibutton_i.h b/applications/main/ibutton/ibutton_i.h index fd11b8c1..a9515195 100644 --- a/applications/main/ibutton/ibutton_i.h +++ b/applications/main/ibutton/ibutton_i.h @@ -41,7 +41,7 @@ struct iButton { iButtonWorker* key_worker; iButtonKey* key; - string_t file_path; + FuriString* file_path; char text_store[IBUTTON_TEXT_STORE_SIZE + 1]; Submenu* submenu; @@ -78,7 +78,7 @@ typedef enum { } iButtonNotificationMessage; bool ibutton_file_select(iButton* ibutton); -bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog); +bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog); bool ibutton_save_key(iButton* ibutton, const char* key_name); bool ibutton_delete_key(iButton* ibutton); void ibutton_text_store_set(iButton* ibutton, const char* text, ...); diff --git a/applications/main/ibutton/scenes/ibutton_scene_add_type.c b/applications/main/ibutton/scenes/ibutton_scene_add_type.c index 9a0583a5..38373999 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_add_type.c +++ b/applications/main/ibutton/scenes/ibutton_scene_add_type.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" enum SubmenuIndex { SubmenuIndexCyfral, @@ -47,7 +46,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { furi_crash("Unknown key type"); } - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); ibutton_key_clear_data(key); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); } diff --git a/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c b/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c index fccefe6e..3d609e83 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c +++ b/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c @@ -17,11 +17,11 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { iButtonKey* key = ibutton->key; const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); + FuriString* key_name; + key_name = furi_string_alloc(); path_extract_filename(ibutton->file_path, key_name, true); - ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", furi_string_get_cstr(key_name)); widget_add_text_box_element( widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, true); widget_add_button_element( @@ -68,7 +68,7 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - string_clear(key_name); + furi_string_free(key_name); } bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_emulate.c b/applications/main/ibutton/scenes/ibutton_scene_emulate.c index e6e0ec68..b3bc38ea 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_emulate.c +++ b/applications/main/ibutton/scenes/ibutton_scene_emulate.c @@ -20,17 +20,17 @@ void ibutton_scene_emulate_on_enter(void* context) { const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } DOLPHIN_DEED(DolphinDeedIbuttonEmulate); // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + if(!furi_string_empty(key_name)) { + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } else { // if not, show key data switch(ibutton_key_get_type(key)) { @@ -69,7 +69,7 @@ void ibutton_scene_emulate_on_enter(void* context) { ibutton->key_worker, ibutton_scene_emulate_callback, ibutton); ibutton_worker_emulate_start(ibutton->key_worker, key); - string_clear(key_name); + furi_string_free(key_name); ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); } diff --git a/applications/main/ibutton/scenes/ibutton_scene_info.c b/applications/main/ibutton/scenes/ibutton_scene_info.c index 9eec2bee..15648f6f 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_info.c +++ b/applications/main/ibutton/scenes/ibutton_scene_info.c @@ -8,11 +8,11 @@ void ibutton_scene_info_on_enter(void* context) { const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); + FuriString* key_name; + key_name = furi_string_alloc(); path_extract_filename(ibutton->file_path, key_name, true); - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); widget_add_text_box_element( widget, 0, 0, 128, 23, AlignCenter, AlignCenter, ibutton->text_store, true); @@ -50,7 +50,7 @@ void ibutton_scene_info_on_enter(void* context) { view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - string_clear(key_name); + furi_string_free(key_name); } bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_read.c b/applications/main/ibutton/scenes/ibutton_scene_read.c index 7af351f0..05920a0a 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_read.c +++ b/applications/main/ibutton/scenes/ibutton_scene_read.c @@ -18,7 +18,7 @@ void ibutton_scene_read_on_enter(void* context) { popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton); ibutton_worker_read_start(worker, key); diff --git a/applications/main/ibutton/scenes/ibutton_scene_rpc.c b/applications/main/ibutton/scenes/ibutton_scene_rpc.c index 0755c8ff..b25b1b8d 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/main/ibutton/scenes/ibutton_scene_rpc.c @@ -29,19 +29,19 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.event == iButtonCustomEventRpcLoad) { const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx); bool result = false; - if(arg && (string_empty_p(ibutton->file_path))) { - string_set_str(ibutton->file_path, arg); + if(arg && (furi_string_empty(ibutton->file_path))) { + furi_string_set(ibutton->file_path, arg); if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - if(!string_empty_p(key_name)) { + if(!furi_string_empty(key_name)) { ibutton_text_store_set( - ibutton, "emulating\n%s", string_get_cstr(key_name)); + ibutton, "emulating\n%s", furi_string_get_cstr(key_name)); } else { ibutton_text_store_set(ibutton, "emulating"); } @@ -49,10 +49,10 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); - string_clear(key_name); + furi_string_free(key_name); result = true; } else { - string_reset(ibutton->file_path); + furi_string_reset(ibutton->file_path); } } rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result); diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_name.c b/applications/main/ibutton/scenes/ibutton_scene_save_name.c index be640387..773b93e0 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_save_name.c +++ b/applications/main/ibutton/scenes/ibutton_scene_save_name.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" #include #include @@ -12,17 +11,17 @@ void ibutton_scene_save_name_on_enter(void* context) { iButton* ibutton = context; TextInput* text_input = ibutton->text_input; - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - const bool key_name_is_empty = string_empty_p(key_name); + const bool key_name_is_empty = furi_string_empty(key_name); if(key_name_is_empty) { set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE); } else { - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } text_input_set_header_text(text_input, "Name the key"); @@ -34,19 +33,19 @@ void ibutton_scene_save_name_on_enter(void* context) { IBUTTON_KEY_NAME_SIZE, key_name_is_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - path_extract_dirname(string_get_cstr(ibutton->file_path), folder_path); + path_extract_dirname(furi_string_get_cstr(ibutton->file_path), folder_path); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, string_get_cstr(key_name)); + furi_string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, furi_string_get_cstr(key_name)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); - string_clear(key_name); - string_clear(folder_path); + furi_string_free(key_name); + furi_string_free(folder_path); } bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_start.c b/applications/main/ibutton/scenes/ibutton_scene_start.c index c2844cde..dde224e1 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_start.c +++ b/applications/main/ibutton/scenes/ibutton_scene_start.c @@ -39,7 +39,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexRead) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); } else if(event.event == SubmenuIndexSaved) { - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey); } else if(event.event == SubmenuIndexAdd) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType); diff --git a/applications/main/ibutton/scenes/ibutton_scene_write.c b/applications/main/ibutton/scenes/ibutton_scene_write.c index af65575c..cdea04db 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_write.c +++ b/applications/main/ibutton/scenes/ibutton_scene_write.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" #include "toolbox/path.h" typedef enum { @@ -20,15 +19,15 @@ void ibutton_scene_write_on_enter(void* context) { const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + if(!furi_string_empty(key_name)) { + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } else { // if not, show key data switch(ibutton_key_get_type(key)) { @@ -66,7 +65,7 @@ void ibutton_scene_write_on_enter(void* context) { ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton); ibutton_worker_write_start(worker, key); - string_clear(key_name); + furi_string_free(key_name); ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); } diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index 60809e78..a647b158 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -65,51 +65,52 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context } } -static void infrared_find_vacant_remote_name(string_t name, const char* path) { +static void infrared_find_vacant_remote_name(FuriString* name, const char* path) { Storage* storage = furi_record_open(RECORD_STORAGE); - string_t base_path; - string_init_set_str(base_path, path); + FuriString* base_path; + base_path = furi_string_alloc_set(path); - if(string_end_with_str_p(base_path, INFRARED_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(base_path, '/'); - string_left(base_path, filename_start); + if(furi_string_end_with(base_path, INFRARED_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(base_path, '/'); + furi_string_left(base_path, filename_start); } - string_printf(base_path, "%s/%s%s", path, string_get_cstr(name), INFRARED_APP_EXTENSION); + furi_string_printf( + base_path, "%s/%s%s", path, furi_string_get_cstr(name), INFRARED_APP_EXTENSION); - FS_Error status = storage_common_stat(storage, string_get_cstr(base_path), NULL); + FS_Error status = storage_common_stat(storage, furi_string_get_cstr(base_path), NULL); if(status == FSE_OK) { /* If the suggested name is occupied, try another one (name2, name3, etc) */ - size_t dot = string_search_rchar(base_path, '.'); - string_left(base_path, dot); + size_t dot = furi_string_search_rchar(base_path, '.'); + furi_string_left(base_path, dot); - string_t path_temp; - string_init(path_temp); + FuriString* path_temp; + path_temp = furi_string_alloc(); uint32_t i = 1; do { - string_printf( - path_temp, "%s%u%s", string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); - status = storage_common_stat(storage, string_get_cstr(path_temp), NULL); + furi_string_printf( + path_temp, "%s%u%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); + status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL); } while(status == FSE_OK); - string_clear(path_temp); + furi_string_free(path_temp); if(status == FSE_NOT_EXIST) { - string_cat_printf(name, "%u", i); + furi_string_cat_printf(name, "%u", i); } } - string_clear(base_path); + furi_string_free(base_path); furi_record_close(RECORD_STORAGE); } static Infrared* infrared_alloc() { Infrared* infrared = malloc(sizeof(Infrared)); - string_init(infrared->file_path); + infrared->file_path = furi_string_alloc(); InfraredAppState* app_state = &infrared->app_state; app_state->is_learning_new_remote = false; @@ -232,7 +233,7 @@ static void infrared_free(Infrared* infrared) { furi_record_close(RECORD_GUI); infrared->gui = NULL; - string_clear(infrared->file_path); + furi_string_free(infrared->file_path); free(infrared); } @@ -243,19 +244,20 @@ bool infrared_add_remote_with_button( InfraredSignal* signal) { InfraredRemote* remote = infrared->remote; - string_t new_name, new_path; - string_init_set_str(new_name, INFRARED_DEFAULT_REMOTE_NAME); - string_init_set_str(new_path, INFRARED_APP_FOLDER); + FuriString *new_name, *new_path; + new_name = furi_string_alloc_set(INFRARED_DEFAULT_REMOTE_NAME); + new_path = furi_string_alloc_set(INFRARED_APP_FOLDER); - infrared_find_vacant_remote_name(new_name, string_get_cstr(new_path)); - string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION); + infrared_find_vacant_remote_name(new_name, furi_string_get_cstr(new_path)); + furi_string_cat_printf( + new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION); infrared_remote_reset(remote); - infrared_remote_set_name(remote, string_get_cstr(new_name)); - infrared_remote_set_path(remote, string_get_cstr(new_path)); + infrared_remote_set_name(remote, furi_string_get_cstr(new_name)); + infrared_remote_set_path(remote, furi_string_get_cstr(new_path)); - string_clear(new_name); - string_clear(new_path); + furi_string_free(new_name); + furi_string_free(new_path); return infrared_remote_add_button(remote, button_name, signal); } @@ -267,28 +269,29 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) { return true; } - string_t new_name; - string_init_set_str(new_name, name); + FuriString* new_name; + new_name = furi_string_alloc_set(name); infrared_find_vacant_remote_name(new_name, remote_path); - string_t new_path; - string_init_set(new_path, infrared_remote_get_path(remote)); - if(string_end_with_str_p(new_path, INFRARED_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(new_path, '/'); - string_left(new_path, filename_start); + FuriString* new_path; + new_path = furi_string_alloc_set(infrared_remote_get_path(remote)); + if(furi_string_end_with(new_path, INFRARED_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(new_path, '/'); + furi_string_left(new_path, filename_start); } - string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION); + furi_string_cat_printf( + new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION); Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error status = storage_common_rename( - storage, infrared_remote_get_path(remote), string_get_cstr(new_path)); - infrared_remote_set_name(remote, string_get_cstr(new_name)); - infrared_remote_set_path(remote, string_get_cstr(new_path)); + storage, infrared_remote_get_path(remote), furi_string_get_cstr(new_path)); + infrared_remote_set_name(remote, furi_string_get_cstr(new_name)); + infrared_remote_set_path(remote, furi_string_get_cstr(new_path)); - string_clear(new_name); - string_clear(new_path); + furi_string_free(new_name); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); return (status == FSE_OK || status == FSE_EXIST); @@ -435,7 +438,7 @@ int32_t infrared_app(void* p) { rpc_system_app_send_started(infrared->rpc_ctx); is_rpc_mode = true; } else { - string_set_str(infrared->file_path, (const char*)p); + furi_string_set(infrared->file_path, (const char*)p); is_remote_loaded = infrared_remote_load(infrared->remote, infrared->file_path); if(!is_remote_loaded) { dialog_message_show_storage_error( diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 0edc5f74..3f426f1d 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -2,7 +2,6 @@ #include #include -#include #include #include "infrared_signal.h" @@ -14,15 +13,15 @@ typedef struct { DICT_DEF2( InfraredBruteForceRecordDict, - string_t, - STRING_OPLIST, + FuriString*, + FURI_STRING_OPLIST, InfraredBruteForceRecord, M_POD_OPLIST); struct InfraredBruteForce { FlipperFormat* ff; const char* db_filename; - string_t current_record_name; + FuriString* current_record_name; InfraredSignal* current_signal; InfraredBruteForceRecordDict_t records; bool is_started; @@ -34,7 +33,7 @@ InfraredBruteForce* infrared_brute_force_alloc() { brute_force->db_filename = NULL; brute_force->current_signal = NULL; brute_force->is_started = false; - string_init(brute_force->current_record_name); + brute_force->current_record_name = furi_string_alloc(); InfraredBruteForceRecordDict_init(brute_force->records); return brute_force; } @@ -42,7 +41,7 @@ InfraredBruteForce* infrared_brute_force_alloc() { void infrared_brute_force_free(InfraredBruteForce* brute_force) { furi_assert(!brute_force->is_started); InfraredBruteForceRecordDict_clear(brute_force->records); - string_clear(brute_force->current_record_name); + furi_string_free(brute_force->current_record_name); free(brute_force); } @@ -61,8 +60,8 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename); if(success) { - string_t signal_name; - string_init(signal_name); + FuriString* signal_name; + signal_name = furi_string_alloc(); while(flipper_format_read_string(ff, "name", signal_name)) { InfraredBruteForceRecord* record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); @@ -70,7 +69,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { ++(record->count); } } - string_clear(signal_name); + furi_string_free(signal_name); } flipper_format_free(ff); @@ -94,7 +93,7 @@ bool infrared_brute_force_start( if(record->value.index == index) { *record_count = record->value.count; if(*record_count) { - string_set(brute_force->current_record_name, record->key); + furi_string_set(brute_force->current_record_name, record->key); } break; } @@ -118,7 +117,7 @@ bool infrared_brute_force_is_started(InfraredBruteForce* brute_force) { void infrared_brute_force_stop(InfraredBruteForce* brute_force) { furi_assert(brute_force->is_started); - string_reset(brute_force->current_record_name); + furi_string_reset(brute_force->current_record_name); infrared_signal_free(brute_force->current_signal); flipper_format_free(brute_force->ff); brute_force->current_signal = NULL; @@ -142,10 +141,10 @@ void infrared_brute_force_add_record( uint32_t index, const char* name) { InfraredBruteForceRecord value = {.index = index, .count = 0}; - string_t key; - string_init_set_str(key, name); + FuriString* key; + key = furi_string_alloc_set(name); InfraredBruteForceRecordDict_set_at(brute_force->records, key, value); - string_clear(key); + furi_string_free(key); } void infrared_brute_force_reset(InfraredBruteForce* brute_force) { diff --git a/applications/main/infrared/infrared_cli.c b/applications/main/infrared/infrared_cli.c index 693e191e..5ec57c75 100644 --- a/applications/main/infrared/infrared_cli.c +++ b/applications/main/infrared/infrared_cli.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -10,13 +9,13 @@ #define INFRARED_CLI_BUF_SIZE 10 -static void infrared_cli_start_ir_rx(Cli* cli, string_t args); -static void infrared_cli_start_ir_tx(Cli* cli, string_t args); -static void infrared_cli_process_decode(Cli* cli, string_t args); +static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args); +static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args); +static void infrared_cli_process_decode(Cli* cli, FuriString* args); static const struct { const char* cmd; - void (*process_function)(Cli* cli, string_t args); + void (*process_function)(Cli* cli, FuriString* args); } infrared_cli_commands[] = { {.cmd = "rx", .process_function = infrared_cli_start_ir_rx}, {.cmd = "tx", .process_function = infrared_cli_start_ir_tx}, @@ -58,7 +57,7 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv } } -static void infrared_cli_start_ir_rx(Cli* cli, string_t args) { +static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); InfraredWorker* worker = infrared_worker_alloc(); @@ -151,9 +150,9 @@ static bool infrared_cli_parse_raw(const char* str, InfraredSignal* signal) { return infrared_signal_is_valid(signal); } -static void infrared_cli_start_ir_tx(Cli* cli, string_t args) { +static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args) { UNUSED(cli); - const char* str = string_get_cstr(args); + const char* str = furi_string_get_cstr(args); InfraredSignal* signal = infrared_signal_alloc(); bool success = infrared_cli_parse_message(str, signal) || infrared_cli_parse_raw(str, signal); @@ -231,8 +230,8 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o InfraredSignal* signal = infrared_signal_alloc(); InfraredDecoderHandler* decoder = infrared_alloc_decoder(); - string_t tmp; - string_init(tmp); + FuriString* tmp; + tmp = furi_string_alloc(); while(infrared_signal_read(signal, input_file, tmp)) { ret = false; @@ -242,7 +241,7 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o } if(!infrared_signal_is_raw(signal)) { if(output_file && - !infrared_cli_save_signal(signal, output_file, string_get_cstr(tmp))) { + !infrared_cli_save_signal(signal, output_file, furi_string_get_cstr(tmp))) { break; } else { printf("Skipping decoded signal\r\n"); @@ -250,31 +249,33 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o } } InfraredRawSignal* raw_signal = infrared_signal_get_raw_signal(signal); - printf("Raw signal: %s, %u samples\r\n", string_get_cstr(tmp), raw_signal->timings_size); - if(!infrared_cli_decode_raw_signal(raw_signal, decoder, output_file, string_get_cstr(tmp))) + printf( + "Raw signal: %s, %u samples\r\n", furi_string_get_cstr(tmp), raw_signal->timings_size); + if(!infrared_cli_decode_raw_signal( + raw_signal, decoder, output_file, furi_string_get_cstr(tmp))) break; ret = true; } infrared_free_decoder(decoder); infrared_signal_free(signal); - string_clear(tmp); + furi_string_free(tmp); return ret; } -static void infrared_cli_process_decode(Cli* cli, string_t args) { +static void infrared_cli_process_decode(Cli* cli, FuriString* args) { UNUSED(cli); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* input_file = flipper_format_buffered_file_alloc(storage); FlipperFormat* output_file = NULL; uint32_t version; - string_t tmp, header, input_path, output_path; - string_init(tmp); - string_init(header); - string_init(input_path); - string_init(output_path); + FuriString *tmp, *header, *input_path, *output_path; + tmp = furi_string_alloc(); + header = furi_string_alloc(); + input_path = furi_string_alloc(); + output_path = furi_string_alloc(); do { if(!args_read_probably_quoted_string_and_trim(args, input_path)) { @@ -283,26 +284,32 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) { break; } args_read_probably_quoted_string_and_trim(args, output_path); - if(!flipper_format_buffered_file_open_existing(input_file, string_get_cstr(input_path))) { - printf("Failed to open file for reading: \"%s\"\r\n", string_get_cstr(input_path)); + if(!flipper_format_buffered_file_open_existing( + input_file, furi_string_get_cstr(input_path))) { + printf( + "Failed to open file for reading: \"%s\"\r\n", furi_string_get_cstr(input_path)); break; } if(!flipper_format_read_header(input_file, header, &version) || - (!string_start_with_str_p(header, "IR")) || version != 1) { - printf("Invalid or corrupted input file: \"%s\"\r\n", string_get_cstr(input_path)); + (!furi_string_start_with_str(header, "IR")) || version != 1) { + printf( + "Invalid or corrupted input file: \"%s\"\r\n", furi_string_get_cstr(input_path)); break; } - if(!string_empty_p(output_path)) { - printf("Writing output to file: \"%s\"\r\n", string_get_cstr(output_path)); + if(!furi_string_empty(output_path)) { + printf("Writing output to file: \"%s\"\r\n", furi_string_get_cstr(output_path)); output_file = flipper_format_file_alloc(storage); } if(output_file && - !flipper_format_file_open_always(output_file, string_get_cstr(output_path))) { - printf("Failed to open file for writing: \"%s\"\r\n", string_get_cstr(output_path)); + !flipper_format_file_open_always(output_file, furi_string_get_cstr(output_path))) { + printf( + "Failed to open file for writing: \"%s\"\r\n", furi_string_get_cstr(output_path)); break; } if(output_file && !flipper_format_write_header(output_file, header, version)) { - printf("Failed to write to the output file: \"%s\"\r\n", string_get_cstr(output_path)); + printf( + "Failed to write to the output file: \"%s\"\r\n", + furi_string_get_cstr(output_path)); break; } if(!infrared_cli_decode_file(input_file, output_file)) { @@ -311,31 +318,31 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) { printf("File successfully decoded.\r\n"); } while(false); - string_clear(tmp); - string_clear(header); - string_clear(input_path); - string_clear(output_path); + furi_string_free(tmp); + furi_string_free(header); + furi_string_free(input_path); + furi_string_free(output_path); flipper_format_free(input_file); if(output_file) flipper_format_free(output_file); furi_record_close(RECORD_STORAGE); } -static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { +static void infrared_cli_start_ir(Cli* cli, FuriString* args, void* context) { UNUSED(context); if(furi_hal_infrared_is_busy()) { printf("INFRARED is busy. Exiting."); return; } - string_t command; - string_init(command); + FuriString* command; + command = furi_string_alloc(); args_read_string_and_trim(args, command); size_t i = 0; for(; i < COUNT_OF(infrared_cli_commands); ++i) { size_t cmd_len = strlen(infrared_cli_commands[i].cmd); - if(!strncmp(string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) { + if(!strncmp(furi_string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) { break; } } @@ -346,7 +353,7 @@ static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { infrared_cli_print_usage(); } - string_clear(command); + furi_string_free(command); } void infrared_on_system_start() { #ifdef SRV_CLI diff --git a/applications/main/infrared/infrared_i.h b/applications/main/infrared/infrared_i.h index 95215258..6d25d160 100644 --- a/applications/main/infrared/infrared_i.h +++ b/applications/main/infrared/infrared_i.h @@ -96,7 +96,7 @@ struct Infrared { Loading* loading; InfraredProgressView* progress; - string_t file_path; + FuriString* file_path; char text_store[INFRARED_TEXT_STORE_NUM][INFRARED_TEXT_STORE_SIZE + 1]; InfraredAppState app_state; diff --git a/applications/main/infrared/infrared_remote.c b/applications/main/infrared/infrared_remote.c index 4417c3c7..3a528a65 100644 --- a/applications/main/infrared/infrared_remote.c +++ b/applications/main/infrared/infrared_remote.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -15,8 +14,8 @@ ARRAY_DEF(InfraredButtonArray, InfraredRemoteButton*, M_PTR_OPLIST); struct InfraredRemote { InfraredButtonArray_t buttons; - string_t name; - string_t path; + FuriString* name; + FuriString* path; }; static void infrared_remote_clear_buttons(InfraredRemote* remote) { @@ -31,39 +30,39 @@ static void infrared_remote_clear_buttons(InfraredRemote* remote) { InfraredRemote* infrared_remote_alloc() { InfraredRemote* remote = malloc(sizeof(InfraredRemote)); InfraredButtonArray_init(remote->buttons); - string_init(remote->name); - string_init(remote->path); + remote->name = furi_string_alloc(); + remote->path = furi_string_alloc(); return remote; } void infrared_remote_free(InfraredRemote* remote) { infrared_remote_clear_buttons(remote); InfraredButtonArray_clear(remote->buttons); - string_clear(remote->path); - string_clear(remote->name); + furi_string_free(remote->path); + furi_string_free(remote->name); free(remote); } void infrared_remote_reset(InfraredRemote* remote) { infrared_remote_clear_buttons(remote); - string_reset(remote->name); - string_reset(remote->path); + furi_string_reset(remote->name); + furi_string_reset(remote->path); } void infrared_remote_set_name(InfraredRemote* remote, const char* name) { - string_set_str(remote->name, name); + furi_string_set(remote->name, name); } const char* infrared_remote_get_name(InfraredRemote* remote) { - return string_get_cstr(remote->name); + return furi_string_get_cstr(remote->name); } void infrared_remote_set_path(InfraredRemote* remote, const char* path) { - string_set_str(remote->path, path); + furi_string_set(remote->path, path); } const char* infrared_remote_get_path(InfraredRemote* remote) { - return string_get_cstr(remote->path); + return furi_string_get_cstr(remote->path); } size_t infrared_remote_get_button_count(InfraredRemote* remote) { @@ -112,7 +111,7 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { bool infrared_remote_store(InfraredRemote* remote) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_file_alloc(storage); - const char* path = string_get_cstr(remote->path); + const char* path = furi_string_get_cstr(remote->path); FURI_LOG_I(TAG, "store file: \'%s\'", path); @@ -138,33 +137,33 @@ bool infrared_remote_store(InfraredRemote* remote) { return success; } -bool infrared_remote_load(InfraredRemote* remote, string_t path) { +bool infrared_remote_load(InfraredRemote* remote, FuriString* path) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); - FURI_LOG_I(TAG, "load file: \'%s\'", string_get_cstr(path)); - bool success = flipper_format_buffered_file_open_existing(ff, string_get_cstr(path)); + FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path)); + bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path)); if(success) { uint32_t version; success = flipper_format_read_header(ff, buf, &version) && - !string_cmp_str(buf, "IR signals file") && (version == 1); + !furi_string_cmp(buf, "IR signals file") && (version == 1); } if(success) { path_extract_filename(path, buf, true); infrared_remote_clear_buttons(remote); - infrared_remote_set_name(remote, string_get_cstr(buf)); - infrared_remote_set_path(remote, string_get_cstr(path)); + infrared_remote_set_name(remote, furi_string_get_cstr(buf)); + infrared_remote_set_path(remote, furi_string_get_cstr(path)); for(bool can_read = true; can_read;) { InfraredRemoteButton* button = infrared_remote_button_alloc(); can_read = infrared_signal_read(infrared_remote_button_get_signal(button), ff, buf); if(can_read) { - infrared_remote_button_set_name(button, string_get_cstr(buf)); + infrared_remote_button_set_name(button, furi_string_get_cstr(buf)); InfraredButtonArray_push_back(remote->buttons, button); } else { infrared_remote_button_free(button); @@ -172,7 +171,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) { } } - string_clear(buf); + furi_string_free(buf); flipper_format_free(ff); furi_record_close(RECORD_STORAGE); return success; @@ -181,7 +180,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) { bool infrared_remote_remove(InfraredRemote* remote) { Storage* storage = furi_record_open(RECORD_STORAGE); - FS_Error status = storage_common_remove(storage, string_get_cstr(remote->path)); + FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path)); infrared_remote_reset(remote); furi_record_close(RECORD_STORAGE); diff --git a/applications/main/infrared/infrared_remote.h b/applications/main/infrared/infrared_remote.h index b6f63a19..6eac193d 100644 --- a/applications/main/infrared/infrared_remote.h +++ b/applications/main/infrared/infrared_remote.h @@ -25,5 +25,5 @@ bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); bool infrared_remote_store(InfraredRemote* remote); -bool infrared_remote_load(InfraredRemote* remote, string_t path); +bool infrared_remote_load(InfraredRemote* remote, FuriString* path); bool infrared_remote_remove(InfraredRemote* remote); diff --git a/applications/main/infrared/infrared_remote_button.c b/applications/main/infrared/infrared_remote_button.c index 7525ce48..1f6315ec 100644 --- a/applications/main/infrared/infrared_remote_button.c +++ b/applications/main/infrared/infrared_remote_button.c @@ -1,32 +1,31 @@ #include "infrared_remote_button.h" #include -#include struct InfraredRemoteButton { - string_t name; + FuriString* name; InfraredSignal* signal; }; InfraredRemoteButton* infrared_remote_button_alloc() { InfraredRemoteButton* button = malloc(sizeof(InfraredRemoteButton)); - string_init(button->name); + button->name = furi_string_alloc(); button->signal = infrared_signal_alloc(); return button; } void infrared_remote_button_free(InfraredRemoteButton* button) { - string_clear(button->name); + furi_string_free(button->name); infrared_signal_free(button->signal); free(button); } void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name) { - string_set_str(button->name, name); + furi_string_set(button->name, name); } const char* infrared_remote_button_get_name(InfraredRemoteButton* button) { - return string_get_cstr(button->name); + return furi_string_get_cstr(button->name); } void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal) { diff --git a/applications/main/infrared/infrared_signal.c b/applications/main/infrared/infrared_signal.c index f2e359c8..30459d60 100644 --- a/applications/main/infrared/infrared_signal.c +++ b/applications/main/infrared/infrared_signal.c @@ -100,15 +100,15 @@ static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperForma } static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { if(!flipper_format_read_string(ff, "protocol", buf)) break; InfraredMessage message; - message.protocol = infrared_get_protocol_by_name(string_get_cstr(buf)); + message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) && flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) && @@ -119,7 +119,7 @@ static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperF infrared_signal_set_message(signal, &message); } while(0); - string_clear(buf); + furi_string_free(buf); return success; } @@ -147,22 +147,22 @@ static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperForma } static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) { - string_t tmp; - string_init(tmp); + FuriString* tmp = furi_string_alloc(); + bool success = false; do { if(!flipper_format_read_string(ff, "type", tmp)) break; - if(string_equal_p(tmp, "raw")) { + if(furi_string_equal(tmp, "raw")) { success = infrared_signal_read_raw(signal, ff); - } else if(string_equal_p(tmp, "parsed")) { + } else if(furi_string_equal(tmp, "parsed")) { success = infrared_signal_read_message(signal, ff); } else { FURI_LOG_E(TAG, "Unknown signal type"); } } while(false); - string_clear(tmp); + furi_string_free(tmp); return success; } @@ -246,34 +246,33 @@ bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* } } -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name) { - string_t tmp; - string_init(tmp); +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) { + FuriString* tmp = furi_string_alloc(); + bool success = false; do { if(!flipper_format_read_string(ff, "name", tmp)) break; - string_set(name, tmp); + furi_string_set(name, tmp); if(!infrared_signal_read_body(signal, ff)) break; success = true; } while(0); - string_clear(tmp); + furi_string_free(tmp); return success; } bool infrared_signal_search_and_read( InfraredSignal* signal, FlipperFormat* ff, - const string_t name) { + const FuriString* name) { bool success = false; - string_t tmp; - string_init(tmp); + FuriString* tmp = furi_string_alloc(); do { bool is_name_found = false; while(flipper_format_read_string(ff, "name", tmp)) { - is_name_found = string_equal_p(name, tmp); + is_name_found = furi_string_equal(name, tmp); if(is_name_found) break; } if(!is_name_found) break; @@ -281,7 +280,7 @@ bool infrared_signal_search_and_read( success = true; } while(false); - string_clear(tmp); + furi_string_free(tmp); return success; } diff --git a/applications/main/infrared/infrared_signal.h b/applications/main/infrared/infrared_signal.h index ad2f5d57..29c66193 100644 --- a/applications/main/infrared/infrared_signal.h +++ b/applications/main/infrared/infrared_signal.h @@ -36,10 +36,10 @@ void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* InfraredMessage* infrared_signal_get_message(InfraredSignal* signal); bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name); -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name); +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name); bool infrared_signal_search_and_read( InfraredSignal* signal, FlipperFormat* ff, - const string_t name); + const FuriString* name); void infrared_signal_transmit(InfraredSignal* signal); diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename.c b/applications/main/infrared/scenes/infrared_scene_edit_rename.c index ebe7c2a9..a2199215 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_rename.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_rename.c @@ -29,20 +29,20 @@ void infrared_scene_edit_rename_on_enter(void* context) { enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH; strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(infrared->file_path, INFRARED_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(infrared->file_path), folder_path); + if(furi_string_end_with(infrared->file_path, INFRARED_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(infrared->file_path), folder_path); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), + furi_string_get_cstr(folder_path), INFRARED_APP_EXTENSION, infrared_remote_get_name(remote)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(folder_path); + furi_string_free(folder_path); } else { furi_assert(0); } diff --git a/applications/main/infrared/scenes/infrared_scene_rpc.c b/applications/main/infrared/scenes/infrared_scene_rpc.c index ca7bbd8d..8044e831 100644 --- a/applications/main/infrared/scenes/infrared_scene_rpc.c +++ b/applications/main/infrared/scenes/infrared_scene_rpc.c @@ -42,7 +42,7 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); if(arg && (state == InfraredRpcStateIdle)) { - string_set_str(infrared->file_path, arg); + furi_string_set(infrared->file_path, arg); result = infrared_remote_load(infrared->remote, infrared->file_path); if(result) { scene_manager_set_scene_state( diff --git a/applications/main/infrared/scenes/infrared_scene_start.c b/applications/main/infrared/scenes/infrared_scene_start.c index d188a6c3..c7df0f45 100644 --- a/applications/main/infrared/scenes/infrared_scene_start.c +++ b/applications/main/infrared/scenes/infrared_scene_start.c @@ -66,7 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(scene_manager, InfraredSceneLearn); consumed = true; } else if(submenu_index == SubmenuIndexSavedRemotes) { - string_set_str(infrared->file_path, INFRARED_APP_FOLDER); + furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); consumed = true; } else if(submenu_index == SubmenuIndexDebug) { diff --git a/applications/main/infrared/views/infrared_progress_view.c b/applications/main/infrared/views/infrared_progress_view.c index 5c84ce0d..3c50f89e 100644 --- a/applications/main/infrared/views/infrared_progress_view.c +++ b/applications/main/infrared/views/infrared_progress_view.c @@ -4,7 +4,6 @@ #include "gui/canvas.h" #include "gui/view.h" #include "input/input.h" -#include "m-string.h" #include #include #include "infrared_progress_view.h" diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index dbed9f3a..b0f98937 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -36,9 +36,9 @@ static LfRfid* lfrfid_alloc() { lfrfid->storage = furi_record_open(RECORD_STORAGE); lfrfid->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(lfrfid->file_name); - string_init(lfrfid->raw_file_name); - string_init_set_str(lfrfid->file_path, LFRFID_APP_FOLDER); + lfrfid->file_name = furi_string_alloc(); + lfrfid->raw_file_name = furi_string_alloc(); + lfrfid->file_path = furi_string_alloc_set(LFRFID_APP_FOLDER); lfrfid->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); @@ -104,9 +104,9 @@ static LfRfid* lfrfid_alloc() { static void lfrfid_free(LfRfid* lfrfid) { furi_assert(lfrfid); - string_clear(lfrfid->raw_file_name); - string_clear(lfrfid->file_name); - string_clear(lfrfid->file_path); + furi_string_free(lfrfid->raw_file_name); + furi_string_free(lfrfid->file_name); + furi_string_free(lfrfid->file_path); protocol_dict_free(lfrfid->dict); lfrfid_worker_free(lfrfid->lfworker); @@ -183,7 +183,7 @@ int32_t lfrfid_app(void* p) { app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc); } else { - string_set_str(app->file_path, args); + furi_string_set(app->file_path, args); lfrfid_load_key_data(app, app->file_path, true); view_dispatcher_attach_to_gui( app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); @@ -210,13 +210,13 @@ bool lfrfid_save_key(LfRfid* app) { lfrfid_make_app_folder(app); - if(string_end_with_str_p(app->file_path, LFRFID_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(app->file_path, '/'); - string_left(app->file_path, filename_start); + if(furi_string_end_with(app->file_path, LFRFID_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(app->file_path, '/'); + furi_string_left(app->file_path, filename_start); } - string_cat_printf( - app->file_path, "/%s%s", string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); + furi_string_cat_printf( + app->file_path, "/%s%s", furi_string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); result = lfrfid_save_key_data(app, app->file_path); return result; @@ -242,14 +242,14 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { bool lfrfid_delete_key(LfRfid* app) { furi_assert(app); - return storage_simply_remove(app->storage, string_get_cstr(app->file_path)); + return storage_simply_remove(app->storage, furi_string_get_cstr(app->file_path)); } -bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) { +bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog) { bool result = false; do { - app->protocol_id = lfrfid_dict_file_load(app->dict, string_get_cstr(path)); + app->protocol_id = lfrfid_dict_file_load(app->dict, furi_string_get_cstr(path)); if(app->protocol_id == PROTOCOL_NO) break; path_extract_filename(path, app->file_name, true); @@ -263,8 +263,8 @@ bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) { return result; } -bool lfrfid_save_key_data(LfRfid* app, string_t path) { - bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, string_get_cstr(path)); +bool lfrfid_save_key_data(LfRfid* app, FuriString* path) { + bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, furi_string_get_cstr(path)); if(!result) { dialog_message_show_storage_error(app->dialogs, "Cannot save\nkey file"); diff --git a/applications/main/lfrfid/lfrfid_cli.c b/applications/main/lfrfid/lfrfid_cli.c index 281a0e96..64027452 100644 --- a/applications/main/lfrfid/lfrfid_cli.c +++ b/applications/main/lfrfid/lfrfid_cli.c @@ -14,7 +14,7 @@ #include #include -static void lfrfid_cli(Cli* cli, string_t args, void* context); +static void lfrfid_cli(Cli* cli, FuriString* args, void* context); // app cli function void lfrfid_on_system_start() { @@ -46,27 +46,28 @@ static void lfrfid_cli_read_callback(LFRFIDWorkerReadResult result, ProtocolId p furi_event_flag_set(context->event, 1 << result); } -static void lfrfid_cli_read(Cli* cli, string_t args) { - string_t type_string; - string_init(type_string); +static void lfrfid_cli_read(Cli* cli, FuriString* args) { + FuriString* type_string; + type_string = furi_string_alloc(); LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto; if(args_read_string_and_trim(args, type_string)) { - if(string_cmp_str(type_string, "normal") == 0 || string_cmp_str(type_string, "ask") == 0) { + if(furi_string_cmp_str(type_string, "normal") == 0 || + furi_string_cmp_str(type_string, "ask") == 0) { // ask type = LFRFIDWorkerReadTypeASKOnly; } else if( - string_cmp_str(type_string, "indala") == 0 || - string_cmp_str(type_string, "psk") == 0) { + furi_string_cmp_str(type_string, "indala") == 0 || + furi_string_cmp_str(type_string, "psk") == 0) { // psk type = LFRFIDWorkerReadTypePSKOnly; } else { lfrfid_cli_print_usage(); - string_clear(type_string); + furi_string_free(type_string); return; } } - string_clear(type_string); + furi_string_free(type_string); ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); LFRFIDWorker* worker = lfrfid_worker_alloc(dict); @@ -111,13 +112,13 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { printf("\r\n"); free(data); - string_t info; - string_init(info); + FuriString* info; + info = furi_string_alloc(); protocol_dict_render_data(dict, info, context.protocol); - if(!string_empty_p(info)) { - printf("%s\r\n", string_get_cstr(info)); + if(!furi_string_empty(info)) { + printf("%s\r\n", furi_string_get_cstr(info)); } - string_clear(info); + furi_string_free(info); } printf("Reading stopped\r\n"); @@ -126,11 +127,11 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { furi_event_flag_free(context.event); } -static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* protocol) { +static bool lfrfid_cli_parse_args(FuriString* args, ProtocolDict* dict, ProtocolId* protocol) { bool result = false; - string_t protocol_name, data_text; - string_init(protocol_name); - string_init(data_text); + FuriString *protocol_name, *data_text; + protocol_name = furi_string_alloc(); + data_text = furi_string_alloc(); size_t data_size = protocol_dict_get_max_data_size(dict); uint8_t* data = malloc(data_size); @@ -143,12 +144,12 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* } // check protocol arg - *protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(protocol_name)); + *protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(protocol_name)); if(*protocol == PROTOCOL_NO) { printf( "Unknown protocol: %s\r\n" "Available protocols:\r\n", - string_get_cstr(protocol_name)); + furi_string_get_cstr(protocol_name)); for(ProtocolId i = 0; i < LFRFIDProtocolMax; i++) { printf( @@ -177,8 +178,8 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* } while(false); free(data); - string_clear(protocol_name); - string_clear(data_text); + furi_string_free(protocol_name); + furi_string_free(data_text); return result; } @@ -188,7 +189,7 @@ static void lfrfid_cli_write_callback(LFRFIDWorkerWriteResult result, void* ctx) furi_event_flag_set(events, 1 << result); } -static void lfrfid_cli_write(Cli* cli, string_t args) { +static void lfrfid_cli_write(Cli* cli, FuriString* args) { ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); ProtocolId protocol; @@ -235,7 +236,7 @@ static void lfrfid_cli_write(Cli* cli, string_t args) { furi_event_flag_free(event); } -static void lfrfid_cli_emulate(Cli* cli, string_t args) { +static void lfrfid_cli_emulate(Cli* cli, FuriString* args) { ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); ProtocolId protocol; @@ -261,11 +262,11 @@ static void lfrfid_cli_emulate(Cli* cli, string_t args) { protocol_dict_free(dict); } -static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { +static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath, info_string; - string_init(filepath); - string_init(info_string); + FuriString *filepath, *info_string; + filepath = furi_string_alloc(); + info_string = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); @@ -278,7 +279,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { break; } - if(!lfrfid_raw_file_open_read(file, string_get_cstr(filepath))) { + if(!lfrfid_raw_file_open_read(file, furi_string_get_cstr(filepath))) { printf("Failed to open file\r\n"); break; } @@ -308,10 +309,10 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { warn = true; } - string_printf(info_string, "[%ld %ld]", pulse, duration); - printf("%-16s", string_get_cstr(info_string)); - string_printf(info_string, "[%ld %ld]", pulse, duration - pulse); - printf("%-16s", string_get_cstr(info_string)); + furi_string_printf(info_string, "[%ld %ld]", pulse, duration); + printf("%-16s", furi_string_get_cstr(info_string)); + furi_string_printf(info_string, "[%ld %ld]", pulse, duration - pulse); + printf("%-16s", furi_string_get_cstr(info_string)); if(warn) { printf(" <<----"); @@ -366,7 +367,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { printf("]\r\n"); protocol_dict_render_data(dict, info_string, total_protocol); - printf("%s\r\n", string_get_cstr(info_string)); + printf("%s\r\n", furi_string_get_cstr(info_string)); free(data); } else { @@ -376,8 +377,8 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { protocol_dict_free(dict); } while(false); - string_clear(filepath); - string_clear(info_string); + furi_string_free(filepath); + furi_string_free(info_string); lfrfid_raw_file_free(file); furi_record_close(RECORD_STORAGE); } @@ -388,23 +389,23 @@ static void lfrfid_cli_raw_read_callback(LFRFIDWorkerReadRawResult result, void* furi_event_flag_set(event, 1 << result); } -static void lfrfid_cli_raw_read(Cli* cli, string_t args) { +static void lfrfid_cli_raw_read(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath, type_string; - string_init(filepath); - string_init(type_string); + FuriString *filepath, *type_string; + filepath = furi_string_alloc(); + type_string = furi_string_alloc(); LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto; do { if(args_read_string_and_trim(args, type_string)) { - if(string_cmp_str(type_string, "normal") == 0 || - string_cmp_str(type_string, "ask") == 0) { + if(furi_string_cmp_str(type_string, "normal") == 0 || + furi_string_cmp_str(type_string, "ask") == 0) { // ask type = LFRFIDWorkerReadTypeASKOnly; } else if( - string_cmp_str(type_string, "indala") == 0 || - string_cmp_str(type_string, "psk") == 0) { + furi_string_cmp_str(type_string, "indala") == 0 || + furi_string_cmp_str(type_string, "psk") == 0) { // psk type = LFRFIDWorkerReadTypePSKOnly; } else { @@ -430,7 +431,7 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) { (1 << LFRFIDWorkerReadRawOverrun); lfrfid_worker_read_raw_start( - worker, string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event); + worker, furi_string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event); while(true) { uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100); @@ -465,8 +466,8 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) { } while(false); - string_clear(filepath); - string_clear(type_string); + furi_string_free(filepath); + furi_string_free(type_string); } static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, void* context) { @@ -475,11 +476,11 @@ static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, furi_event_flag_set(event, 1 << result); } -static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { +static void lfrfid_cli_raw_emulate(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath; - string_init(filepath); + FuriString* filepath; + filepath = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); do { @@ -488,8 +489,8 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { break; } - if(!storage_file_exists(storage, string_get_cstr(filepath))) { - printf("File not found: \"%s\"\r\n", string_get_cstr(filepath)); + if(!storage_file_exists(storage, furi_string_get_cstr(filepath))) { + printf("File not found: \"%s\"\r\n", furi_string_get_cstr(filepath)); break; } @@ -505,7 +506,7 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { (1 << LFRFIDWorkerEmulateRawOverrun); lfrfid_worker_emulate_raw_start( - worker, string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event); + worker, furi_string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event); while(true) { uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100); @@ -541,35 +542,35 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { } while(false); furi_record_close(RECORD_STORAGE); - string_clear(filepath); + furi_string_free(filepath); } -static void lfrfid_cli(Cli* cli, string_t args, void* context) { +static void lfrfid_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); lfrfid_cli_print_usage(); return; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { lfrfid_cli_read(cli, args); - } else if(string_cmp_str(cmd, "write") == 0) { + } else if(furi_string_cmp_str(cmd, "write") == 0) { lfrfid_cli_write(cli, args); - } else if(string_cmp_str(cmd, "emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "emulate") == 0) { lfrfid_cli_emulate(cli, args); - } else if(string_cmp_str(cmd, "raw_read") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_read") == 0) { lfrfid_cli_raw_read(cli, args); - } else if(string_cmp_str(cmd, "raw_emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_emulate") == 0) { lfrfid_cli_raw_emulate(cli, args); - } else if(string_cmp_str(cmd, "raw_analyze") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_analyze") == 0) { lfrfid_cli_raw_analyze(cli, args); } else { lfrfid_cli_print_usage(); } - string_clear(cmd); + furi_string_free(cmd); } \ No newline at end of file diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 77e87252..71917c0c 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -1,7 +1,5 @@ #pragma once -#include "m-string.h" - #include #include @@ -86,9 +84,9 @@ struct LfRfid { Widget* widget; char text_store[LFRFID_TEXT_STORE_SIZE + 1]; - string_t file_path; - string_t file_name; - string_t raw_file_name; + FuriString* file_path; + FuriString* file_name; + FuriString* raw_file_name; ProtocolDict* dict; ProtocolId protocol_id; @@ -128,9 +126,9 @@ bool lfrfid_load_key_from_file_select(LfRfid* app); bool lfrfid_delete_key(LfRfid* app); -bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog); +bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog); -bool lfrfid_save_key_data(LfRfid* app, string_t path); +bool lfrfid_save_key_data(LfRfid* app, FuriString* path); void lfrfid_make_app_folder(LfRfid* app); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c index dc1c3df2..b7702e26 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c @@ -4,31 +4,31 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app); - string_printf(tmp_string, "Delete %s?", string_get_cstr(app->file_name)); + furi_string_printf(tmp_string, "Delete %s?", furi_string_get_cstr(app->file_name)); widget_add_string_element( - widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(tmp_string)); + widget, 64, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - string_reset(tmp_string); + furi_string_reset(tmp_string); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); uint8_t* data = (uint8_t*)malloc(size); protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < MIN(size, (size_t)8); i++) { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } free(data); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 64, 19, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); widget_add_string_element( widget, 64, @@ -39,7 +39,7 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) { protocol_dict_get_name(app->dict, app->protocol_id)); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c index 70cc2418..2725982f 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c @@ -8,8 +8,8 @@ void lfrfid_scene_emulate_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedRfidEmulate); popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop); - if(!string_empty_p(app->file_name)) { - popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + if(!furi_string_empty(app->file_name)) { + popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); } else { popup_set_text( popup, diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c index 43e3de99..d7fd93e1 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -42,7 +42,7 @@ void lfrfid_scene_extra_actions_on_enter(void* context) { submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions)); // clear key - string_reset(app->file_name); + furi_string_reset(app->file_name); app->protocol_id = PROTOCOL_NO; app->read_type = LFRFIDWorkerReadTypeAuto; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c index f60dd624..e5193521 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c @@ -4,8 +4,8 @@ void lfrfid_scene_raw_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - // string_t tmp_string; - // string_init(tmp_string); + // FuriString* tmp_string; + // tmp_string = furi_string_alloc(); bool sd_exist = storage_sd_status(app->storage) == FSE_OK; if(!sd_exist) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c index 512f9ee4..3e09dbf0 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c @@ -4,9 +4,9 @@ void lfrfid_scene_raw_name_on_enter(void* context) { LfRfid* app = context; TextInput* text_input = app->text_input; - const char* key_name = string_get_cstr(app->raw_file_name); + const char* key_name = furi_string_get_cstr(app->raw_file_name); - bool key_name_is_empty = string_empty_p(app->file_name); + bool key_name_is_empty = furi_string_empty(app->file_name); if(key_name_is_empty) { lfrfid_text_store_set(app, "RfidRecord"); } else { @@ -38,7 +38,7 @@ bool lfrfid_scene_raw_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == LfRfidEventNext) { consumed = true; - string_set_str(app->raw_file_name, app->text_store); + furi_string_set(app->raw_file_name, app->text_store); scene_manager_next_scene(scene_manager, LfRfidSceneRawInfo); } } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c index d0c03ffa..b2c7c364 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c @@ -3,7 +3,7 @@ #define RAW_READ_TIME 5000 typedef struct { - string_t string_file_name; + FuriString* string_file_name; FuriTimer* timer; bool is_psk; bool error; @@ -31,7 +31,7 @@ void lfrfid_scene_raw_read_on_enter(void* context) { LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); - string_init(state->string_file_name); + state->string_file_name = furi_string_alloc(); popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); @@ -40,16 +40,16 @@ void lfrfid_scene_raw_read_on_enter(void* context) { state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app); furi_timer_start(state->timer, RAW_READ_TIME); - string_printf( + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, - string_get_cstr(app->raw_file_name), + furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_ASK_EXTENSION); popup_set_header(popup, "Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); lfrfid_worker_read_raw_start( app->lfworker, - string_get_cstr(state->string_file_name), + furi_string_get_cstr(state->string_file_name), LFRFIDWorkerReadTypeASKOnly, lfrfid_read_callback, app); @@ -88,15 +88,15 @@ bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) { popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop); notification_message(app->notifications, &sequence_blink_start_yellow); lfrfid_worker_stop(app->lfworker); - string_printf( + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, - string_get_cstr(app->raw_file_name), + furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_PSK_EXTENSION); lfrfid_worker_read_raw_start( app->lfworker, - string_get_cstr(state->string_file_name), + furi_string_get_cstr(state->string_file_name), LFRFIDWorkerReadTypePSKOnly, lfrfid_read_callback, app); @@ -121,6 +121,6 @@ void lfrfid_scene_raw_read_on_exit(void* context) { lfrfid_worker_stop_thread(app->lfworker); furi_timer_free(state->timer); - string_clear(state->string_file_name); + furi_string_free(state->string_file_name); free(state); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_read.c index 66168038..4bdb215d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read.c @@ -81,7 +81,7 @@ bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) { app->protocol_id = app->protocol_id_next; DOLPHIN_DEED(DolphinDeedRfidReadSuccess); notification_message(app->notifications, &sequence_success); - string_reset(app->file_name); + furi_string_reset(app->file_name); scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess); consumed = true; } else if(event.event == LfRfidEventReadStartPSK) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c index 221cc008..7480304b 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c @@ -38,7 +38,7 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite); consumed = true; } else if(event.event == SubmenuIndexSave) { - string_reset(app->file_name); + furi_string_reset(app->file_name); scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveName); consumed = true; } else if(event.event == SubmenuIndexEmulate) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c index 5ae6f0f1..b83ef4a3 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c @@ -4,51 +4,51 @@ void lfrfid_scene_read_success_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); - string_printf( + furi_string_printf( tmp_string, "%s[%s]", protocol_dict_get_name(app->dict, app->protocol_id), protocol_dict_get_manufacturer(app->dict, app->protocol_id)); widget_add_string_element( - widget, 0, 2, AlignLeft, AlignTop, FontPrimary, string_get_cstr(tmp_string)); + widget, 0, 2, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - string_reset(tmp_string); + furi_string_reset(tmp_string); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); uint8_t* data = (uint8_t*)malloc(size); protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < size; i++) { if(i >= 9) { - string_cat_printf(tmp_string, ".."); + furi_string_cat_printf(tmp_string, ".."); break; } else { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } } free(data); - string_t render_data; - string_init(render_data); + FuriString* render_data; + render_data = furi_string_alloc(); protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id); - string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); + furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); + furi_string_free(render_data); widget_add_string_multiline_element( - widget, 0, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 0, 16, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); notification_message_block(app->notifications, &sequence_set_green_255); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c index a69d6453..156dd97a 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c @@ -34,13 +34,14 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { const char* arg = rpc_system_app_get_data(app->rpc_ctx); bool result = false; if(arg && (app->rpc_state == LfRfidRpcStateIdle)) { - string_set_str(app->file_path, arg); + furi_string_set(app->file_path, arg); if(lfrfid_load_key_data(app, app->file_path, false)) { lfrfid_worker_start_thread(app->lfworker); lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); app->rpc_state = LfRfidRpcStateEmulating; - lfrfid_text_store_set(app, "emulating\n%s", string_get_cstr(app->file_name)); + lfrfid_text_store_set( + app, "emulating\n%s", furi_string_get_cstr(app->file_name)); popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); notification_message(app->notifications, &sequence_blink_start_magenta); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c index febf30a4..ca9a52de 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c @@ -1,21 +1,20 @@ -#include "m-string.h" #include #include "../lfrfid_i.h" void lfrfid_scene_save_name_on_enter(void* context) { LfRfid* app = context; TextInput* text_input = app->text_input; - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - bool key_name_is_empty = string_empty_p(app->file_name); + bool key_name_is_empty = furi_string_empty(app->file_name); if(key_name_is_empty) { - string_set_str(app->file_path, LFRFID_APP_FOLDER); + furi_string_set(app->file_path, LFRFID_APP_FOLDER); set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE); - string_set_str(folder_path, LFRFID_APP_FOLDER); + furi_string_set(folder_path, LFRFID_APP_FOLDER); } else { - lfrfid_text_store_set(app, "%s", string_get_cstr(app->file_name)); - path_extract_dirname(string_get_cstr(app->file_path), folder_path); + lfrfid_text_store_set(app, "%s", furi_string_get_cstr(app->file_name)); + path_extract_dirname(furi_string_get_cstr(app->file_path), folder_path); } text_input_set_header_text(text_input, "Name the card"); @@ -27,13 +26,15 @@ void lfrfid_scene_save_name_on_enter(void* context) { LFRFID_KEY_NAME_SIZE, key_name_is_empty); - FURI_LOG_I("", "%s %s", string_get_cstr(folder_path), app->text_store); + FURI_LOG_I("", "%s %s", furi_string_get_cstr(folder_path), app->text_store); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), LFRFID_APP_EXTENSION, string_get_cstr(app->file_name)); + furi_string_get_cstr(folder_path), + LFRFID_APP_EXTENSION, + furi_string_get_cstr(app->file_name)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(folder_path); + furi_string_free(folder_path); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput); } @@ -46,11 +47,11 @@ bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == LfRfidEventNext) { consumed = true; - if(!string_empty_p(app->file_name)) { + if(!furi_string_empty(app->file_name)) { lfrfid_delete_key(app); } - string_set_str(app->file_name, app->text_store); + furi_string_set(app->file_name, app->text_store); if(lfrfid_save_key(app)) { scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c index 4c111600..0ba51f06 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c @@ -1,7 +1,7 @@ #include "../lfrfid_i.h" typedef struct { - string_t menu_item_name[LFRFIDProtocolMax]; + FuriString* menu_item_name[LFRFIDProtocolMax]; uint32_t line_sel; } SaveTypeCtx; @@ -20,18 +20,17 @@ void lfrfid_scene_save_type_on_enter(void* context) { if(strcmp( protocol_dict_get_manufacturer(app->dict, i), protocol_dict_get_name(app->dict, i)) != 0) { - string_init_printf( - state->menu_item_name[i], + state->menu_item_name[i] = furi_string_alloc_printf( "%s %s", protocol_dict_get_manufacturer(app->dict, i), protocol_dict_get_name(app->dict, i)); } else { - string_init_printf( - state->menu_item_name[i], "%s", protocol_dict_get_name(app->dict, i)); + state->menu_item_name[i] = + furi_string_alloc_printf("%s", protocol_dict_get_name(app->dict, i)); } submenu_add_item( submenu, - string_get_cstr(state->menu_item_name[i]), + furi_string_get_cstr(state->menu_item_name[i]), i, lfrfid_scene_save_type_submenu_callback, app); @@ -43,7 +42,7 @@ void lfrfid_scene_save_type_on_enter(void* context) { scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, (uint32_t)state); // clear key name - string_reset(app->file_name); + furi_string_reset(app->file_name); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); } @@ -75,7 +74,7 @@ void lfrfid_scene_save_type_on_exit(void* context) { submenu_reset(app->submenu); for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) { - string_clear(state->menu_item_name[i]); + furi_string_free(state->menu_item_name[i]); } uint32_t line_sel = state->line_sel; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c index 1496c6b4..3f1c2d40 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c @@ -4,13 +4,13 @@ void lfrfid_scene_saved_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); - string_printf( + furi_string_printf( tmp_string, "%s [%s]\r\n", - string_get_cstr(app->file_name), + furi_string_get_cstr(app->file_name), protocol_dict_get_name(app->dict, app->protocol_id)); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); @@ -18,24 +18,24 @@ void lfrfid_scene_saved_info_on_enter(void* context) { protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < size; i++) { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } free(data); - string_t render_data; - string_init(render_data); + FuriString* render_data; + render_data = furi_string_alloc(); protocol_dict_render_data(app->dict, render_data, app->protocol_id); - string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); + furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); + furi_string_free(render_data); widget_add_string_multiline_element( - widget, 0, 1, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 0, 1, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_saved_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_start.c b/applications/main/lfrfid/scenes/lfrfid_scene_start.c index 9074e859..d6d87f44 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_start.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_start.c @@ -33,7 +33,7 @@ void lfrfid_scene_start_on_enter(void* context) { submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneStart)); // clear key - string_reset(app->file_name); + furi_string_reset(app->file_name); app->protocol_id = PROTOCOL_NO; app->read_type = LFRFIDWorkerReadTypeAuto; @@ -49,7 +49,7 @@ bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); consumed = true; } else if(event.event == SubmenuIndexSaved) { - string_set_str(app->file_path, LFRFID_APP_FOLDER); + furi_string_set(app->file_path, LFRFID_APP_FOLDER); scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectKey); consumed = true; } else if(event.event == SubmenuIndexAddManually) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write.c b/applications/main/lfrfid/scenes/lfrfid_scene_write.c index 8e791d52..b7faed69 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write.c @@ -22,8 +22,8 @@ void lfrfid_scene_write_on_enter(void* context) { Popup* popup = app->popup; popup_set_header(popup, "Writing", 89, 30, AlignCenter, AlignTop); - if(!string_empty_p(app->file_name)) { - popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + if(!furi_string_empty(app->file_name)) { + popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); } else { popup_set_text( popup, diff --git a/applications/main/nfc/helpers/nfc_emv_parser.c b/applications/main/nfc/helpers/nfc_emv_parser.c index 0d7cb5a3..30e10240 100644 --- a/applications/main/nfc/helpers/nfc_emv_parser.c +++ b/applications/main/nfc/helpers/nfc_emv_parser.c @@ -7,12 +7,12 @@ static const uint32_t nfc_resources_file_version = 1; static bool nfc_emv_parser_search_data( Storage* storage, const char* file_name, - string_t key, - string_t data) { + FuriString* key, + FuriString* data) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { // Open file @@ -20,14 +20,14 @@ static bool nfc_emv_parser_search_data( // Read file header and version uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_resources_header) || + if(furi_string_cmp_str(temp_str, nfc_resources_header) || (version != nfc_resources_file_version)) break; - if(!flipper_format_read_string(file, string_get_cstr(key), data)) break; + if(!flipper_format_read_string(file, furi_string_get_cstr(key), data)) break; parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; } @@ -36,47 +36,47 @@ bool nfc_emv_parser_get_aid_name( Storage* storage, uint8_t* aid, uint8_t aid_len, - string_t aid_name) { + FuriString* aid_name) { furi_assert(storage); bool parsed = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); for(uint8_t i = 0; i < aid_len; i++) { - string_cat_printf(key, "%02X", aid[i]); + furi_string_cat_printf(key, "%02X", aid[i]); } if(nfc_emv_parser_search_data(storage, EXT_PATH("nfc/assets/aid.nfc"), key, aid_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } bool nfc_emv_parser_get_country_name( Storage* storage, uint16_t country_code, - string_t country_name) { + FuriString* country_name) { bool parsed = false; - string_t key; - string_init_printf(key, "%04X", country_code); + FuriString* key; + key = furi_string_alloc_printf("%04X", country_code); if(nfc_emv_parser_search_data( storage, EXT_PATH("nfc/assets/country_code.nfc"), key, country_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } bool nfc_emv_parser_get_currency_name( Storage* storage, uint16_t currency_code, - string_t currency_name) { + FuriString* currency_name) { bool parsed = false; - string_t key; - string_init_printf(key, "%04X", currency_code); + FuriString* key; + key = furi_string_alloc_printf("%04X", currency_code); if(nfc_emv_parser_search_data( storage, EXT_PATH("nfc/assets/currency_code.nfc"), key, currency_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } diff --git a/applications/main/nfc/helpers/nfc_emv_parser.h b/applications/main/nfc/helpers/nfc_emv_parser.h index 5948ed34..abe57f47 100644 --- a/applications/main/nfc/helpers/nfc_emv_parser.h +++ b/applications/main/nfc/helpers/nfc_emv_parser.h @@ -2,7 +2,6 @@ #include #include -#include #include /** Get EMV application name by number @@ -16,7 +15,7 @@ bool nfc_emv_parser_get_aid_name( Storage* storage, uint8_t* aid, uint8_t aid_len, - string_t aid_name); + FuriString* aid_name); /** Get country name by country code * @param storage Storage instance @@ -27,7 +26,7 @@ bool nfc_emv_parser_get_aid_name( bool nfc_emv_parser_get_country_name( Storage* storage, uint16_t country_code, - string_t country_name); + FuriString* country_name); /** Get currency name by currency code * @param storage Storage instance @@ -38,4 +37,4 @@ bool nfc_emv_parser_get_country_name( bool nfc_emv_parser_get_currency_name( Storage* storage, uint16_t currency_code, - string_t currency_name); + FuriString* currency_name); diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index f47a5bac..44a0f636 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -83,7 +83,7 @@ Nfc* nfc_alloc() { nfc->text_box = text_box_alloc(); view_dispatcher_add_view( nfc->view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box)); - string_init(nfc->text_box_store); + nfc->text_box_store = furi_string_alloc(); // Custom Widget nfc->widget = widget_alloc(); @@ -153,7 +153,7 @@ void nfc_free(Nfc* nfc) { // TextBox view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextBox); text_box_free(nfc->text_box); - string_clear(nfc->text_box_store); + furi_string_free(nfc->text_box_store); // Custom Widget view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewWidget); diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index 4ac95f04..a6475ca6 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -17,7 +17,7 @@ static void nfc_cli_print_usage() { } } -static void nfc_cli_detect(Cli* cli, string_t args) { +static void nfc_cli_detect(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -46,7 +46,7 @@ static void nfc_cli_detect(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli_emulate(Cli* cli, string_t args) { +static void nfc_cli_emulate(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -76,7 +76,7 @@ static void nfc_cli_emulate(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli_field(Cli* cli, string_t args) { +static void nfc_cli_field(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -98,27 +98,27 @@ static void nfc_cli_field(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli(Cli* cli, string_t args, void* context) { +static void nfc_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { nfc_cli_print_usage(); break; } - if(string_cmp_str(cmd, "detect") == 0) { + if(furi_string_cmp_str(cmd, "detect") == 0) { nfc_cli_detect(cli, args); break; } - if(string_cmp_str(cmd, "emulate") == 0) { + if(furi_string_cmp_str(cmd, "emulate") == 0) { nfc_cli_emulate(cli, args); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "field") == 0) { + if(furi_string_cmp_str(cmd, "field") == 0) { nfc_cli_field(cli, args); break; } @@ -127,7 +127,7 @@ static void nfc_cli(Cli* cli, string_t args, void* context) { nfc_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void nfc_on_system_start() { diff --git a/applications/main/nfc/nfc_i.h b/applications/main/nfc/nfc_i.h index 15ea5348..fa5b54ed 100644 --- a/applications/main/nfc/nfc_i.h +++ b/applications/main/nfc/nfc_i.h @@ -62,7 +62,7 @@ struct Nfc { FuriHalNfcDevData dev_edit_data; char text_store[NFC_TEXT_STORE_SIZE + 1]; - string_t text_box_store; + FuriString* text_box_store; uint8_t byte_input_store[6]; MfClassicUserKeys_t mfc_key_strs; // Used in MFC key listing diff --git a/applications/main/nfc/scenes/nfc_scene_delete.c b/applications/main/nfc/scenes/nfc_scene_delete.c index 987927e1..cbb52bfd 100644 --- a/applications/main/nfc/scenes/nfc_scene_delete.c +++ b/applications/main/nfc/scenes/nfc_scene_delete.c @@ -12,40 +12,40 @@ void nfc_scene_delete_on_enter(void* context) { FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; // Setup Custom Widget view - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); - string_printf(temp_str, "\e#Delete %s?\e#", nfc->dev->dev_name); + furi_string_printf(temp_str, "\e#Delete %s?\e#", nfc->dev->dev_name); widget_add_text_box_element( - nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, string_get_cstr(temp_str), false); + nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, furi_string_get_cstr(temp_str), false); widget_add_button_element( nfc->widget, GuiButtonTypeLeft, "Cancel", nfc_scene_delete_widget_callback, nfc); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc); - string_set_str(temp_str, "UID:"); + furi_string_set(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } widget_add_string_element( - nfc->widget, 64, 24, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str)); + nfc->widget, 64, 24, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); NfcProtocol protocol = nfc->dev->dev_data.protocol; if(protocol == NfcDeviceProtocolEMV) { - string_set_str(temp_str, "EMV bank card"); + furi_string_set(temp_str, "EMV bank card"); } else if(protocol == NfcDeviceProtocolMifareUl) { - string_set_str(temp_str, nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, true)); + furi_string_set(temp_str, nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, true)); } else if(protocol == NfcDeviceProtocolMifareClassic) { - string_set_str(temp_str, nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type)); + furi_string_set(temp_str, nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { - string_set_str(temp_str, "MIFARE DESFire"); + furi_string_set(temp_str, "MIFARE DESFire"); } else { - string_set_str(temp_str, "Unknown ISO tag"); + furi_string_set(temp_str, "Unknown ISO tag"); } widget_add_string_element( - nfc->widget, 64, 34, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str)); + nfc->widget, 64, 34, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_string_element(nfc->widget, 64, 44, AlignCenter, AlignTop, FontSecondary, "NFC-A"); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_device_info.c b/applications/main/nfc/scenes/nfc_scene_device_info.c index 245aea5c..9780ffe4 100644 --- a/applications/main/nfc/scenes/nfc_scene_device_info.c +++ b/applications/main/nfc/scenes/nfc_scene_device_info.c @@ -12,49 +12,52 @@ void nfc_scene_device_info_on_enter(void* context) { Nfc* nfc = context; NfcDeviceData* dev_data = &nfc->dev->dev_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); if(dev_data->protocol == NfcDeviceProtocolEMV) { EmvData* emv_data = &dev_data->emv_data; - string_printf(temp_str, "\e#%s\n", emv_data->name); + furi_string_printf(temp_str, "\e#%s\n", emv_data->name); for(uint8_t i = 0; i < emv_data->number_len; i += 2) { - string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + furi_string_cat_printf( + temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); } - string_strim(temp_str); + furi_string_trim(temp_str); // Add expiration date if(emv_data->exp_mon) { - string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); + furi_string_cat_printf( + temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); } // Parse currency code if((emv_data->currency_code)) { - string_t currency_name; - string_init(currency_name); + FuriString* currency_name; + currency_name = furi_string_alloc(); if(nfc_emv_parser_get_currency_name( nfc->dev->storage, emv_data->currency_code, currency_name)) { - string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name)); + furi_string_cat_printf( + temp_str, "\nCur: %s ", furi_string_get_cstr(currency_name)); } - string_clear(currency_name); + furi_string_free(currency_name); } // Parse country code if((emv_data->country_code)) { - string_t country_name; - string_init(country_name); + FuriString* country_name; + country_name = furi_string_alloc(); if(nfc_emv_parser_get_country_name( nfc->dev->storage, emv_data->country_code, country_name)) { - string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name)); + furi_string_cat_printf(temp_str, "Reg: %s", furi_string_get_cstr(country_name)); } - string_clear(country_name); + furi_string_free(country_name); } } else if( dev_data->protocol == NfcDeviceProtocolMifareClassic || dev_data->protocol == NfcDeviceProtocolMifareUl) { - string_set(temp_str, nfc->dev->dev_data.parsed_data); + furi_string_set(temp_str, nfc->dev->dev_data.parsed_data); } - widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "More", nfc_scene_device_info_widget_callback, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c index f6402301..8bb20796 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c @@ -35,22 +35,22 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; widget_reset(widget); - string_t info_str; - string_init(info_str); + FuriString* info_str; + info_str = furi_string_alloc(); widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); widget_add_string_element(widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating UID"); if(strcmp(nfc->dev->dev_name, "")) { - string_printf(info_str, "%s", nfc->dev->dev_name); + furi_string_printf(info_str, "%s", nfc->dev->dev_name); } else { for(uint8_t i = 0; i < data->uid_len; i++) { - string_cat_printf(info_str, "%02X ", data->uid[i]); + furi_string_cat_printf(info_str, "%02X ", data->uid[i]); } } - string_strim(info_str); + furi_string_trim(info_str); widget_add_text_box_element( - widget, 56, 43, 70, 21, AlignCenter, AlignTop, string_get_cstr(info_str), true); - string_clear(info_str); + widget, 56, 43, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); + furi_string_free(info_str); if(data_received) { widget_add_button_element( widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_uid_widget_callback, nfc); @@ -67,7 +67,7 @@ void nfc_scene_emulate_uid_on_enter(void* context) { TextBox* text_box = nfc->text_box; text_box_set_font(text_box, TextBoxFontHex); text_box_set_focus(text_box, TextBoxFocusEnd); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); // Set Widget state and view scene_manager_set_scene_state( @@ -94,17 +94,17 @@ bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { // Add data button to widget if data is received for the first time - if(!string_size(nfc->text_box_store)) { + if(!furi_string_size(nfc->text_box_store)) { nfc_scene_emulate_uid_widget_config(nfc, true); } // Update TextBox data - if(string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) { - string_cat_printf(nfc->text_box_store, "R:"); + if(furi_string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); for(uint16_t i = 0; i < reader_data->size; i++) { - string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); + furi_string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); } - string_push_back(nfc->text_box_store, '\n'); - text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store)); + furi_string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, furi_string_get_cstr(nfc->text_box_store)); } memset(reader_data, 0, sizeof(NfcReaderRequestData)); consumed = true; @@ -140,7 +140,7 @@ void nfc_scene_emulate_uid_on_exit(void* context) { // Clear view widget_reset(nfc->widget); text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); nfc_blink_stop(nfc); } diff --git a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c index a40b4c1c..8b6ab160 100644 --- a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c @@ -23,42 +23,44 @@ void nfc_scene_emv_read_success_on_enter(void* context) { widget_add_button_element( nfc->widget, GuiButtonTypeRight, "More", nfc_scene_emv_read_success_widget_callback, nfc); - string_t temp_str; - string_init_printf(temp_str, "\e#%s\n", emv_data->name); + FuriString* temp_str; + temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name); for(uint8_t i = 0; i < emv_data->number_len; i += 2) { - string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + furi_string_cat_printf( + temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); } - string_strim(temp_str); + furi_string_trim(temp_str); // Add expiration date if(emv_data->exp_mon) { - string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); + furi_string_cat_printf( + temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); } // Parse currency code if((emv_data->currency_code)) { - string_t currency_name; - string_init(currency_name); + FuriString* currency_name; + currency_name = furi_string_alloc(); if(nfc_emv_parser_get_currency_name( nfc->dev->storage, emv_data->currency_code, currency_name)) { - string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name)); + furi_string_cat_printf(temp_str, "\nCur: %s ", furi_string_get_cstr(currency_name)); } - string_clear(currency_name); + furi_string_free(currency_name); } // Parse country code if((emv_data->country_code)) { - string_t country_name; - string_init(country_name); + FuriString* country_name; + country_name = furi_string_alloc(); if(nfc_emv_parser_get_country_name( nfc->dev->storage, emv_data->country_code, country_name)) { - string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name)); + furi_string_cat_printf(temp_str, "Reg: %s", furi_string_get_cstr(country_name)); } - string_clear(country_name); + furi_string_free(country_name); } notification_message_block(nfc->notifications, &sequence_set_green_255); - widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_generate_info.c b/applications/main/nfc/scenes/nfc_scene_generate_info.c index 7fb7eb94..66900767 100644 --- a/applications/main/nfc/scenes/nfc_scene_generate_info.c +++ b/applications/main/nfc/scenes/nfc_scene_generate_info.c @@ -16,15 +16,15 @@ void nfc_scene_generate_info_on_enter(void* context) { dialog_ex_set_right_button_text(dialog_ex, "More"); // Create info text - string_t info_str; - string_init_printf( - info_str, "%s\n%s\nUID:", nfc->generator->name, nfc_get_dev_type(data->type)); + FuriString* info_str = furi_string_alloc_printf( + "%s\n%s\nUID:", nfc->generator->name, nfc_get_dev_type(data->type)); + // Append UID for(int i = 0; i < data->uid_len; ++i) { - string_cat_printf(info_str, " %02X", data->uid[i]); + furi_string_cat_printf(info_str, " %02X", data->uid[i]); } - nfc_text_store_set(nfc, string_get_cstr(info_str)); - string_clear(info_str); + nfc_text_store_set(nfc, furi_string_get_cstr(info_str)); + furi_string_free(info_str); dialog_ex_set_text(dialog_ex, nfc->text_store, 0, 0, AlignLeft, AlignTop); dialog_ex_set_context(dialog_ex, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c index 16a189da..0ea3f59a 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c @@ -16,8 +16,8 @@ void nfc_scene_mf_classic_keys_delete_on_enter(void* context) { uint32_t key_index = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicKeysDelete); // Setup Custom Widget view - string_t key_str; - string_init(key_str); + FuriString* key_str; + key_str = furi_string_alloc(); widget_add_string_element( nfc->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Delete this key?"); @@ -36,9 +36,15 @@ void nfc_scene_mf_classic_keys_delete_on_enter(void* context) { mf_classic_dict_get_key_at_index_str(dict, key_str, key_index); widget_add_string_element( - nfc->widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(key_str)); + nfc->widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(key_str)); - string_clear(key_str); + furi_string_free(key_str); mf_classic_dict_free(dict); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c index 6670ae13..5649ea87 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c @@ -19,19 +19,19 @@ void nfc_scene_mf_classic_keys_list_popup_callback(void* context) { void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) { Submenu* submenu = nfc->submenu; uint32_t index = 0; - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); submenu_set_header(submenu, "Select key to delete:"); while(mf_classic_dict_get_next_key_str(dict, temp_key)) { char* current_key = (char*)malloc(sizeof(char) * 13); - strncpy(current_key, string_get_cstr(temp_key), 12); + strncpy(current_key, furi_string_get_cstr(temp_key), 12); MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); submenu_add_item( submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); } - string_clear(temp_key); + furi_string_free(temp_key); } void nfc_scene_mf_classic_keys_list_on_enter(void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c index 3ca24416..0cdb8646 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c @@ -27,26 +27,26 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_mf_classic_read_success_widget_callback, nfc); - string_t temp_str; - if(string_size(nfc->dev->dev_data.parsed_data)) { - string_init_set(temp_str, nfc->dev->dev_data.parsed_data); + FuriString* temp_str; + if(furi_string_size(nfc->dev->dev_data.parsed_data)) { + temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data); } else { - string_init_printf(temp_str, "\e#%s\n", nfc_mf_classic_type(mf_data->type)); - string_cat_printf(temp_str, "UID:"); + temp_str = furi_string_alloc_printf("\e#%s\n", nfc_mf_classic_type(mf_data->type)); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < dev_data->nfc_data.uid_len; i++) { - string_cat_printf(temp_str, " %02X", dev_data->nfc_data.uid[i]); + furi_string_cat_printf(temp_str, " %02X", dev_data->nfc_data.uid[i]); } uint8_t sectors_total = mf_classic_get_total_sectors_num(mf_data->type); uint8_t keys_total = sectors_total * 2; uint8_t keys_found = 0; uint8_t sectors_read = 0; mf_classic_get_read_sectors_and_keys(mf_data, §ors_read, &keys_found); - string_cat_printf(temp_str, "\nKeys Found: %d/%d", keys_found, keys_total); - string_cat_printf(temp_str, "\nSectors Read: %d/%d", sectors_read, sectors_total); + furi_string_cat_printf(temp_str, "\nKeys Found: %d/%d", keys_found, keys_total); + furi_string_cat_printf(temp_str, "\nSectors Read: %d/%d", sectors_read, sectors_total); } - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); notification_message_block(nfc->notifications, &sequence_set_green_255); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c index dd842464..afc5f0de 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c @@ -84,7 +84,7 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { } else { MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); TextBox* text_box = nfc->text_box; - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); if(event.event == SubmenuIndexAppInfo) { mf_df_cat_application_info(app, nfc->text_box_store); } else { @@ -98,7 +98,7 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { } mf_df_cat_file(file, nfc->text_box_store); } - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); consumed = true; @@ -120,6 +120,6 @@ void nfc_scene_mf_desfire_app_on_exit(void* context) { // Clear views popup_reset(nfc->popup); text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); submenu_reset(nfc->submenu); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c index 0019a084..e619d037 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c @@ -67,10 +67,10 @@ bool nfc_scene_mf_desfire_data_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { TextBox* text_box = nfc->text_box; - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); if(event.event == SubmenuIndexCardInfo) { mf_df_cat_card_info(data, nfc->text_box_store); - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); scene_manager_set_scene_state( nfc->scene_manager, @@ -102,6 +102,6 @@ void nfc_scene_mf_desfire_data_on_exit(void* context) { // Clear views text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); submenu_reset(nfc->submenu); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c index 12047c15..c5b8cfa2 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -20,20 +20,19 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { Widget* widget = nfc->widget; // Prepare string for data display - string_t temp_str; - string_init_printf(temp_str, "\e#MIFARE DESfire\n"); - string_cat_printf(temp_str, "UID:"); + FuriString* temp_str = furi_string_alloc_printf("\e#MIFARE DESfire\n"); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%d", bytes_total); if(data->version.sw_storage & 1) { - string_push_back(temp_str, '+'); + furi_string_push_back(temp_str, '+'); } - string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; @@ -43,20 +42,20 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { n_files++; } } - string_cat_printf(temp_str, "%d Application", n_apps); + furi_string_cat_printf(temp_str, "%d Application", n_apps); if(n_apps != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } - string_cat_printf(temp_str, ", %d file", n_files); + furi_string_cat_printf(temp_str, ", %d file", n_files); if(n_files != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } notification_message_block(nfc->notifications, &sequence_set_green_255); // Add text scroll element - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); // Add button elements widget_add_button_element( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c index d4184a6b..8cd223ee 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c @@ -8,11 +8,11 @@ void nfc_scene_mf_ultralight_data_on_enter(void* context) { text_box_set_font(text_box, TextBoxFontHex); for(uint16_t i = 0; i < data->data_size; i += 2) { if(!(i % 8) && i) { - string_push_back(nfc->text_box_store, '\n'); + furi_string_push_back(nfc->text_box_store, '\n'); } - string_cat_printf(nfc->text_box_store, "%02X%02X ", data->data[i], data->data[i + 1]); + furi_string_cat_printf(nfc->text_box_store, "%02X%02X ", data->data[i], data->data[i + 1]); } - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); } @@ -28,5 +28,5 @@ void nfc_scene_mf_ultralight_data_on_exit(void* context) { // Clean view text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); } \ No newline at end of file diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c index b9421545..f0c53c9b 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c @@ -21,8 +21,8 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; MfUltralightConfigPages* config_pages = mf_ultralight_get_config_pages(mf_ul_data); Widget* widget = nfc->widget; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); if((mf_ul_data->data_read == mf_ul_data->data_size) && (mf_ul_data->data_read > 0)) { widget_add_string_element( @@ -31,14 +31,14 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { widget_add_string_element( widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Not all pages unlocked!"); } - string_set_str(temp_str, "UID:"); + furi_string_set(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } widget_add_string_element( - widget, 0, 17, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); if(mf_ul_data->auth_success) { - string_printf( + furi_string_printf( temp_str, "Password: %02X %02X %02X %02X", config_pages->auth_data.pwd.raw[0], @@ -46,19 +46,19 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { config_pages->auth_data.pwd.raw[2], config_pages->auth_data.pwd.raw[3]); widget_add_string_element( - widget, 0, 28, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); - string_printf( + widget, 0, 28, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + furi_string_printf( temp_str, "PACK: %02X %02X", config_pages->auth_data.pack.raw[0], config_pages->auth_data.pack.raw[1]); widget_add_string_element( - widget, 0, 39, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); } - string_printf( + furi_string_printf( temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4); widget_add_string_element( - widget, 0, 50, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 50, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_button_element( widget, GuiButtonTypeRight, @@ -66,7 +66,7 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { nfc_scene_mf_ultralight_read_auth_result_widget_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c index f6dc5984..77034ea8 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c @@ -33,23 +33,23 @@ void nfc_scene_mf_ultralight_read_success_on_enter(void* context) { nfc_scene_mf_ultralight_read_success_widget_callback, nfc); - string_t temp_str; - if(string_size(nfc->dev->dev_data.parsed_data)) { - string_init_set(temp_str, nfc->dev->dev_data.parsed_data); + FuriString* temp_str; + if(furi_string_size(nfc->dev->dev_data.parsed_data)) { + temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data); } else { - string_init_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(mf_ul_data->type, true)); - string_cat_printf(temp_str, "UID:"); + temp_str = furi_string_alloc_printf("\e#%s\n", nfc_mf_ul_type(mf_ul_data->type, true)); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } - string_cat_printf( + furi_string_cat_printf( temp_str, "\nPages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4); if(mf_ul_data->data_read != mf_ul_data->data_size) { - string_cat_printf(temp_str, "\nPassword-protected pages!"); + furi_string_cat_printf(temp_str, "\nPassword-protected pages!"); } } - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); notification_message_block(nfc->notifications, &sequence_set_green_255); diff --git a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c index b45b690d..9fd4f5ae 100644 --- a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c +++ b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c @@ -11,21 +11,21 @@ void nfc_scene_mfkey_nonces_info_callback(GuiButtonType result, InputType type, void nfc_scene_mfkey_nonces_info_on_enter(void* context) { Nfc* nfc = context; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint16_t nonces_saved = mfkey32_get_auth_sectors(temp_str); - widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, string_get_cstr(temp_str)); - string_printf(temp_str, "Nonces saved %d", nonces_saved); + widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, furi_string_get_cstr(temp_str)); + furi_string_printf(temp_str, "Nonces saved %d", nonces_saved); widget_add_string_element( - nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, string_get_cstr(temp_str)); + nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(temp_str)); widget_add_string_element( nfc->widget, 0, 12, AlignLeft, AlignTop, FontSecondary, "Authenticated sectors:"); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "Next", nfc_scene_mfkey_nonces_info_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 33f5e44a..bb7d58f7 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -22,47 +22,48 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { text_scroll_height = 64; } - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); // Set name if present if(nfc->dev->dev_name[0] != '\0') { - string_printf(temp_str, "\ec%s\n", nfc->dev->dev_name); + furi_string_printf(temp_str, "\ec%s\n", nfc->dev->dev_name); } // Set tag type if(protocol == NfcDeviceProtocolEMV) { - string_cat_printf(temp_str, "\e#EMV Bank Card\n"); + furi_string_cat_printf(temp_str, "\e#EMV Bank Card\n"); } else if(protocol == NfcDeviceProtocolMifareUl) { - string_cat_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true)); + furi_string_cat_printf( + temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true)); } else if(protocol == NfcDeviceProtocolMifareClassic) { - string_cat_printf( + furi_string_cat_printf( temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { - string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); + furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); } else { - string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); + furi_string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); } // Set tag iso data char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3'; - string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); - string_cat_printf(temp_str, "UID:"); + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } - string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); - string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); + furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); // Set application specific data if(protocol == NfcDeviceProtocolMifareDesfire) { MifareDesfireData* data = &dev_data->mf_df_data; uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%d", bytes_total); if(data->version.sw_storage & 1) { - string_push_back(temp_str, '+'); + furi_string_push_back(temp_str, '+'); } - string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; @@ -72,20 +73,20 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { n_files++; } } - string_cat_printf(temp_str, "%d Application", n_apps); + furi_string_cat_printf(temp_str, "%d Application", n_apps); if(n_apps != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } - string_cat_printf(temp_str, ", %d file", n_files); + furi_string_cat_printf(temp_str, ", %d file", n_files); if(n_files != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } } else if(protocol == NfcDeviceProtocolMifareUl) { MfUltralightData* data = &dev_data->mf_ul_data; - string_cat_printf( + furi_string_cat_printf( temp_str, "\nPages Read %d/%d", data->data_read / 4, data->data_size / 4); if(data->data_size > data->data_read) { - string_cat_printf(temp_str, "\nPassword-protected"); + furi_string_cat_printf(temp_str, "\nPassword-protected"); } } else if(protocol == NfcDeviceProtocolMifareClassic) { MfClassicData* data = &dev_data->mf_classic_data; @@ -94,14 +95,14 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { uint8_t keys_found = 0; uint8_t sectors_read = 0; mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); - string_cat_printf(temp_str, "\nKeys Found %d/%d", keys_found, keys_total); - string_cat_printf(temp_str, "\nSectors Read %d/%d", sectors_read, sectors_total); + furi_string_cat_printf(temp_str, "\nKeys Found %d/%d", keys_found, keys_total); + furi_string_cat_printf(temp_str, "\nSectors Read %d/%d", sectors_read, sectors_total); } // Add text scroll widget widget_add_text_scroll_element( - widget, 0, 0, 128, text_scroll_height, string_get_cstr(temp_str)); - string_clear(temp_str); + widget, 0, 0, 128, text_scroll_height, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c b/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c index c695da24..2ea7c992 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c @@ -22,22 +22,22 @@ void nfc_scene_nfca_read_success_on_enter(void* context) { FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; - string_t temp_str; - string_init_set_str(temp_str, "\e#Unknown ISO tag\n"); + FuriString* temp_str; + temp_str = furi_string_alloc_set("\e#Unknown ISO tag\n"); notification_message_block(nfc->notifications, &sequence_set_green_255); char iso_type = FURI_BIT(data->sak, 5) ? '4' : '3'; - string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); - string_cat_printf(temp_str, "UID:"); + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } - string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); - string_cat_printf(temp_str, " SAK: %02X", data->sak); + furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X", data->sak); - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", nfc_scene_nfca_read_success_widget_callback, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_read_card_success.c b/applications/main/nfc/scenes/nfc_scene_read_card_success.c index 0cb38cbd..352cb4a7 100644 --- a/applications/main/nfc/scenes/nfc_scene_read_card_success.c +++ b/applications/main/nfc/scenes/nfc_scene_read_card_success.c @@ -16,26 +16,26 @@ void nfc_scene_read_card_success_widget_callback( void nfc_scene_read_card_success_on_enter(void* context) { Nfc* nfc = context; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Setup view FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; - string_set_str(temp_str, nfc_get_dev_type(data->type)); + furi_string_set(temp_str, nfc_get_dev_type(data->type)); widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, string_get_cstr(temp_str)); - string_set_str(temp_str, "UID:"); + widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, furi_string_get_cstr(temp_str)); + furi_string_set(temp_str, "UID:"); for(uint8_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(temp_str)); + widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_save_name.c b/applications/main/nfc/scenes/nfc_scene_save_name.c index d5e05472..736eab7d 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_name.c +++ b/applications/main/nfc/scenes/nfc_scene_save_name.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "m-string.h" #include #include #include @@ -31,22 +30,22 @@ void nfc_scene_save_name_on_enter(void* context) { NFC_DEV_NAME_MAX_LEN, dev_name_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(nfc->dev->load_path, NFC_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(nfc->dev->load_path), folder_path); + if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path); } else { - string_set_str(folder_path, NFC_APP_FOLDER); + furi_string_set(folder_path, NFC_APP_FOLDER); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); + furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); - string_clear(folder_path); + furi_string_free(folder_path); } bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_set_type.c b/applications/main/nfc/scenes/nfc_scene_set_type.c index ec6d1144..3e08aeb3 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_type.c +++ b/applications/main/nfc/scenes/nfc_scene_set_type.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "m-string.h" #include "../helpers/nfc_generators.h" enum SubmenuIndex { @@ -19,7 +18,7 @@ void nfc_scene_set_type_on_enter(void* context) { Submenu* submenu = nfc->submenu; // Clear device name nfc_device_set_name(nfc->dev, ""); - string_set_str(nfc->dev->load_path, ""); + furi_string_set(nfc->dev->load_path, ""); submenu_add_item( submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu_add_item( diff --git a/applications/main/nfc/views/dict_attack.c b/applications/main/nfc/views/dict_attack.c index b4674fd3..cbafbf69 100644 --- a/applications/main/nfc/views/dict_attack.c +++ b/applications/main/nfc/views/dict_attack.c @@ -1,6 +1,5 @@ #include "dict_attack.h" -#include #include typedef enum { @@ -17,7 +16,7 @@ struct DictAttack { typedef struct { DictAttackState state; MfClassicType type; - string_t header; + FuriString* header; uint8_t sectors_total; uint8_t sectors_read; uint8_t sector_current; @@ -38,7 +37,8 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) { } else if(m->state == DictAttackStateRead) { char draw_str[32] = {}; canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, string_get_cstr(m->header)); + canvas_draw_str_aligned( + canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(m->header)); canvas_set_font(canvas, FontSecondary); float dict_progress = m->dict_keys_total == 0 ? 0 : @@ -81,7 +81,7 @@ DictAttack* dict_attack_alloc() { view_set_context(dict_attack->view, dict_attack); with_view_model( dict_attack->view, (DictAttackViewModel * model) { - string_init(model->header); + model->header = furi_string_alloc(); return false; }); return dict_attack; @@ -91,7 +91,7 @@ void dict_attack_free(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( dict_attack->view, (DictAttackViewModel * model) { - string_clear(model->header); + furi_string_free(model->header); return false; }); view_free(dict_attack->view); @@ -111,7 +111,7 @@ void dict_attack_reset(DictAttack* dict_attack) { model->keys_found = 0; model->dict_keys_total = 0; model->dict_keys_current = 0; - string_reset(model->header); + furi_string_reset(model->header); return false; }); } @@ -134,7 +134,7 @@ void dict_attack_set_header(DictAttack* dict_attack, const char* header) { with_view_model( dict_attack->view, (DictAttackViewModel * model) { - string_set_str(model->header, header); + furi_string_set(model->header, header); return true; }); } diff --git a/applications/main/subghz/helpers/subghz_types.h b/applications/main/subghz/helpers/subghz_types.h index 7fe1e7ce..023fb4b6 100644 --- a/applications/main/subghz/helpers/subghz_types.h +++ b/applications/main/subghz/helpers/subghz_types.h @@ -1,6 +1,5 @@ #pragma once -#include "m-string.h" #include #include @@ -72,7 +71,7 @@ typedef enum { } SubGhzViewId; struct SubGhzPresetDefinition { - string_t name; + FuriString* name; uint32_t frequency; uint8_t* data; size_t data_size; diff --git a/applications/main/subghz/scenes/subghz_scene_delete.c b/applications/main/subghz/scenes/subghz_scene_delete.c index 43151de2..94814b14 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete.c +++ b/applications/main/subghz/scenes/subghz_scene_delete.c @@ -11,17 +11,23 @@ void subghz_scene_delete_callback(GuiButtonType result, InputType type, void* co void subghz_scene_delete_on_enter(void* context) { SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; - string_t text; + FuriString* frequency_str; + FuriString* modulation_str; + FuriString* text; - string_init(frequency_str); - string_init(modulation_str); - string_init(text); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); + text = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( - subghz->widget, 78, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(frequency_str)); + subghz->widget, + 78, + 0, + AlignLeft, + AlignTop, + FontSecondary, + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -30,14 +36,14 @@ void subghz_scene_delete_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); + subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(text); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(text); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_callback, subghz); @@ -49,7 +55,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDelete) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/main/subghz/scenes/subghz_scene_delete_raw.c b/applications/main/subghz/scenes/subghz_scene_delete_raw.c index a20968d5..fa4fc6f6 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_raw.c @@ -15,18 +15,18 @@ void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void void subghz_scene_delete_raw_on_enter(void* context) { SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); char delete_str[SUBGHZ_MAX_LEN_NAME + 16]; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(subghz->file_path, file_name, true); - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(file_name)); - string_clear(file_name); + snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(file_name)); + furi_string_free(file_name); widget_add_text_box_element( subghz->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); @@ -35,7 +35,13 @@ void subghz_scene_delete_raw_on_enter(void* context) { subghz->widget, 38, 25, AlignLeft, AlignTop, FontSecondary, "RAW signal"); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( - subghz->widget, 35, 37, AlignLeft, AlignTop, FontSecondary, string_get_cstr(frequency_str)); + subghz->widget, + 35, + 37, + AlignLeft, + AlignTop, + FontSecondary, + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -44,10 +50,10 @@ void subghz_scene_delete_raw_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_raw_callback, subghz); @@ -61,7 +67,7 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDeleteRAW) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/main/subghz/scenes/subghz_scene_more_raw.c b/applications/main/subghz/scenes/subghz_scene_more_raw.c index a5bade92..d75ab13c 100644 --- a/applications/main/subghz/scenes/subghz_scene_more_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_more_raw.c @@ -45,7 +45,7 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW); return true; } else if(event.event == SubmenuIndexEdit) { - string_reset(subghz->file_path_tmp); + furi_string_reset(subghz->file_path_tmp); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 38b73e07..5dacefd6 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -10,8 +10,8 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { bool ret = false; //set the path to read the file - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!flipper_format_rewind(subghz->txrx->fff_data)) { FURI_LOG_E(TAG, "Rewind error"); @@ -23,12 +23,12 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { break; } - string_set(subghz->file_path, temp_str); + furi_string_set(subghz->file_path, temp_str); ret = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return ret; } @@ -36,18 +36,20 @@ static void subghz_scene_read_raw_update_statusbar(void* context) { furi_assert(context); SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_read_raw_add_data_statusbar( - subghz->subghz_read_raw, string_get_cstr(frequency_str), string_get_cstr(modulation_str)); + subghz->subghz_read_raw, + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); } void subghz_scene_read_raw_callback(SubGhzCustomEvent event, void* context) { @@ -65,8 +67,8 @@ void subghz_scene_read_raw_callback_end_tx(void* context) { void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); switch(subghz->txrx->rx_key_state) { case SubGhzRxKeyStateBack: @@ -75,13 +77,15 @@ void subghz_scene_read_raw_on_enter(void* context) { case SubGhzRxKeyStateRAWLoad: path_extract_filename(subghz->file_path, file_name, true); subghz_read_raw_set_status( - subghz->subghz_read_raw, SubGhzReadRAWStatusLoadKeyTX, string_get_cstr(file_name)); + subghz->subghz_read_raw, + SubGhzReadRAWStatusLoadKeyTX, + furi_string_get_cstr(file_name)); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; case SubGhzRxKeyStateRAWSave: path_extract_filename(subghz->file_path, file_name, true); subghz_read_raw_set_status( - subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, string_get_cstr(file_name)); + subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, furi_string_get_cstr(file_name)); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; default: @@ -89,7 +93,7 @@ void subghz_scene_read_raw_on_enter(void* context) { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; } - string_clear(file_name); + furi_string_free(file_name); subghz_scene_read_raw_update_statusbar(subghz); //set callback view raw @@ -174,7 +178,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWErase: if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { if(subghz_scene_read_raw_update_filename(subghz)) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); subghz_delete_file(subghz); } } @@ -245,12 +249,13 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_protocol_raw_save_to_file_stop( (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result); - string_t temp_str; - string_init(temp_str); - string_printf( + FuriString* temp_str; + temp_str = furi_string_alloc(); + furi_string_printf( temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION); - subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str)); - string_clear(temp_str); + subghz_protocol_raw_gen_fff_data( + subghz->txrx->fff_data, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); if(spl_count > 0) { notification_message(subghz->notifications, &sequence_set_green_255); @@ -279,13 +284,14 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, + furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz->state_notifications = SubGhzNotificationStateRx; subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { - string_set_str(subghz->error_str, "Function requires\nan SD card."); + furi_string_set(subghz->error_str, "Function requires\nan SD card."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 7c1f016d..77a92145 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -33,31 +33,31 @@ static const NotificationSequence subghs_sequence_rx_locked = { static void subghz_scene_receiver_update_statusbar(void* context) { SubGhz* subghz = context; - string_t history_stat_str; - string_init(history_stat_str); + FuriString* history_stat_str; + history_stat_str = furi_string_alloc(); if(!subghz_history_get_text_space_left(subghz->txrx->history, history_stat_str)) { - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_view_receiver_add_data_statusbar( subghz->subghz_receiver, - string_get_cstr(frequency_str), - string_get_cstr(modulation_str), - string_get_cstr(history_stat_str)); + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str), + furi_string_get_cstr(history_stat_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); } else { subghz_view_receiver_add_data_statusbar( - subghz->subghz_receiver, string_get_cstr(history_stat_str), "", ""); + subghz->subghz_receiver, furi_string_get_cstr(history_stat_str), "", ""); subghz->state_notifications = SubGhzNotificationStateIDLE; } - string_clear(history_stat_str); + furi_string_free(history_stat_str); } void subghz_scene_receiver_callback(SubGhzCustomEvent event, void* context) { @@ -72,11 +72,11 @@ static void subghz_scene_add_to_history_callback( void* context) { furi_assert(context); SubGhz* subghz = context; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { - string_reset(str_buff); + furi_string_reset(str_buff); subghz->state_notifications = SubGhzNotificationStateRxDone; @@ -84,22 +84,22 @@ static void subghz_scene_add_to_history_callback( subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - string_get_cstr(str_buff), + furi_string_get_cstr(str_buff), subghz_history_get_type_protocol( subghz->txrx->history, subghz_history_get_item(subghz->txrx->history) - 1)); subghz_scene_receiver_update_statusbar(subghz); } subghz_receiver_reset(receiver); - string_clear(str_buff); + furi_string_free(str_buff); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } void subghz_scene_receiver_on_enter(void* context) { SubGhz* subghz = context; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { subghz_preset_init( @@ -113,15 +113,15 @@ void subghz_scene_receiver_on_enter(void* context) { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { - string_reset(str_buff); + furi_string_reset(str_buff); subghz_history_get_text_item_menu(subghz->txrx->history, str_buff, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - string_get_cstr(str_buff), + furi_string_get_cstr(str_buff), subghz_history_get_type_protocol(subghz->txrx->history, i)); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } - string_clear(str_buff); + furi_string_free(str_buff); subghz_scene_receiver_update_statusbar(subghz); subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); @@ -137,7 +137,7 @@ void subghz_scene_receiver_on_enter(void* context) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 541ec0e0..5f022d6e 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -191,7 +191,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_preset, subghz); value_index = subghz_scene_receiver_config_next_preset( - string_get_cstr(subghz->txrx->preset->name), subghz); + furi_string_get_cstr(subghz->txrx->preset->name), subghz); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text( item, subghz_setting_get_preset_name(subghz->setting, value_index)); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 6f3e6fd1..2e833edd 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -32,7 +32,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { subghz_history_get_preset_def(subghz->txrx->history, subghz->txrx->idx_menu_chosen); subghz_preset_init( subghz, - string_get_cstr(preset->name), + furi_string_get_cstr(preset->name), preset->frequency, preset->data, preset->data_size); @@ -47,13 +47,13 @@ void subghz_scene_receiver_info_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo); if(subghz_scene_receiver_info_update_parser(subghz)) { - string_t frequency_str; - string_t modulation_str; - string_t text; + FuriString* frequency_str; + FuriString* modulation_str; + FuriString* text; - string_init(frequency_str); - string_init(modulation_str); - string_init(text); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); + text = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( @@ -63,7 +63,7 @@ void subghz_scene_receiver_info_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(frequency_str)); + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -72,14 +72,14 @@ void subghz_scene_receiver_info_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); + subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(text); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(text); if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == SubGhzProtocolFlag_Save) { @@ -146,7 +146,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 652499d0..1f06f4f9 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -61,20 +61,20 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(subghz_key_load(subghz, arg, false)) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded); - string_set_str(subghz->file_path, arg); + furi_string_set(subghz->file_path, arg); result = true; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(subghz->file_path, file_name, true); snprintf( subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME, "loaded\n%s", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); - string_clear(file_name); + furi_string_free(file_name); } } rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventLoadFile, result); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 12ec9868..b9bb3636 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -1,5 +1,4 @@ #include "../subghz_i.h" -#include "m-string.h" #include "subghz/types.h" #include #include "../helpers/subghz_custom_event.h" @@ -21,21 +20,21 @@ void subghz_scene_save_name_on_enter(void* context) { TextInput* text_input = subghz->text_input; bool dev_name_empty = false; - string_t file_name; - string_t dir_name; - string_init(file_name); - string_init(dir_name); + FuriString* file_name; + FuriString* dir_name; + file_name = furi_string_alloc(); + dir_name = furi_string_alloc(); if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); - string_set_str(file_name, file_name_buf); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_set(file_name, file_name_buf); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); //highlighting the entire filename by default dev_name_empty = true; } else { - string_set(subghz->file_path_tmp, subghz->file_path); - path_extract_dirname(string_get_cstr(subghz->file_path), dir_name); + furi_string_set(subghz->file_path_tmp, subghz->file_path); + path_extract_dirname(furi_string_get_cstr(subghz->file_path), dir_name); path_extract_filename(subghz->file_path, file_name, true); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { @@ -46,10 +45,10 @@ void subghz_scene_save_name_on_enter(void* context) { } path_extract_filename(subghz->file_path, file_name, true); } - string_set(subghz->file_path, dir_name); + furi_string_set(subghz->file_path, dir_name); } - strncpy(subghz->file_name_tmp, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); + strncpy(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, @@ -59,12 +58,12 @@ void subghz_scene_save_name_on_enter(void* context) { MAX_TEXT_INPUT_LEN, // buffer size dev_name_empty); - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, ""); + ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( + furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, ""); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(file_name); - string_clear(dir_name); + furi_string_free(file_name); + furi_string_free(dir_name); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTextInput); } @@ -75,14 +74,14 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(!strcmp(subghz->file_name_tmp, "") || scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { - string_set(subghz->file_path, subghz->file_path_tmp); + furi_string_set(subghz->file_path, subghz->file_path_tmp); } scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveName) { if(strcmp(subghz->file_name_tmp, "")) { - string_cat_printf( + furi_string_cat_printf( subghz->file_path, "/%s%s", subghz->file_name_tmp, SUBGHZ_APP_EXTENSION); if(subghz_path_is_file(subghz->file_path_tmp)) { if(!subghz_rename_file(subghz)) { @@ -92,7 +91,9 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) != SubGhzCustomEventManagerNoSet) { subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz, + subghz->txrx->fff_data, + furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneSetType, @@ -102,14 +103,14 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { subghz, subghz_history_get_raw_data( subghz->txrx->history, subghz->txrx->idx_menu_chosen), - string_get_cstr(subghz->file_path)); + furi_string_get_cstr(subghz->file_path)); } } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { subghz_protocol_raw_gen_fff_data( - subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } else { @@ -119,7 +120,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); return true; } else { - string_set_str(subghz->error_str, "No name file"); + furi_string_set(subghz->error_str, "No name file"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return true; } diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 1a359542..1e7a7474 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -27,7 +27,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, protocol_name); if(subghz->txrx->decoder_result == NULL) { - string_set_str(subghz->error_str, "Protocol not\nfound!"); + furi_string_set(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return false; } @@ -261,7 +261,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } subghz_transmitter_free(subghz->txrx->transmitter); if(!generated_protocol) { - string_set_str( + furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } @@ -285,7 +285,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } subghz_transmitter_free(subghz->txrx->transmitter); if(!generated_protocol) { - string_set_str( + furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } diff --git a/applications/main/subghz/scenes/subghz_scene_show_error.c b/applications/main/subghz/scenes/subghz_scene_show_error.c index 5632a859..eadfb211 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error.c @@ -33,7 +33,7 @@ void subghz_scene_show_error_on_enter(void* context) { AlignCenter, AlignCenter, FontSecondary, - string_get_cstr(subghz->error_str)); + furi_string_get_cstr(subghz->error_str)); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == SubGhzCustomEventManagerSet) { widget_add_button_element( @@ -89,6 +89,6 @@ void subghz_scene_show_error_on_exit(void* context) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerNoSet); widget_reset(subghz->widget); - string_reset(subghz->error_str); + furi_string_reset(subghz->error_str); notification_message(subghz->notifications, &sequence_reset_rgb); } diff --git a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c index 74e03432..2720b2b9 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c @@ -12,7 +12,7 @@ void subghz_scene_show_error_sub_on_enter(void* context) { // Setup view Popup* popup = subghz->popup; popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48); - popup_set_header(popup, string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop); + popup_set_header(popup, furi_string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop); popup_set_timeout(popup, 1500); popup_set_context(popup, subghz); popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback); @@ -46,7 +46,7 @@ void subghz_scene_show_error_sub_on_exit(void* context) { popup_set_context(popup, NULL); popup_set_timeout(popup, 0); popup_disable_timeout(popup); - string_reset(subghz->error_str); + furi_string_reset(subghz->error_str); notification_message(subghz->notifications, &sequence_reset_rgb); } diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index b3f8d079..5da6f430 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -13,13 +13,13 @@ bool subghz_scene_transmitter_update_data_show(void* context) { SubGhz* subghz = context; if(subghz->txrx->decoder_result) { - string_t key_str; - string_t frequency_str; - string_t modulation_str; + FuriString* key_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(key_str); - string_init(frequency_str); - string_init(modulation_str); + key_str = furi_string_alloc(); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); uint8_t show_button = 0; subghz_protocol_decoder_base_deserialize( @@ -34,14 +34,14 @@ bool subghz_scene_transmitter_update_data_show(void* context) { subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_view_transmitter_add_data_to_show( subghz->subghz_transmitter, - string_get_cstr(key_str), - string_get_cstr(frequency_str), - string_get_cstr(modulation_str), + furi_string_get_cstr(key_str), + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str), show_button); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(key_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(key_str); return true; } @@ -94,7 +94,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart); return true; } else if(event.event == SubGhzCustomEventViewTransmitterError) { - string_set_str(subghz->error_str, "Protocol not\nfound!"); + furi_string_set(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 61960218..71c6bc2c 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -1,6 +1,5 @@ /* Abandon hope, all ye who enter here. */ -#include "m-string.h" #include "subghz/types.h" #include "subghz_i.h" #include @@ -62,8 +61,8 @@ void subghz_blink_stop(SubGhz* instance) { SubGhz* subghz_alloc() { SubGhz* subghz = malloc(sizeof(SubGhz)); - string_init(subghz->file_path); - string_init(subghz->file_path_tmp); + subghz->file_path = furi_string_alloc(); + subghz->file_path_tmp = furi_string_alloc(); // GUI subghz->gui = furi_record_open(RECORD_GUI); @@ -171,7 +170,7 @@ SubGhz* subghz_alloc() { subghz->lock = SubGhzLockOff; subghz->txrx = malloc(sizeof(SubGhzTxRx)); subghz->txrx->preset = malloc(sizeof(SubGhzPresetDefinition)); - string_init(subghz->txrx->preset->name); + subghz->txrx->preset->name = furi_string_alloc(); subghz_preset_init( subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); @@ -197,7 +196,7 @@ SubGhz* subghz_alloc() { subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->receiver); //Init Error_str - string_init(subghz->error_str); + subghz->error_str = furi_string_alloc(); return subghz; } @@ -282,20 +281,20 @@ void subghz_free(SubGhz* subghz) { subghz_worker_free(subghz->txrx->worker); flipper_format_free(subghz->txrx->fff_data); subghz_history_free(subghz->txrx->history); - string_clear(subghz->txrx->preset->name); + furi_string_free(subghz->txrx->preset->name); free(subghz->txrx->preset); free(subghz->txrx); //Error string - string_clear(subghz->error_str); + furi_string_free(subghz->error_str); // Notifications furi_record_close(RECORD_NOTIFICATION); subghz->notifications = NULL; // Path strings - string_clear(subghz->file_path); - string_clear(subghz->file_path_tmp); + furi_string_free(subghz->file_path); + furi_string_free(subghz->file_path_tmp); // The rest free(subghz); @@ -329,7 +328,7 @@ int32_t subghz_app(void* p) { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); if(subghz_key_load(subghz, p, true)) { - string_set_str(subghz->file_path, p); + furi_string_set(subghz->file_path, (const char*)p); if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { //Load Raw TX @@ -348,13 +347,13 @@ int32_t subghz_app(void* p) { } else { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); if(load_database) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); } else { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerSet); - string_set_str( + furi_string_set( subghz->error_str, "No SD card or\ndatabase found.\nSome app function\nmay be reduced."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index d921979f..c6e196fb 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -24,15 +24,15 @@ #define SUBGHZ_REGION_FILENAME "/int/.region_data" -void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { +void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz tx_carrier", "", string_get_cstr(args)); + cli_print_usage("subghz tx_carrier", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -68,15 +68,15 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { furi_hal_power_suppress_charge_exit(); } -void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { +void subghz_cli_command_rx_carrier(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz rx_carrier", "", string_get_cstr(args)); + cli_print_usage("subghz rx_carrier", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -109,15 +109,16 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_sleep(); } -void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { +void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; uint32_t key = 0x0074BADE; uint32_t repeat = 10; uint32_t te = 403; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lx %lu %lu %lu", &key, &frequency, &te, &repeat); + if(furi_string_size(args)) { + int ret = + sscanf(furi_string_get_cstr(args), "%lx %lu %lu %lu", &key, &frequency, &te, &repeat); if(ret != 4) { printf( "sscanf returned %d, key: %lx, frequency: %lu, te:%lu, repeat: %lu\r\n", @@ -129,7 +130,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { cli_print_usage( "subghz tx", "<3 Byte Key: in hex> ", - string_get_cstr(args)); + furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -147,9 +148,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { te, repeat); - string_t flipper_format_string; - string_init_printf( - flipper_format_string, + FuriString* flipper_format_string = furi_string_alloc_printf( "Protocol: Princeton\n" "Bit: 24\n" "Key: 00 00 00 00 00 %02X %02X %02X\n" @@ -163,7 +162,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); stream_clean(stream); - stream_write_cstring(stream, string_get_cstr(flipper_format_string)); + stream_write_cstring(stream, furi_string_get_cstr(flipper_format_string)); SubGhzEnvironment* environment = subghz_environment_alloc(); @@ -221,23 +220,23 @@ static void subghz_cli_command_rx_callback( SubGhzCliCommandRx* instance = context; instance->packet_count++; - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); subghz_protocol_decoder_base_get_string(decoder_base, text); subghz_receiver_reset(receiver); - printf("%s", string_get_cstr(text)); - string_clear(text); + printf("%s", furi_string_get_cstr(text)); + furi_string_free(text); } -void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { +void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz rx", "", string_get_cstr(args)); + cli_print_usage("subghz rx", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -309,32 +308,32 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { free(instance); } -void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { +void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t file_name; - string_init(file_name); - string_set_str(file_name, ANY_PATH("subghz/test.sub")); + FuriString* file_name; + file_name = furi_string_alloc(); + furi_string_set(file_name, ANY_PATH("subghz/test.sub")); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; bool check_file = false; do { - if(string_size(args)) { + if(furi_string_size(args)) { if(!args_read_string_and_trim(args, file_name)) { cli_print_usage( - "subghz decode_raw", "", string_get_cstr(args)); + "subghz decode_raw", "", furi_string_get_cstr(args)); break; } } - if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name))) { + if(!flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(file_name))) { printf( "subghz decode_raw \033[0;31mError open file\033[0m %s\r\n", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); break; } @@ -343,7 +342,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { break; } - if(!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE) && + if(!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE) && temp_data32 == SUBGHZ_KEY_FILE_VERSION) { } else { printf("subghz decode_raw \033[0;31mType or version mismatch\033[0m\r\n"); @@ -353,7 +352,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { check_file = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -385,14 +384,14 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { subghz_receiver_set_rx_callback(receiver, subghz_cli_command_rx_callback, instance); SubGhzFileEncoderWorker* file_worker_encoder = subghz_file_encoder_worker_alloc(); - if(subghz_file_encoder_worker_start(file_worker_encoder, string_get_cstr(file_name))) { + if(subghz_file_encoder_worker_start(file_worker_encoder, furi_string_get_cstr(file_name))) { //the worker needs a file in order to open and read part of the file furi_delay_ms(100); } printf( "Listening at \033[0;33m%s\033[0m.\r\n\r\nPress CTRL+C to stop\r\n\r\n", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { @@ -419,7 +418,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { subghz_file_encoder_worker_free(file_worker_encoder); free(instance); } - string_clear(file_name); + furi_string_free(file_name); } static void subghz_cli_command_print_usage() { @@ -445,14 +444,14 @@ static void subghz_cli_command_print_usage() { } } -static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_keeloq(Cli* cli, FuriString* args) { UNUSED(cli); uint8_t iv[16]; - string_t source; - string_t destination; - string_init(source); - string_init(destination); + FuriString* source; + FuriString* destination; + source = furi_string_alloc(); + destination = furi_string_alloc(); SubGhzKeystore* keystore = subghz_keystore_alloc(); @@ -472,30 +471,30 @@ static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { break; } - if(!subghz_keystore_load(keystore, string_get_cstr(source))) { + if(!subghz_keystore_load(keystore, furi_string_get_cstr(source))) { printf("Failed to load Keystore"); break; } - if(!subghz_keystore_save(keystore, string_get_cstr(destination), iv)) { + if(!subghz_keystore_save(keystore, furi_string_get_cstr(destination), iv)) { printf("Failed to save Keystore"); break; } } while(false); subghz_keystore_free(keystore); - string_clear(destination); - string_clear(source); + furi_string_free(destination); + furi_string_free(source); } -static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) { UNUSED(cli); uint8_t iv[16]; - string_t source; - string_t destination; - string_init(source); - string_init(destination); + FuriString* source; + FuriString* destination; + source = furi_string_alloc(); + destination = furi_string_alloc(); do { if(!args_read_string_and_trim(args, source)) { @@ -514,25 +513,25 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { } if(!subghz_keystore_raw_encrypted_save( - string_get_cstr(source), string_get_cstr(destination), iv)) { + furi_string_get_cstr(source), furi_string_get_cstr(destination), iv)) { printf("Failed to save Keystore"); break; } } while(false); - string_clear(destination); - string_clear(source); + furi_string_free(destination); + furi_string_free(source); } -static void subghz_cli_command_chat(Cli* cli, string_t args) { +static void subghz_cli_command_chat(Cli* cli, FuriString* args) { uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz chat", "", string_get_cstr(args)); + cli_print_usage("subghz chat", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -568,22 +567,22 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { size_t message_max_len = 64; uint8_t message[64] = {0}; - string_t input; - string_init(input); - string_t name; - string_init(name); - string_t output; - string_init(output); - string_t sysmsg; - string_init(sysmsg); + FuriString* input; + input = furi_string_alloc(); + FuriString* name; + name = furi_string_alloc(); + FuriString* output; + output = furi_string_alloc(); + FuriString* sysmsg; + sysmsg = furi_string_alloc(); bool exit = false; SubGhzChatEvent chat_event; NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); - string_set(input, name); - printf("%s", string_get_cstr(input)); + furi_string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); + furi_string_set(input, name); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); while(!exit) { @@ -597,63 +596,63 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { break; } else if( (chat_event.c == CliSymbolAsciiBackspace) || (chat_event.c == CliSymbolAsciiDel)) { - size_t len = string_length_u(input); - if(len > string_length_u(name)) { + size_t len = furi_string_utf8_length(input); + if(len > furi_string_utf8_length(name)) { printf("%s", "\e[D\e[1P"); fflush(stdout); //delete 1 char UTF - const char* str = string_get_cstr(input); + const char* str = furi_string_get_cstr(input); size_t size = 0; - m_str1ng_utf8_state_e s = M_STRING_UTF8_STARTING; - string_unicode_t u = 0; - string_reset(sysmsg); + FuriStringUTF8State s = FuriStringUTF8StateStarting; + FuriStringUnicodeValue u = 0; + furi_string_reset(sysmsg); while(*str) { - m_str1ng_utf8_decode(*str, &s, &u); - if((s == M_STRING_UTF8_ERROR) || s == M_STRING_UTF8_STARTING) { - string_push_u(sysmsg, u); + furi_string_utf8_decode(*str, &s, &u); + if((s == FuriStringUTF8StateError) || s == FuriStringUTF8StateStarting) { + furi_string_utf8_push(sysmsg, u); if(++size >= len - 1) break; - s = M_STRING_UTF8_STARTING; + s = FuriStringUTF8StateStarting; } str++; } - string_set(input, sysmsg); + furi_string_set(input, sysmsg); } } else if(chat_event.c == CliSymbolAsciiCR) { printf("\r\n"); - string_push_back(input, '\r'); - string_push_back(input, '\n'); + furi_string_push_back(input, '\r'); + furi_string_push_back(input, '\n'); while(!subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(input), - strlen(string_get_cstr(input)))) { + (uint8_t*)furi_string_get_cstr(input), + strlen(furi_string_get_cstr(input)))) { furi_delay_ms(10); } - string_printf(input, "%s", string_get_cstr(name)); - printf("%s", string_get_cstr(input)); + furi_string_printf(input, "%s", furi_string_get_cstr(name)); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); } else if(chat_event.c == CliSymbolAsciiLF) { //cut out the symbol \n } else { putc(chat_event.c, stdout); fflush(stdout); - string_push_back(input, chat_event.c); + furi_string_push_back(input, chat_event.c); break; case SubGhzChatEventRXData: do { memset(message, 0x00, message_max_len); size_t len = subghz_chat_worker_read(subghz_chat, message, message_max_len); for(size_t i = 0; i < len; i++) { - string_push_back(output, message[i]); + furi_string_push_back(output, message[i]); if(message[i] == '\n') { printf("\r"); for(uint8_t i = 0; i < 80; i++) { printf(" "); } - printf("\r %s", string_get_cstr(output)); - printf("%s", string_get_cstr(input)); + printf("\r %s", furi_string_get_cstr(output)); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); - string_reset(output); + furi_string_reset(output); } } } while(subghz_chat_worker_available(subghz_chat)); @@ -662,22 +661,22 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { notification_message(notification, &sequence_single_vibro); break; case SubGhzChatEventUserEntrance: - string_printf( + furi_string_printf( sysmsg, "\033[0;34m%s joined chat.\033[0m\r\n", furi_hal_version_get_name_ptr()); subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(sysmsg), - strlen(string_get_cstr(sysmsg))); + (uint8_t*)furi_string_get_cstr(sysmsg), + strlen(furi_string_get_cstr(sysmsg))); break; case SubGhzChatEventUserExit: - string_printf( + furi_string_printf( sysmsg, "\033[0;31m%s left chat.\033[0m\r\n", furi_hal_version_get_name_ptr()); subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(sysmsg), - strlen(string_get_cstr(sysmsg))); + (uint8_t*)furi_string_get_cstr(sysmsg), + strlen(furi_string_get_cstr(sysmsg))); furi_delay_ms(10); exit = true; break; @@ -693,10 +692,10 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { } } - string_clear(input); - string_clear(name); - string_clear(output); - string_clear(sysmsg); + furi_string_free(input); + furi_string_free(name); + furi_string_free(output); + furi_string_free(sysmsg); furi_hal_power_suppress_charge_exit(); furi_record_close(RECORD_NOTIFICATION); @@ -707,9 +706,9 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("\r\nExit chat\r\n"); } -static void subghz_cli_command(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); +static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -717,43 +716,43 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "chat") == 0) { + if(furi_string_cmp_str(cmd, "chat") == 0) { subghz_cli_command_chat(cli, args); break; } - if(string_cmp_str(cmd, "tx") == 0) { + if(furi_string_cmp_str(cmd, "tx") == 0) { subghz_cli_command_tx(cli, args, context); break; } - if(string_cmp_str(cmd, "rx") == 0) { + if(furi_string_cmp_str(cmd, "rx") == 0) { subghz_cli_command_rx(cli, args, context); break; } - if(string_cmp_str(cmd, "decode_raw") == 0) { + if(furi_string_cmp_str(cmd, "decode_raw") == 0) { subghz_cli_command_decode_raw(cli, args, context); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "encrypt_keeloq") == 0) { + if(furi_string_cmp_str(cmd, "encrypt_keeloq") == 0) { subghz_cli_command_encrypt_keeloq(cli, args); break; } - if(string_cmp_str(cmd, "encrypt_raw") == 0) { + if(furi_string_cmp_str(cmd, "encrypt_raw") == 0) { subghz_cli_command_encrypt_raw(cli, args); break; } - if(string_cmp_str(cmd, "tx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "tx_carrier") == 0) { subghz_cli_command_tx_carrier(cli, args, context); break; } - if(string_cmp_str(cmd, "rx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "rx_carrier") == 0) { subghz_cli_command_rx_carrier(cli, args, context); break; } @@ -762,7 +761,7 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { subghz_cli_command_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } static bool diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 820a13d1..0f67b4fc 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -3,13 +3,12 @@ #include #include -#include #define SUBGHZ_HISTORY_MAX 50 #define TAG "SubGhzHistory" typedef struct { - string_t item_str; + FuriString* item_str; FlipperFormat* flipper_string; uint8_t type; SubGhzPresetDefinition* preset; @@ -27,13 +26,13 @@ struct SubGhzHistory { uint32_t last_update_timestamp; uint16_t last_index_write; uint8_t code_last_hash_data; - string_t tmp_string; + FuriString* tmp_string; SubGhzHistoryStruct* history; }; SubGhzHistory* subghz_history_alloc(void) { SubGhzHistory* instance = malloc(sizeof(SubGhzHistory)); - string_init(instance->tmp_string); + instance->tmp_string = furi_string_alloc(); instance->history = malloc(sizeof(SubGhzHistoryStruct)); SubGhzHistoryItemArray_init(instance->history->data); return instance; @@ -41,11 +40,11 @@ SubGhzHistory* subghz_history_alloc(void) { void subghz_history_free(SubGhzHistory* instance) { furi_assert(instance); - string_clear(instance->tmp_string); + furi_string_free(instance->tmp_string); for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { - string_clear(item->item_str); - string_clear(item->preset->name); + furi_string_free(item->item_str); + furi_string_free(item->preset->name); free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; @@ -70,16 +69,16 @@ SubGhzPresetDefinition* subghz_history_get_preset_def(SubGhzHistory* instance, u const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); - return string_get_cstr(item->preset->name); + return furi_string_get_cstr(item->preset->name); } void subghz_history_reset(SubGhzHistory* instance) { furi_assert(instance); - string_reset(instance->tmp_string); + furi_string_reset(instance->tmp_string); for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { - string_clear(item->item_str); - string_clear(item->preset->name); + furi_string_free(item->item_str); + furi_string_free(item->preset->name); free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; @@ -106,9 +105,9 @@ const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t i flipper_format_rewind(item->flipper_string); if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { FURI_LOG_E(TAG, "Missing Protocol"); - string_reset(instance->tmp_string); + furi_string_reset(instance->tmp_string); } - return string_get_cstr(instance->tmp_string); + return furi_string_get_cstr(instance->tmp_string); } FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) { @@ -120,20 +119,20 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx return NULL; } } -bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output) { +bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) { furi_assert(instance); if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { - if(output != NULL) string_printf(output, "Memory is FULL"); + if(output != NULL) furi_string_printf(output, "Memory is FULL"); return true; } if(output != NULL) - string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); + furi_string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); return false; } -void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx) { +void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx) { SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); - string_set(output, item->item_str); + furi_string_set(output, item->item_str); } bool subghz_history_add_to_history( @@ -156,18 +155,18 @@ bool subghz_history_add_to_history( instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); instance->last_update_timestamp = furi_get_tick(); - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); SubGhzHistoryItem* item = SubGhzHistoryItemArray_push_raw(instance->history->data); item->preset = malloc(sizeof(SubGhzPresetDefinition)); item->type = decoder_base->protocol->type; item->preset->frequency = preset->frequency; - string_init(item->preset->name); - string_set(item->preset->name, preset->name); + item->preset->name = furi_string_alloc(); + furi_string_set(item->preset->name, preset->name); item->preset->data = preset->data; item->preset->data_size = preset->data_size; - string_init(item->item_str); + item->item_str = furi_string_alloc(); item->flipper_string = flipper_format_string_alloc(); subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); @@ -180,20 +179,20 @@ bool subghz_history_add_to_history( FURI_LOG_E(TAG, "Missing Protocol"); break; } - if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) { - string_set_str(instance->tmp_string, "KL "); + if(!strcmp(furi_string_get_cstr(instance->tmp_string), "KeeLoq")) { + furi_string_set(instance->tmp_string, "KL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - string_cat(instance->tmp_string, text); - } else if(!strcmp(string_get_cstr(instance->tmp_string), "Star Line")) { - string_set_str(instance->tmp_string, "SL "); + furi_string_cat(instance->tmp_string, text); + } else if(!strcmp(furi_string_get_cstr(instance->tmp_string), "Star Line")) { + furi_string_set(instance->tmp_string, "SL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - string_cat(instance->tmp_string, text); + furi_string_cat(instance->tmp_string, text); } if(!flipper_format_rewind(item->flipper_string)) { FURI_LOG_E(TAG, "Rewind error"); @@ -209,22 +208,22 @@ bool subghz_history_add_to_history( data = (data << 8) | key_data[i]; } if(!(uint32_t)(data >> 32)) { - string_printf( + furi_string_printf( item->item_str, "%s %lX", - string_get_cstr(instance->tmp_string), + furi_string_get_cstr(instance->tmp_string), (uint32_t)(data & 0xFFFFFFFF)); } else { - string_printf( + furi_string_printf( item->item_str, "%s %lX%08lX", - string_get_cstr(instance->tmp_string), + furi_string_get_cstr(instance->tmp_string), (uint32_t)(data >> 32), (uint32_t)(data & 0xFFFFFFFF)); } } while(false); - string_clear(text); + furi_string_free(text); instance->last_index_write++; return true; } diff --git a/applications/main/subghz/subghz_history.h b/applications/main/subghz/subghz_history.h index adbcfc18..7bff3df5 100644 --- a/applications/main/subghz/subghz_history.h +++ b/applications/main/subghz/subghz_history.h @@ -71,18 +71,18 @@ const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t i /** Get string item menu to history[idx] * * @param instance - SubGhzHistory instance - * @param output - string_t output + * @param output - FuriString* output * @param idx - record index */ -void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx); +void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx); /** Get string the remaining number of records to history * * @param instance - SubGhzHistory instance - * @param output - string_t output + * @param output - FuriString* output * @return bool - is FUUL */ -bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output); +bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output); /** Add protocol to history * diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 6ed8fd53..f2658c0e 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -26,7 +26,7 @@ void subghz_preset_init( size_t preset_data_size) { furi_assert(context); SubGhz* subghz = context; - string_set(subghz->txrx->preset->name, preset_name); + furi_string_set(subghz->txrx->preset->name, preset_name); subghz->txrx->preset->frequency = frequency; subghz->txrx->preset->data = preset_data; subghz->txrx->preset->data_size = preset_data_size; @@ -34,15 +34,15 @@ void subghz_preset_init( bool subghz_set_preset(SubGhz* subghz, const char* preset) { if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - string_set(subghz->txrx->preset->name, "AM270"); + furi_string_set(subghz->txrx->preset->name, "AM270"); } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - string_set(subghz->txrx->preset->name, "AM650"); + furi_string_set(subghz->txrx->preset->name, "AM650"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - string_set(subghz->txrx->preset->name, "FM238"); + furi_string_set(subghz->txrx->preset->name, "FM238"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - string_set(subghz->txrx->preset->name, "FM476"); + furi_string_set(subghz->txrx->preset->name, "FM476"); } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - string_set(subghz->txrx->preset->name, "CUSTOM"); + furi_string_set(subghz->txrx->preset->name, "CUSTOM"); } else { FURI_LOG_E(TAG, "Unknown preset"); return false; @@ -50,17 +50,17 @@ bool subghz_set_preset(SubGhz* subghz, const char* preset) { return true; } -void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_t modulation) { +void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation) { furi_assert(subghz); if(frequency != NULL) { - string_printf( + furi_string_printf( frequency, "%03ld.%02ld", subghz->txrx->preset->frequency / 1000000 % 1000, subghz->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { - string_printf(modulation, "%0.2s", string_get_cstr(subghz->txrx->preset->name)); + furi_string_printf(modulation, "%0.2s", furi_string_get_cstr(subghz->txrx->preset->name)); } } @@ -137,8 +137,8 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { furi_assert(subghz); bool ret = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t repeat = 200; do { if(!flipper_format_rewind(flipper_format)) { @@ -155,21 +155,21 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { break; } - subghz->txrx->transmitter = - subghz_transmitter_alloc_init(subghz->txrx->environment, string_get_cstr(temp_str)); + subghz->txrx->transmitter = subghz_transmitter_alloc_init( + subghz->txrx->environment, furi_string_get_cstr(temp_str)); if(subghz->txrx->transmitter) { if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format)) { - if(strcmp(string_get_cstr(subghz->txrx->preset->name), "")) { + if(strcmp(furi_string_get_cstr(subghz->txrx->preset->name), "")) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); } else { FURI_LOG_E( TAG, "Unknown name preset \" %s \"", - string_get_cstr(subghz->txrx->preset->name)); + furi_string_get_cstr(subghz->txrx->preset->name)); subghz_begin( subghz, subghz_setting_get_preset_data_by_name(subghz->setting, "AM650")); } @@ -193,7 +193,7 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { } } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return ret; } @@ -209,7 +209,7 @@ void subghz_tx_stop(SubGhz* subghz) { if((subghz->txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) && (subghz_path_is_file(subghz->file_path))) { subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz, subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); } subghz_idle(subghz); notification_message(subghz->notifications, &sequence_reset_red); @@ -244,8 +244,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); SubGhzLoadKeyState load_key_state = SubGhzLoadKeyStateParseErr; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; do { @@ -260,8 +260,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { break; } - if(((!strcmp(string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || - (!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && + if(((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || + (!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && temp_data32 == SUBGHZ_KEY_FILE_VERSION) { } else { FURI_LOG_E(TAG, "Type or version mismatch"); @@ -285,27 +285,29 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { break; } - if(!subghz_set_preset(subghz, string_get_cstr(temp_str))) { + if(!subghz_set_preset(subghz, furi_string_get_cstr(temp_str))) { break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { //Todo add Custom_preset_module //delete preset if it already exists subghz_setting_delete_custom_preset( - subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); //load custom preset from file if(!subghz_setting_load_custom_preset( - subghz->setting, string_get_cstr(subghz->txrx->preset->name), fff_data_file)) { + subghz->setting, + furi_string_get_cstr(subghz->txrx->preset->name), + fff_data_file)) { FURI_LOG_E(TAG, "Missing Custom preset"); break; } } size_t preset_index = subghz_setting_get_inx_preset_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); subghz_preset_init( subghz, - string_get_cstr(subghz->txrx->preset->name), + furi_string_get_cstr(subghz->txrx->preset->name), subghz->txrx->preset->frequency, subghz_setting_get_preset_data(subghz->setting, preset_index), subghz_setting_get_preset_data_size(subghz->setting, preset_index)); @@ -314,7 +316,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - if(!strcmp(string_get_cstr(temp_str), "RAW")) { + if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { //if RAW subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, file_path); } else { @@ -324,7 +326,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { } subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( - subghz->txrx->receiver, string_get_cstr(temp_str)); + subghz->txrx->receiver, furi_string_get_cstr(temp_str)); if(subghz->txrx->decoder_result) { if(!subghz_protocol_decoder_base_deserialize( subghz->txrx->decoder_result, subghz->txrx->fff_data)) { @@ -338,7 +340,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { load_key_state = SubGhzLoadKeyStateOK; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -362,42 +364,42 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { furi_assert(subghz); Storage* storage = furi_record_open(RECORD_STORAGE); - string_t temp_str; - string_t file_name; - string_t file_path; + FuriString* temp_str; + FuriString* file_name; + FuriString* file_path; - string_init(temp_str); - string_init(file_name); - string_init(file_path); + temp_str = furi_string_alloc(); + file_name = furi_string_alloc(); + file_path = furi_string_alloc(); bool res = false; if(subghz_path_is_file(subghz->file_path)) { //get the name of the next free file path_extract_filename(subghz->file_path, file_name, true); - path_extract_dirname(string_get_cstr(subghz->file_path), file_path); + path_extract_dirname(furi_string_get_cstr(subghz->file_path), file_path); storage_get_next_filename( storage, - string_get_cstr(file_path), - string_get_cstr(file_name), + furi_string_get_cstr(file_path), + furi_string_get_cstr(file_name), SUBGHZ_APP_EXTENSION, file_name, max_len); - string_printf( + furi_string_printf( temp_str, "%s/%s%s", - string_get_cstr(file_path), - string_get_cstr(file_name), + furi_string_get_cstr(file_path), + furi_string_get_cstr(file_name), SUBGHZ_APP_EXTENSION); - string_set(subghz->file_path, temp_str); + furi_string_set(subghz->file_path, temp_str); res = true; } - string_clear(temp_str); - string_clear(file_path); - string_clear(file_name); + furi_string_free(temp_str); + furi_string_free(file_path); + furi_string_free(file_name); furi_record_close(RECORD_STORAGE); return res; @@ -415,8 +417,8 @@ bool subghz_save_protocol_to_file( Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format); bool saved = false; - string_t file_dir; - string_init(file_dir); + FuriString* file_dir; + file_dir = furi_string_alloc(); path_extract_dirname(dev_file_name, file_dir); do { @@ -425,7 +427,7 @@ bool subghz_save_protocol_to_file( flipper_format_delete_key(flipper_format, "Manufacture"); // Create subghz folder directory if necessary - if(!storage_simply_mkdir(storage, string_get_cstr(file_dir))) { + if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder"); break; } @@ -439,7 +441,7 @@ bool subghz_save_protocol_to_file( saved = true; } while(0); - string_clear(file_dir); + furi_string_free(file_dir); furi_record_close(RECORD_STORAGE); return saved; } @@ -447,8 +449,8 @@ bool subghz_save_protocol_to_file( bool subghz_load_protocol_from_file(SubGhz* subghz) { furi_assert(subghz); - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); @@ -458,10 +460,10 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { subghz->dialogs, subghz->file_path, subghz->file_path, &browser_options); if(res) { - res = subghz_key_load(subghz, string_get_cstr(subghz->file_path), true); + res = subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), true); } - string_clear(file_path); + furi_string_free(file_path); return res; } @@ -472,9 +474,11 @@ bool subghz_rename_file(SubGhz* subghz) { Storage* storage = furi_record_open(RECORD_STORAGE); - if(string_cmp(subghz->file_path_tmp, subghz->file_path)) { + if(furi_string_cmp(subghz->file_path_tmp, subghz->file_path)) { FS_Error fs_result = storage_common_rename( - storage, string_get_cstr(subghz->file_path_tmp), string_get_cstr(subghz->file_path)); + storage, + furi_string_get_cstr(subghz->file_path_tmp), + furi_string_get_cstr(subghz->file_path)); if(fs_result != FSE_OK) { dialog_message_show_storage_error(subghz->dialogs, "Cannot rename\n file/directory"); @@ -490,7 +494,7 @@ bool subghz_delete_file(SubGhz* subghz) { furi_assert(subghz); Storage* storage = furi_record_open(RECORD_STORAGE); - bool result = storage_simply_remove(storage, string_get_cstr(subghz->file_path_tmp)); + bool result = storage_simply_remove(storage, furi_string_get_cstr(subghz->file_path_tmp)); furi_record_close(RECORD_STORAGE); subghz_file_name_clear(subghz); @@ -500,12 +504,12 @@ bool subghz_delete_file(SubGhz* subghz) { void subghz_file_name_clear(SubGhz* subghz) { furi_assert(subghz); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); - string_reset(subghz->file_path_tmp); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_reset(subghz->file_path_tmp); } -bool subghz_path_is_file(string_t path) { - return string_end_with_str_p(path, SUBGHZ_APP_EXTENSION); +bool subghz_path_is_file(FuriString* path) { + return furi_string_end_with(path, SUBGHZ_APP_EXTENSION); } uint32_t subghz_random_serial(void) { diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 99a0f8a2..58d30717 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -75,8 +75,8 @@ struct SubGhz { TextInput* text_input; Widget* widget; DialogsApp* dialogs; - string_t file_path; - string_t file_path_tmp; + FuriString* file_path; + FuriString* file_path_tmp; char file_name_tmp[SUBGHZ_MAX_LEN_NAME]; SubGhzNotificationState state_notifications; @@ -89,7 +89,7 @@ struct SubGhz { SubGhzTestStatic* subghz_test_static; SubGhzTestCarrier* subghz_test_carrier; SubGhzTestPacket* subghz_test_packet; - string_t error_str; + FuriString* error_str; SubGhzSetting* setting; SubGhzLock lock; @@ -103,7 +103,7 @@ void subghz_preset_init( uint8_t* preset_data, size_t preset_data_size); bool subghz_set_preset(SubGhz* subghz, const char* preset); -void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_t modulation); +void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation); void subghz_begin(SubGhz* subghz, uint8_t* preset_data); uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); void subghz_rx_end(SubGhz* subghz); @@ -125,6 +125,6 @@ bool subghz_load_protocol_from_file(SubGhz* subghz); bool subghz_rename_file(SubGhz* subghz); bool subghz_delete_file(SubGhz* subghz); void subghz_file_name_clear(SubGhz* subghz); -bool subghz_path_is_file(string_t path); +bool subghz_path_is_file(FuriString* path); uint32_t subghz_random_serial(void); void subghz_hopper_update(SubGhz* subghz); diff --git a/applications/main/subghz/subghz_setting.c b/applications/main/subghz/subghz_setting.c index b7c143cd..e0322f6a 100644 --- a/applications/main/subghz/subghz_setting.c +++ b/applications/main/subghz/subghz_setting.c @@ -158,7 +158,7 @@ static const uint32_t subghz_hopper_frequency_list_region_jp[] = { }; typedef struct { - string_t custom_preset_name; + FuriString* custom_preset_name; uint8_t* custom_preset_data; size_t custom_preset_data_size; } SubGhzSettingCustomPresetItem; @@ -194,7 +194,7 @@ SubGhzSetting* subghz_setting_alloc(void) { static void subghz_setting_preset_reset(SubGhzSetting* instance) { for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - string_clear(item->custom_preset_name); + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); } SubGhzSettingCustomPresetItemArray_reset(instance->preset->data); @@ -206,7 +206,7 @@ void subghz_setting_free(SubGhzSetting* instance) { FrequencyList_clear(instance->hopper_frequencies); for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - string_clear(item->custom_preset_name); + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); } SubGhzSettingCustomPresetItemArray_clear(instance->preset->data); @@ -225,8 +225,8 @@ static void subghz_setting_load_default_preset( SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - string_init(item->custom_preset_name); - string_set(item->custom_preset_name, preset_name); + item->custom_preset_name = furi_string_alloc(); + furi_string_set(item->custom_preset_name, preset_name); while(preset_data[preset_data_count]) { preset_data_count += 2; @@ -314,8 +314,8 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; bool temp_bool; @@ -333,7 +333,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } - if((!strcmp(string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && + if((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && temp_data32 == SUBGHZ_SETTING_FILE_VERSION) { } else { FURI_LOG_E(TAG, "Type or version mismatch"); @@ -402,15 +402,15 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } while(flipper_format_read_string(fff_data_file, "Custom_preset_name", temp_str)) { - FURI_LOG_I(TAG, "Custom preset loaded %s", string_get_cstr(temp_str)); + FURI_LOG_I(TAG, "Custom preset loaded %s", furi_string_get_cstr(temp_str)); subghz_setting_load_custom_preset( - instance, string_get_cstr(temp_str), fff_data_file); + instance, furi_string_get_cstr(temp_str), fff_data_file); } } while(false); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -440,7 +440,7 @@ const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx) furi_assert(instance); SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); - return string_get_cstr(item->custom_preset_name); + return furi_string_get_cstr(item->custom_preset_name); } int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name) { @@ -448,7 +448,7 @@ int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* p size_t idx = 0; for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { + if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { return idx; } idx++; @@ -466,8 +466,8 @@ bool subghz_setting_load_custom_preset( uint32_t temp_data32; SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - string_init(item->custom_preset_name); - string_set(item->custom_preset_name, preset_name); + item->custom_preset_name = furi_string_alloc(); + furi_string_set(item->custom_preset_name, preset_name); do { if(!flipper_format_get_value_count(fff_data_file, "Custom_preset_data", &temp_data32)) break; @@ -497,8 +497,8 @@ bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* pr SubGhzSettingCustomPresetItemArray_it_last(it, instance->preset->data); while(!SubGhzSettingCustomPresetItemArray_end_p(it)) { SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_ref(it); - if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { - string_clear(item->custom_preset_name); + if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); SubGhzSettingCustomPresetItemArray_remove(instance->preset->data, it); return true; diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index c28c3363..6ec12e78 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #define FRAME_HEIGHT 12 @@ -14,7 +13,7 @@ #define UNLOCK_CNT 3 typedef struct { - string_t item_str; + FuriString* item_str; uint8_t type; } SubGhzReceiverMenuItem; @@ -52,9 +51,9 @@ struct SubGhzViewReceiver { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t history_stat_str; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* history_stat_str; SubGhzReceiverHistory* history; uint16_t idx; uint16_t list_offset; @@ -121,7 +120,7 @@ void subghz_view_receiver_add_item_to_menu( subghz_receiver->view, (SubGhzViewReceiverModel * model) { SubGhzReceiverMenuItem* item_menu = SubGhzReceiverMenuItemArray_push_raw(model->history->data); - string_init_set_str(item_menu->item_str, name); + item_menu->item_str = furi_string_alloc_set(name); item_menu->type = type; if((model->idx == model->history_item - 1)) { model->history_item++; @@ -143,9 +142,9 @@ void subghz_view_receiver_add_data_statusbar( furi_assert(subghz_receiver); with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); - string_set_str(model->history_stat_str, history_stat_str); + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); + furi_string_set(model->history_stat_str, history_stat_str); return true; }); } @@ -173,15 +172,15 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_line(canvas, 46, 51, 125, 51); bool scrollbar = model->history_item > 4; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); SubGhzReceiverMenuItem* item_menu; for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx); - string_set(str_buff, item_menu->item_str); + furi_string_set(str_buff, item_menu->item_str); elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); if(model->idx == idx) { subghz_view_receiver_draw_frame(canvas, i, scrollbar); @@ -189,13 +188,13 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_set_color(canvas, ColorBlack); } canvas_draw_icon(canvas, 1, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, string_get_cstr(str_buff)); - string_reset(str_buff); + canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); + furi_string_reset(str_buff); } if(scrollbar) { elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); } - string_clear(str_buff); + furi_string_free(str_buff); canvas_set_color(canvas, ColorBlack); @@ -213,9 +212,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 74, 62, "Locked"); break; case SubGhzViewReceiverBarShowToUnlockPress: - canvas_draw_str(canvas, 44, 62, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); canvas_set_font(canvas, FontSecondary); elements_bold_rounded_frame(canvas, 14, 8, 99, 48); elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); @@ -230,9 +229,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 74, 62, "Unlocked"); break; default: - canvas_draw_str(canvas, 44, 62, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); break; } } @@ -331,12 +330,12 @@ void subghz_view_receiver_exit(void* context) { SubGhzViewReceiver* subghz_receiver = context; with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_reset(model->frequency_str); - string_reset(model->preset_str); - string_reset(model->history_stat_str); + furi_string_reset(model->frequency_str); + furi_string_reset(model->preset_str); + furi_string_reset(model->history_stat_str); for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { - string_clear(item_menu->item_str); + furi_string_free(item_menu->item_str); item_menu->type = 0; } SubGhzReceiverMenuItemArray_reset(model->history->data); @@ -366,9 +365,9 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->history_stat_str); + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->history_stat_str = furi_string_alloc(); model->bar_show = SubGhzViewReceiverBarShowDefault; model->history = malloc(sizeof(SubGhzReceiverHistory)); SubGhzReceiverMenuItemArray_init(model->history->data); @@ -384,12 +383,12 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->history_stat_str); + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->history_stat_str); for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { - string_clear(item_menu->item_str); + furi_string_free(item_menu->item_str); item_menu->type = 0; } SubGhzReceiverMenuItemArray_clear(model->history->data); diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index ccffaf42..0b4305b7 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -18,10 +18,10 @@ struct SubGhzReadRAW { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t sample_write; - string_t file_name; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* sample_write; + FuriString* file_name; uint8_t* rssi_history; bool rssi_history_end; uint8_t ind_write; @@ -46,8 +46,8 @@ void subghz_read_raw_add_data_statusbar( furi_assert(instance); with_view_model( instance->view, (SubGhzReadRAWModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); return true; }); } @@ -78,7 +78,7 @@ void subghz_read_raw_update_sample_write(SubGhzReadRAW* instance, size_t sample) with_view_model( instance->view, (SubGhzReadRAWModel * model) { - string_printf(model->sample_write, "%d spl.", sample); + furi_string_printf(model->sample_write, "%d spl.", sample); return false; }); } @@ -216,10 +216,10 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { uint8_t graphics_mode = 1; canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 5, 7, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 40, 7, string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 5, 7, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 40, 7, furi_string_get_cstr(model->preset_str)); canvas_draw_str_aligned( - canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); + canvas, 126, 0, AlignRight, AlignTop, furi_string_get_cstr(model->sample_write)); canvas_draw_line(canvas, 0, 14, 115, 14); canvas_draw_line(canvas, 0, 48, 115, 48); @@ -243,7 +243,7 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { 30, AlignCenter, AlignCenter, - string_get_cstr(model->file_name), + furi_string_get_cstr(model->file_name), true); break; @@ -372,8 +372,8 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->sample_write, "0 spl."); - string_reset(model->file_name); + furi_string_set(model->sample_write, "0 spl."); + furi_string_reset(model->file_name); instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context); } return true; @@ -423,8 +423,8 @@ void subghz_read_raw_set_status( model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; - string_reset(model->file_name); - string_set_str(model->sample_write, "0 spl."); + furi_string_reset(model->file_name); + furi_string_set(model->sample_write, "0 spl."); return true; }); break; @@ -441,8 +441,8 @@ void subghz_read_raw_set_status( model->status = SubGhzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); + furi_string_set(model->file_name, file_name); + furi_string_set(model->sample_write, "RAW"); return true; }); break; @@ -451,10 +451,10 @@ void subghz_read_raw_set_status( instance->view, (SubGhzReadRAWModel * model) { model->status = SubGhzReadRAWStatusLoadKeyIDLE; if(!model->ind_write) { - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); + furi_string_set(model->file_name, file_name); + furi_string_set(model->sample_write, "RAW"); } else { - string_reset(model->file_name); + furi_string_reset(model->file_name); } return true; }); @@ -501,10 +501,10 @@ SubGhzReadRAW* subghz_read_raw_alloc() { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->sample_write); - string_init(model->file_name); + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->sample_write = furi_string_alloc(); + model->file_name = furi_string_alloc(); model->rssi_history = malloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); return true; }); @@ -517,10 +517,10 @@ void subghz_read_raw_free(SubGhzReadRAW* instance) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->sample_write); - string_clear(model->file_name); + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->sample_write); + furi_string_free(model->file_name); free(model->rssi_history); return true; }); diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index dd2b6d32..1094c5c5 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -11,9 +11,9 @@ struct SubGhzViewTransmitter { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t key_str; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* key_str; uint8_t show_button; } SubGhzViewTransmitterModel; @@ -36,9 +36,9 @@ void subghz_view_transmitter_add_data_to_show( furi_assert(subghz_transmitter); with_view_model( subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_set_str(model->key_str, key_str); - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); + furi_string_set(model->key_str, key_str); + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); model->show_button = show_button; return true; }); @@ -82,9 +82,9 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 8, string_get_cstr(model->key_str)); - canvas_draw_str(canvas, 78, 8, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 113, 8, string_get_cstr(model->preset_str)); + elements_multiline_text(canvas, 0, 8, furi_string_get_cstr(model->key_str)); + canvas_draw_str(canvas, 78, 8, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 113, 8, furi_string_get_cstr(model->preset_str)); if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send"); } @@ -96,9 +96,9 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_reset(model->frequency_str); - string_reset(model->preset_str); - string_reset(model->key_str); + furi_string_reset(model->frequency_str); + furi_string_reset(model->preset_str); + furi_string_reset(model->key_str); model->show_button = 0; return false; }); @@ -150,9 +150,9 @@ SubGhzViewTransmitter* subghz_view_transmitter_alloc() { with_view_model( subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->key_str); + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->key_str = furi_string_alloc(); return true; }); return subghz_transmitter; @@ -163,9 +163,9 @@ void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter) { with_view_model( subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->key_str); + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->key_str); return true; }); view_free(subghz_transmitter->view); diff --git a/applications/main/u2f/u2f_data.c b/applications/main/u2f/u2f_data.c index 117fbdbe..900af462 100644 --- a/applications/main/u2f/u2f_data.c +++ b/applications/main/u2f/u2f_data.c @@ -181,8 +181,8 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { // Check if unique key exists in secure eclave and generate it if missing if(!furi_hal_crypto_verify_key(U2F_DATA_FILE_ENCRYPTION_KEY_SLOT_UNIQUE)) return false; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -194,7 +194,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { break; } - if(strcmp(string_get_cstr(filetype), U2F_CERT_KEY_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), U2F_CERT_KEY_FILE_TYPE) != 0 || version != U2F_CERT_KEY_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -250,7 +250,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); if(cert_type == U2F_CERT_USER_UNENCRYPTED) { return u2f_data_cert_key_encrypt(cert_key); @@ -267,8 +267,8 @@ bool u2f_data_key_load(uint8_t* device_key) { uint8_t key[48]; uint32_t version = 0; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -279,7 +279,7 @@ bool u2f_data_key_load(uint8_t* device_key) { FURI_LOG_E(TAG, "Missing or incorrect header"); break; } - if(strcmp(string_get_cstr(filetype), U2F_DEVICE_KEY_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), U2F_DEVICE_KEY_FILE_TYPE) != 0 || version != U2F_DEVICE_KEY_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -308,7 +308,7 @@ bool u2f_data_key_load(uint8_t* device_key) { } flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); return state; } @@ -366,8 +366,8 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { uint8_t cnt_encr[48]; uint32_t version = 0; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -378,7 +378,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { FURI_LOG_E(TAG, "Missing or incorrect header"); break; } - if(strcmp(string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0) { + if(strcmp(furi_string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0) { FURI_LOG_E(TAG, "Type mismatch"); break; } @@ -417,7 +417,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { } flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); if(old_counter && state) { // Change counter endianness and rewrite counter file diff --git a/applications/plugins/music_player/music_player.c b/applications/plugins/music_player/music_player.c index 40e9085f..6d3c4483 100644 --- a/applications/plugins/music_player/music_player.c +++ b/applications/plugins/music_player/music_player.c @@ -8,8 +8,6 @@ #include #include -#include - #define TAG "MusicPlayer" #define MUSIC_PLAYER_APP_PATH_FOLDER ANY_PATH("music_player") @@ -296,14 +294,14 @@ void music_player_free(MusicPlayer* instance) { int32_t music_player_app(void* p) { MusicPlayer* music_player = music_player_alloc(); - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { if(p && strlen(p)) { - string_cat_str(file_path, p); + furi_string_cat(file_path, (const char*)p); } else { - string_set_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); + furi_string_set(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( @@ -320,7 +318,7 @@ int32_t music_player_app(void* p) { } } - if(!music_player_worker_load(music_player->worker, string_get_cstr(file_path))) { + if(!music_player_worker_load(music_player->worker, furi_string_get_cstr(file_path))) { FURI_LOG_E(TAG, "Unable to load file"); break; } @@ -354,7 +352,7 @@ int32_t music_player_app(void* p) { music_player_worker_stop(music_player->worker); } while(0); - string_clear(file_path); + furi_string_free(file_path); music_player_free(music_player); return 0; diff --git a/applications/plugins/music_player/music_player_cli.c b/applications/plugins/music_player/music_player_cli.c index 78200443..90060d7e 100644 --- a/applications/plugins/music_player/music_player_cli.c +++ b/applications/plugins/music_player/music_player_cli.c @@ -3,20 +3,20 @@ #include #include "music_player_worker.h" -static void music_player_cli(Cli* cli, string_t args, void* context) { +static void music_player_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); MusicPlayerWorker* music_player_worker = music_player_worker_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); do { - if(storage_common_stat(storage, string_get_cstr(args), NULL) == FSE_OK) { - if(!music_player_worker_load(music_player_worker, string_get_cstr(args))) { - printf("Failed to open file %s\r\n", string_get_cstr(args)); + if(storage_common_stat(storage, furi_string_get_cstr(args), NULL) == FSE_OK) { + if(!music_player_worker_load(music_player_worker, furi_string_get_cstr(args))) { + printf("Failed to open file %s\r\n", furi_string_get_cstr(args)); break; } } else { if(!music_player_worker_load_rtttl_from_string( - music_player_worker, string_get_cstr(args))) { + music_player_worker, furi_string_get_cstr(args))) { printf("Argument is not a file or RTTTL\r\n"); break; } diff --git a/applications/plugins/music_player/music_player_worker.c b/applications/plugins/music_player/music_player_worker.c index ca4f1d8c..af09f053 100644 --- a/applications/plugins/music_player/music_player_worker.c +++ b/applications/plugins/music_player/music_player_worker.c @@ -326,8 +326,8 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c furi_assert(file_path); bool result = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); @@ -337,7 +337,8 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || (version != MUSIC_PLAYER_VERSION)) { + if(furi_string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || + (version != MUSIC_PLAYER_VERSION)) { FURI_LOG_E(TAG, "Incorrect file format or version"); break; } @@ -360,7 +361,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c break; } - if(!music_player_worker_parse_notes(instance, string_get_cstr(temp_str))) { + if(!music_player_worker_parse_notes(instance, furi_string_get_cstr(temp_str))) { break; } @@ -369,7 +370,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c furi_record_close(RECORD_STORAGE); flipper_format_free(file); - string_clear(temp_str); + furi_string_free(temp_str); return result; } @@ -379,8 +380,8 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const furi_assert(file_path); bool result = false; - string_t content; - string_init(content); + FuriString* content; + content = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); @@ -395,17 +396,17 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const uint8_t buffer[65] = {0}; ret = storage_file_read(file, buffer, sizeof(buffer) - 1); for(size_t i = 0; i < ret; i++) { - string_push_back(content, buffer[i]); + furi_string_push_back(content, buffer[i]); } } while(ret > 0); - string_strim(content); - if(!string_size(content)) { + furi_string_trim(content); + if(!furi_string_size(content)) { FURI_LOG_E(TAG, "Empty file"); break; } - if(!music_player_worker_load_rtttl_from_string(instance, string_get_cstr(content))) { + if(!music_player_worker_load_rtttl_from_string(instance, furi_string_get_cstr(content))) { FURI_LOG_E(TAG, "Invalid file content"); break; } @@ -415,7 +416,7 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const storage_file_free(file); furi_record_close(RECORD_STORAGE); - string_clear(content); + furi_string_free(content); return result; } diff --git a/applications/plugins/picopass/picopass_device.c b/applications/plugins/picopass/picopass_device.c index e7f3e0be..b6e69cc2 100644 --- a/applications/plugins/picopass/picopass_device.c +++ b/applications/plugins/picopass/picopass_device.c @@ -18,7 +18,7 @@ PicopassDevice* picopass_device_alloc() { picopass_dev->dev_data.pacs.pin_length = 0; picopass_dev->storage = furi_record_open(RECORD_STORAGE); picopass_dev->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(picopass_dev->load_path); + picopass_dev->load_path = furi_string_alloc(); return picopass_dev; } @@ -40,25 +40,25 @@ static bool picopass_device_save_file( FlipperFormat* file = flipper_format_file_alloc(dev->storage); PicopassPacs* pacs = &dev->dev_data.pacs; PicopassBlock* AA1 = dev->dev_data.AA1; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { // Get directory name - path_extract_dirname(string_get_cstr(dev->load_path), temp_str); + path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); // Create picopass directory if necessary - if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break; + if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(temp_str))) break; // Make path to file to save - string_cat_printf(temp_str, "/%s%s", dev_name, extension); + furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); } else { // Create picopass directory if necessary if(!storage_simply_mkdir(dev->storage, PICOPASS_APP_FOLDER)) break; // First remove picopass device file if it was saved - string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); + furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); } // Open file - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; if(dev->format == PicopassDeviceSaveFormatHF) { uint32_t fc = pacs->record.FacilityCode; @@ -87,9 +87,9 @@ static bool picopass_device_save_file( AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : PICOPASS_MAX_APP_LIMIT; for(size_t i = 0; i < app_limit; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_write_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_saved = false; break; } @@ -117,7 +117,7 @@ static bool picopass_device_save_file( if(!saved) { dialog_message_show_storage_error(dev->dialogs, "Can not save\nfile"); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return saved; } @@ -132,13 +132,13 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { return false; } -static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool show_dialog) { +static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, bool show_dialog) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); PicopassBlock* AA1 = dev->dev_data.AA1; PicopassPacs* pacs = &dev->dev_data.pacs; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool deprecated_version = false; if(dev->loading_cb) { @@ -146,12 +146,13 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s } do { - if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; // Read and verify file header uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, picopass_file_header) || (version != picopass_file_version)) { + if(furi_string_cmp_str(temp_str, picopass_file_header) || + (version != picopass_file_version)) { deprecated_version = true; break; } @@ -159,9 +160,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s // Parse header blocks bool block_read = true; for(size_t i = 0; i < 6; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_read_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_read = false; break; } @@ -169,9 +170,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0]; for(size_t i = 6; i < app_limit; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_read_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_read = false; break; } @@ -196,7 +197,7 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s } } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; @@ -208,7 +209,7 @@ void picopass_device_clear(PicopassDevice* dev) { picopass_device_data_clear(&dev->dev_data); memset(&dev->dev_data, 0, sizeof(dev->dev_data)); dev->format = PicopassDeviceSaveFormatHF; - string_reset(dev->load_path); + furi_string_reset(dev->load_path); } void picopass_device_free(PicopassDevice* picopass_dev) { @@ -216,7 +217,7 @@ void picopass_device_free(PicopassDevice* picopass_dev) { picopass_device_clear(picopass_dev); furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_DIALOGS); - string_clear(picopass_dev->load_path); + furi_string_free(picopass_dev->load_path); free(picopass_dev); } @@ -224,8 +225,8 @@ bool picopass_file_select(PicopassDevice* dev) { furi_assert(dev); // Input events and views are managed by file_browser - string_t picopass_app_folder; - string_init_set_str(picopass_app_folder, PICOPASS_APP_FOLDER); + FuriString* picopass_app_folder; + picopass_app_folder = furi_string_alloc_set(PICOPASS_APP_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); @@ -233,17 +234,17 @@ bool picopass_file_select(PicopassDevice* dev) { bool res = dialog_file_browser_show( dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); - string_clear(picopass_app_folder); + furi_string_free(picopass_app_folder); if(res) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN); + strncpy(dev->dev_name, furi_string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN); res = picopass_device_load_data(dev, dev->load_path, true); if(res) { picopass_device_set_name(dev, dev->dev_name); } - string_clear(filename); + furi_string_free(filename); } return res; @@ -262,18 +263,18 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { furi_assert(dev); bool deleted = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { // Delete original file - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(file_path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(file_path, dev->load_path); } else { - string_printf( + furi_string_printf( file_path, "%s/%s%s", PICOPASS_APP_FOLDER, dev->dev_name, PICOPASS_APP_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; deleted = true; } while(0); @@ -281,7 +282,7 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); } - string_clear(file_path); + furi_string_free(file_path); return deleted; } diff --git a/applications/plugins/picopass/picopass_device.h b/applications/plugins/picopass/picopass_device.h index 745b64bd..cbb43d6c 100644 --- a/applications/plugins/picopass/picopass_device.h +++ b/applications/plugins/picopass/picopass_device.h @@ -71,7 +71,7 @@ typedef struct { DialogsApp* dialogs; PicopassDeviceData dev_data; char dev_name[PICOPASS_DEV_NAME_MAX_LEN + 1]; - string_t load_path; + FuriString* load_path; PicopassDeviceSaveFormat format; PicopassLoadingCallback loading_cb; void* loading_cb_ctx; diff --git a/applications/plugins/picopass/picopass_i.h b/applications/plugins/picopass/picopass_i.h index dec5a865..8e011f22 100644 --- a/applications/plugins/picopass/picopass_i.h +++ b/applications/plugins/picopass/picopass_i.h @@ -51,7 +51,7 @@ struct Picopass { PicopassDevice* dev; char text_store[PICOPASS_TEXT_STORE_SIZE + 1]; - string_t text_box_store; + FuriString* text_box_store; // Common Views Submenu* submenu; diff --git a/applications/plugins/picopass/scenes/picopass_scene_device_info.c b/applications/plugins/picopass/scenes/picopass_scene_device_info.c index 38891b67..046e9c8e 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_device_info.c +++ b/applications/plugins/picopass/scenes/picopass_scene_device_info.c @@ -14,10 +14,10 @@ void picopass_scene_device_info_widget_callback( void picopass_scene_device_info_on_enter(void* context) { Picopass* picopass = context; - string_t credential_str; - string_t wiegand_str; - string_init(credential_str); - string_init(wiegand_str); + FuriString* credential_str; + FuriString* wiegand_str; + credential_str = furi_string_alloc(); + wiegand_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -26,25 +26,31 @@ void picopass_scene_device_info_on_enter(void* context) { Widget* widget = picopass->widget; size_t bytesLength = 1 + pacs->record.bitLength / 8; - string_set_str(credential_str, ""); + furi_string_set(credential_str, ""); for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - string_cat_printf(credential_str, " %02X", pacs->credential[i]); + furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); } if(pacs->record.valid) { - string_cat_printf( + furi_string_cat_printf( wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); } else { - string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); + furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); } widget_add_string_element( - widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); + widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(credential_str)); - string_clear(credential_str); - string_clear(wiegand_str); + furi_string_free(credential_str); + furi_string_free(wiegand_str); widget_add_button_element( picopass->widget, diff --git a/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c b/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c index 785f3a7d..37f1db4f 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c +++ b/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c @@ -15,12 +15,12 @@ void picopass_scene_read_card_success_widget_callback( void picopass_scene_read_card_success_on_enter(void* context) { Picopass* picopass = context; - string_t credential_str; - string_t wiegand_str; - string_t sio_str; - string_init(credential_str); - string_init(wiegand_str); - string_init(sio_str); + FuriString* credential_str; + FuriString* wiegand_str; + FuriString* sio_str; + credential_str = furi_string_alloc(); + wiegand_str = furi_string_alloc(); + sio_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -32,10 +32,10 @@ void picopass_scene_read_card_success_on_enter(void* context) { Widget* widget = picopass->widget; if(pacs->record.bitLength == 0) { - string_cat_printf(wiegand_str, "Read Failed"); + furi_string_cat_printf(wiegand_str, "Read Failed"); if(pacs->se_enabled) { - string_cat_printf(credential_str, "SE enabled"); + furi_string_cat_printf(credential_str, "SE enabled"); } widget_add_button_element( @@ -47,20 +47,20 @@ void picopass_scene_read_card_success_on_enter(void* context) { } else { size_t bytesLength = 1 + pacs->record.bitLength / 8; - string_set_str(credential_str, ""); + furi_string_set(credential_str, ""); for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - string_cat_printf(credential_str, " %02X", pacs->credential[i]); + furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); } if(pacs->record.valid) { - string_cat_printf( + furi_string_cat_printf( wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); } else { - string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); + furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); } if(pacs->sio) { - string_cat_printf(sio_str, "+SIO"); + furi_string_cat_printf(sio_str, "+SIO"); } widget_add_button_element( @@ -79,15 +79,21 @@ void picopass_scene_read_card_success_on_enter(void* context) { } widget_add_string_element( - widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); + widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(credential_str)); widget_add_string_element( - widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(sio_str)); + widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str)); - string_clear(credential_str); - string_clear(wiegand_str); - string_clear(sio_str); + furi_string_free(credential_str); + furi_string_free(wiegand_str); + furi_string_free(sio_str); view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); } diff --git a/applications/plugins/picopass/scenes/picopass_scene_save_name.c b/applications/plugins/picopass/scenes/picopass_scene_save_name.c index c5fa7dd1..17ad5927 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_save_name.c +++ b/applications/plugins/picopass/scenes/picopass_scene_save_name.c @@ -1,5 +1,4 @@ #include "../picopass_i.h" -#include "m-string.h" #include #include #include @@ -31,22 +30,22 @@ void picopass_scene_save_name_on_enter(void* context) { PICOPASS_DEV_NAME_MAX_LEN, dev_name_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(picopass->dev->load_path), folder_path); + if(furi_string_end_with(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(picopass->dev->load_path), folder_path); } else { - string_set_str(folder_path, PICOPASS_APP_FOLDER); + furi_string_set(folder_path, PICOPASS_APP_FOLDER); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name); + furi_string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextInput); - string_clear(folder_path); + furi_string_free(folder_path); } bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/services/bt/bt_cli.c b/applications/services/bt/bt_cli.c index ff5ebb44..02bf6cee 100644 --- a/applications/services/bt/bt_cli.c +++ b/applications/services/bt/bt_cli.c @@ -7,18 +7,18 @@ #include "bt_settings.h" #include "bt_service/bt.h" -static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) { +static void bt_cli_command_hci_info(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); furi_hal_bt_dump_state(buffer); - printf("%s", string_get_cstr(buffer)); - string_clear(buffer); + printf("%s", furi_string_get_cstr(buffer)); + furi_string_free(buffer); } -static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_carrier_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int power = 0; @@ -50,7 +50,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_carrier_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; @@ -81,7 +81,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_packet_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int pattern = 0; @@ -129,7 +129,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_packet_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int datarate = 1; @@ -178,12 +178,12 @@ static void bt_cli_print_usage() { } } -static void bt_cli(Cli* cli, string_t args, void* context) { +static void bt_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); furi_record_open(RECORD_BT); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); BtSettings bt_settings; bt_settings_load(&bt_settings); @@ -192,24 +192,24 @@ static void bt_cli(Cli* cli, string_t args, void* context) { bt_cli_print_usage(); break; } - if(string_cmp_str(cmd, "hci_info") == 0) { + if(furi_string_cmp_str(cmd, "hci_info") == 0) { bt_cli_command_hci_info(cli, args, NULL); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && furi_hal_bt_is_testing_supported()) { - if(string_cmp_str(cmd, "tx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "tx_carrier") == 0) { bt_cli_command_carrier_tx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "rx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "rx_carrier") == 0) { bt_cli_command_carrier_rx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "tx_packet") == 0) { + if(furi_string_cmp_str(cmd, "tx_packet") == 0) { bt_cli_command_packet_tx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "rx_packet") == 0) { + if(furi_string_cmp_str(cmd, "rx_packet") == 0) { bt_cli_command_packet_rx(cli, args, NULL); break; } @@ -222,7 +222,7 @@ static void bt_cli(Cli* cli, string_t args, void* context) { furi_hal_bt_start_advertising(); } - string_clear(cmd); + furi_string_free(cmd); furi_record_close(RECORD_BT); } diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index bc80acc1..2bb083f2 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -75,14 +75,14 @@ static void bt_pin_code_hide(Bt* bt) { static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { furi_assert(bt); notification_message(bt->notification, &sequence_display_backlight_on); - string_t pin_str; + FuriString* pin_str; dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); - string_init_printf(pin_str, "Verify code\n%06d", pin); + pin_str = furi_string_alloc_printf("Verify code\n%06d", pin); dialog_message_set_text( - bt->dialog_message, string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); + bt->dialog_message, furi_string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); dialog_message_set_buttons(bt->dialog_message, "Cancel", "OK", NULL); DialogMessageButton button = dialog_message_show(bt->dialogs, bt->dialog_message); - string_clear(pin_str); + furi_string_free(pin_str); return button == DialogMessageButtonCenter; } diff --git a/applications/services/cli/cli.c b/applications/services/cli/cli.c index e554ac89..f29dca9c 100644 --- a/applications/services/cli/cli.c +++ b/applications/services/cli/cli.c @@ -11,8 +11,8 @@ Cli* cli_alloc() { CliCommandTree_init(cli->commands); - string_init(cli->last_line); - string_init(cli->line); + cli->last_line = furi_string_alloc(); + cli->line = furi_string_alloc(); cli->session = NULL; @@ -138,34 +138,26 @@ void cli_nl(Cli* cli) { void cli_prompt(Cli* cli) { UNUSED(cli); - printf("\r\n>: %s", string_get_cstr(cli->line)); + printf("\r\n>: %s", furi_string_get_cstr(cli->line)); fflush(stdout); } void cli_reset(Cli* cli) { // cli->last_line is cleared and cli->line's buffer moved to cli->last_line - string_move(cli->last_line, cli->line); + furi_string_move(cli->last_line, cli->line); // Reiniting cli->line - string_init(cli->line); + cli->line = furi_string_alloc(); cli->cursor_position = 0; } static void cli_handle_backspace(Cli* cli) { if(cli->cursor_position > 0) { - furi_assert(string_size(cli->line) > 0); + furi_assert(furi_string_size(cli->line) > 0); // Other side printf("\e[D\e[1P"); fflush(stdout); // Our side - string_t temp; - string_init(temp); - string_reserve(temp, string_size(cli->line) - 1); - string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position - 1); - string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); - - // cli->line is cleared and temp's buffer moved to cli->line - string_move(cli->line, temp); - // NO MEMORY LEAK, STOP REPORTING IT + furi_string_replace_at(cli->line, cli->cursor_position - 1, 1, ""); cli->cursor_position--; } else { @@ -174,11 +166,11 @@ static void cli_handle_backspace(Cli* cli) { } static void cli_normalize_line(Cli* cli) { - string_strim(cli->line); - cli->cursor_position = string_size(cli->line); + furi_string_trim(cli->line); + cli->cursor_position = furi_string_size(cli->line); } -static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { +static void cli_execute_command(Cli* cli, CliCommand* command, FuriString* args) { if(!(command->flags & CliCommandFlagInsomniaSafe)) { furi_hal_power_insomnia_enter(); } @@ -208,25 +200,25 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { static void cli_handle_enter(Cli* cli) { cli_normalize_line(cli); - if(string_size(cli->line) == 0) { + if(furi_string_size(cli->line) == 0) { cli_prompt(cli); return; } // Command and args container - string_t command; - string_init(command); - string_t args; - string_init(args); + FuriString* command; + command = furi_string_alloc(); + FuriString* args; + args = furi_string_alloc(); // Split command and args - size_t ws = string_search_char(cli->line, ' '); - if(ws == STRING_FAILURE) { - string_set(command, cli->line); + size_t ws = furi_string_search_char(cli->line, ' '); + if(ws == FURI_STRING_FAILURE) { + furi_string_set(command, cli->line); } else { - string_set_n(command, cli->line, 0, ws); - string_set_n(args, cli->line, ws, string_size(cli->line)); - string_strim(args); + furi_string_set_n(command, cli->line, 0, ws); + furi_string_set_n(args, cli->line, ws, furi_string_size(cli->line)); + furi_string_trim(args); } // Search for command @@ -244,7 +236,7 @@ static void cli_handle_enter(Cli* cli) { cli_nl(cli); printf( "`%s` command not found, use `help` or `?` to list all available commands", - string_get_cstr(command)); + furi_string_get_cstr(command)); cli_putc(cli, CliSymbolAsciiBell); } @@ -252,59 +244,59 @@ static void cli_handle_enter(Cli* cli) { cli_prompt(cli); // Cleanup command and args - string_clear(command); - string_clear(args); + furi_string_free(command); + furi_string_free(args); } static void cli_handle_autocomplete(Cli* cli) { cli_normalize_line(cli); - if(string_size(cli->line) == 0) { + if(furi_string_size(cli->line) == 0) { return; } cli_nl(cli); // Prepare common base for autocomplete - string_t common; - string_init(common); + FuriString* common; + common = furi_string_alloc(); // Iterate throw commands for M_EACH(cli_command, cli->commands, CliCommandTree_t) { // Process only if starts with line buffer - if(string_start_with_string_p(*cli_command->key_ptr, cli->line)) { + if(furi_string_start_with(*cli_command->key_ptr, cli->line)) { // Show autocomplete option - printf("%s\r\n", string_get_cstr(*cli_command->key_ptr)); + printf("%s\r\n", furi_string_get_cstr(*cli_command->key_ptr)); // Process common base for autocomplete - if(string_size(common) > 0) { + if(furi_string_size(common) > 0) { // Choose shortest string - const size_t key_size = string_size(*cli_command->key_ptr); - const size_t common_size = string_size(common); + const size_t key_size = furi_string_size(*cli_command->key_ptr); + const size_t common_size = furi_string_size(common); const size_t min_size = key_size > common_size ? common_size : key_size; size_t i = 0; while(i < min_size) { // Stop when do not match - if(string_get_char(*cli_command->key_ptr, i) != - string_get_char(common, i)) { + if(furi_string_get_char(*cli_command->key_ptr, i) != + furi_string_get_char(common, i)) { break; } i++; } // Cut right part if any - string_left(common, i); + furi_string_left(common, i); } else { // Start with something - string_set(common, *cli_command->key_ptr); + furi_string_set(common, *cli_command->key_ptr); } } } // Replace line buffer if autocomplete better - if(string_size(common) > string_size(cli->line)) { - string_set(cli->line, common); - cli->cursor_position = string_size(cli->line); + if(furi_string_size(common) > furi_string_size(cli->line)) { + furi_string_set(cli->line, common); + cli->cursor_position = furi_string_size(cli->line); } // Cleanup - string_clear(common); + furi_string_free(common); // Show prompt cli_prompt(cli); } @@ -312,16 +304,16 @@ static void cli_handle_autocomplete(Cli* cli) { static void cli_handle_escape(Cli* cli, char c) { if(c == 'A') { // Use previous command if line buffer is empty - if(string_size(cli->line) == 0 && string_cmp(cli->line, cli->last_line) != 0) { + if(furi_string_size(cli->line) == 0 && furi_string_cmp(cli->line, cli->last_line) != 0) { // Set line buffer and cursor position - string_set(cli->line, cli->last_line); - cli->cursor_position = string_size(cli->line); + furi_string_set(cli->line, cli->last_line); + cli->cursor_position = furi_string_size(cli->line); // Show new line to user - printf("%s", string_get_cstr(cli->line)); + printf("%s", furi_string_get_cstr(cli->line)); } } else if(c == 'B') { } else if(c == 'C') { - if(cli->cursor_position < string_size(cli->line)) { + if(cli->cursor_position < furi_string_size(cli->line)) { cli->cursor_position++; printf("\e[C"); } @@ -362,21 +354,13 @@ void cli_process_input(Cli* cli) { } else if(in_chr == CliSymbolAsciiCR) { cli_handle_enter(cli); } else if(in_chr >= 0x20 && in_chr < 0x7F) { - if(cli->cursor_position == string_size(cli->line)) { - string_push_back(cli->line, in_chr); + if(cli->cursor_position == furi_string_size(cli->line)) { + furi_string_push_back(cli->line, in_chr); cli_putc(cli, in_chr); } else { - // ToDo: better way? - string_t temp; - string_init(temp); - string_reserve(temp, string_size(cli->line) + 1); - string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position); - string_push_back(temp, in_chr); - string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); - - // cli->line is cleared and temp's buffer moved to cli->line - string_move(cli->line, temp); - // NO MEMORY LEAK, STOP REPORTING IT + // Insert character to line buffer + const char in_str[2] = {in_chr, 0}; + furi_string_replace_at(cli->line, cli->cursor_position, 0, in_str); // Print character in replace mode printf("\e[4h%c\e[4l", in_chr); @@ -394,14 +378,14 @@ void cli_add_command( CliCommandFlag flags, CliCallback callback, void* context) { - string_t name_str; - string_init_set_str(name_str, name); - string_strim(name_str); + FuriString* name_str; + name_str = furi_string_alloc_set(name); + furi_string_trim(name_str); size_t name_replace; do { - name_replace = string_replace_str(name_str, " ", "_"); - } while(name_replace != STRING_FAILURE); + name_replace = furi_string_replace(name_str, " ", "_"); + } while(name_replace != FURI_STRING_FAILURE); CliCommand c; c.callback = callback; @@ -412,24 +396,24 @@ void cli_add_command( CliCommandTree_set_at(cli->commands, name_str, c); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); - string_clear(name_str); + furi_string_free(name_str); } void cli_delete_command(Cli* cli, const char* name) { - string_t name_str; - string_init_set_str(name_str, name); - string_strim(name_str); + FuriString* name_str; + name_str = furi_string_alloc_set(name); + furi_string_trim(name_str); size_t name_replace; do { - name_replace = string_replace_str(name_str, " ", "_"); - } while(name_replace != STRING_FAILURE); + name_replace = furi_string_replace(name_str, " ", "_"); + } while(name_replace != FURI_STRING_FAILURE); furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); CliCommandTree_erase(cli->commands, name_str); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); - string_clear(name_str); + furi_string_free(name_str); } void cli_session_open(Cli* cli, void* session) { diff --git a/applications/services/cli/cli.h b/applications/services/cli/cli.h index 549e72cc..09f54f05 100644 --- a/applications/services/cli/cli.h +++ b/applications/services/cli/cli.h @@ -4,8 +4,7 @@ */ #pragma once - -#include +#include #ifdef __cplusplus extern "C" { @@ -43,7 +42,7 @@ typedef struct Cli Cli; * @param args string with what was passed after command * @param context pointer to whatever you gave us on cli_add_command */ -typedef void (*CliCallback)(Cli* cli, string_t args, void* context); +typedef void (*CliCallback)(Cli* cli, FuriString* args, void* context); /** Add cli command Registers you command callback * diff --git a/applications/services/cli/cli_command_gpio.c b/applications/services/cli/cli_command_gpio.c index d5ec8d65..54671eda 100644 --- a/applications/services/cli/cli_command_gpio.c +++ b/applications/services/cli/cli_command_gpio.c @@ -35,11 +35,11 @@ void cli_command_gpio_print_usage() { printf("\tread \t - Read gpio value\r\n"); } -static bool pin_name_to_int(string_t pin_name, size_t* result) { +static bool pin_name_to_int(FuriString* pin_name, size_t* result) { bool found = false; bool debug = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug); for(size_t i = 0; i < COUNT_OF(cli_command_gpio_pins); i++) { - if(!string_cmp(pin_name, cli_command_gpio_pins[i].name)) { + if(!furi_string_cmp(pin_name, cli_command_gpio_pins[i].name)) { if(!cli_command_gpio_pins[i].debug || (cli_command_gpio_pins[i].debug && debug)) { *result = i; found = true; @@ -63,29 +63,29 @@ static void gpio_print_pins(void) { typedef enum { OK, ERR_CMD_SYNTAX, ERR_PIN, ERR_VALUE } GpioParseError; -static GpioParseError gpio_command_parse(string_t args, size_t* pin_num, uint8_t* value) { - string_t pin_name; - string_init(pin_name); +static GpioParseError gpio_command_parse(FuriString* args, size_t* pin_num, uint8_t* value) { + FuriString* pin_name; + pin_name = furi_string_alloc(); - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { return ERR_CMD_SYNTAX; } - string_set_n(pin_name, args, 0, ws); - string_right(args, ws); - string_strim(args); + furi_string_set_n(pin_name, args, 0, ws); + furi_string_right(args, ws); + furi_string_trim(args); if(!pin_name_to_int(pin_name, pin_num)) { - string_clear(pin_name); + furi_string_free(pin_name); return ERR_PIN; } - string_clear(pin_name); + furi_string_free(pin_name); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { *value = 0; - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { *value = 1; } else { return ERR_VALUE; @@ -94,7 +94,7 @@ static GpioParseError gpio_command_parse(string_t args, size_t* pin_num, uint8_t return OK; } -void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { +void cli_command_gpio_mode(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); @@ -104,7 +104,7 @@ void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { GpioParseError err = gpio_command_parse(args, &num, &value); if(ERR_CMD_SYNTAX == err) { - cli_print_usage("gpio mode", " <0|1>", string_get_cstr(args)); + cli_print_usage("gpio mode", " <0|1>", furi_string_get_cstr(args)); return; } else if(ERR_PIN == err) { gpio_print_pins(); @@ -134,7 +134,7 @@ void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { } } -void cli_command_gpio_read(Cli* cli, string_t args, void* context) { +void cli_command_gpio_read(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); @@ -156,7 +156,7 @@ void cli_command_gpio_read(Cli* cli, string_t args, void* context) { printf("Pin %s <= %u", cli_command_gpio_pins[num].name, val); } -void cli_command_gpio_set(Cli* cli, string_t args, void* context) { +void cli_command_gpio_set(Cli* cli, FuriString* args, void* context) { UNUSED(context); size_t num = 0; @@ -164,7 +164,7 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { GpioParseError err = gpio_command_parse(args, &num, &value); if(ERR_CMD_SYNTAX == err) { - cli_print_usage("gpio set", " <0|1>", string_get_cstr(args)); + cli_print_usage("gpio set", " <0|1>", furi_string_get_cstr(args)); return; } else if(ERR_PIN == err) { gpio_print_pins(); @@ -196,9 +196,9 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { printf("Pin %s => %u", cli_command_gpio_pins[num].name, !!value); } -void cli_command_gpio(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); +void cli_command_gpio(Cli* cli, FuriString* args, void* context) { + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -206,17 +206,17 @@ void cli_command_gpio(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "mode") == 0) { + if(furi_string_cmp_str(cmd, "mode") == 0) { cli_command_gpio_mode(cli, args, context); break; } - if(string_cmp_str(cmd, "set") == 0) { + if(furi_string_cmp_str(cmd, "set") == 0) { cli_command_gpio_set(cli, args, context); break; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { cli_command_gpio_read(cli, args, context); break; } @@ -224,5 +224,5 @@ void cli_command_gpio(Cli* cli, string_t args, void* context) { cli_command_gpio_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/services/cli/cli_command_gpio.h b/applications/services/cli/cli_command_gpio.h index c9b908a0..7ae5aa62 100644 --- a/applications/services/cli/cli_command_gpio.h +++ b/applications/services/cli/cli_command_gpio.h @@ -2,4 +2,4 @@ #include "cli_i.h" -void cli_command_gpio(Cli* cli, string_t args, void* context); +void cli_command_gpio(Cli* cli, FuriString* args, void* context); diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index a6dd672f..21927f81 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -22,13 +22,13 @@ void cli_command_device_info_callback(const char* key, const char* value, bool l * Device Info Command * This command is intended to be used by humans */ -void cli_command_device_info(Cli* cli, string_t args, void* context) { +void cli_command_device_info(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); furi_hal_info_get(cli_command_device_info_callback, context); } -void cli_command_help(Cli* cli, string_t args, void* context) { +void cli_command_help(Cli* cli, FuriString* args, void* context) { UNUSED(args); UNUSED(context); printf("Commands we have:"); @@ -49,34 +49,34 @@ void cli_command_help(Cli* cli, string_t args, void* context) { printf("\r\n"); // Left Column if(!CliCommandTree_end_p(it_left)) { - printf("%-30s", string_get_cstr(*CliCommandTree_ref(it_left)->key_ptr)); + printf("%-30s", furi_string_get_cstr(*CliCommandTree_ref(it_left)->key_ptr)); CliCommandTree_next(it_left); } // Right Column if(!CliCommandTree_end_p(it_right)) { - printf("%s", string_get_cstr(*CliCommandTree_ref(it_right)->key_ptr)); + printf("%s", furi_string_get_cstr(*CliCommandTree_ref(it_right)->key_ptr)); CliCommandTree_next(it_right); } }; - if(string_size(args) > 0) { + if(furi_string_size(args) > 0) { cli_nl(); printf("Also I have no clue what '"); - printf("%s", string_get_cstr(args)); + printf("%s", furi_string_get_cstr(args)); printf("' is."); } } -void cli_command_date(Cli* cli, string_t args, void* context) { +void cli_command_date(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); FuriHalRtcDateTime datetime = {0}; - if(string_size(args) > 0) { + if(furi_string_size(args) > 0) { uint16_t hours, minutes, seconds, month, day, year, weekday; int ret = sscanf( - string_get_cstr(args), + furi_string_get_cstr(args), "%hu-%hu-%hu %hu:%hu:%hu %hu", &year, &month, @@ -101,7 +101,7 @@ void cli_command_date(Cli* cli, string_t args, void* context) { "Invalid datetime format, use `%s`. sscanf %d %s", "%Y-%m-%d %H:%M:%S %u", ret, - string_get_cstr(args)); + furi_string_get_cstr(args)); return; } @@ -143,7 +143,7 @@ void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* conte xStreamBufferSend(context, buffer, size, 0); } -void cli_command_log(Cli* cli, string_t args, void* context) { +void cli_command_log(Cli* cli, FuriString* args, void* context) { UNUSED(args); UNUSED(context); StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); @@ -162,75 +162,75 @@ void cli_command_log(Cli* cli, string_t args, void* context) { vStreamBufferDelete(ring); } -void cli_command_vibro(Cli* cli, string_t args, void* context) { +void cli_command_vibro(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_reset_vibro); furi_record_close(RECORD_NOTIFICATION); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_set_vibro_on); furi_record_close(RECORD_NOTIFICATION); } else { - cli_print_usage("vibro", "<1|0>", string_get_cstr(args)); + cli_print_usage("vibro", "<1|0>", furi_string_get_cstr(args)); } } -void cli_command_debug(Cli* cli, string_t args, void* context) { +void cli_command_debug(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); loader_update_menu(); printf("Debug disabled."); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_rtc_set_flag(FuriHalRtcFlagDebug); loader_update_menu(); printf("Debug enabled."); } else { - cli_print_usage("debug", "<1|0>", string_get_cstr(args)); + cli_print_usage("debug", "<1|0>", furi_string_get_cstr(args)); } } -void cli_command_led(Cli* cli, string_t args, void* context) { +void cli_command_led(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); // Get first word as light name NotificationMessage notification_led_message; - string_t light_name; - string_init(light_name); - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); - string_clear(light_name); + FuriString* light_name; + light_name = furi_string_alloc(); + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); + furi_string_free(light_name); return; } else { - string_set_n(light_name, args, 0, ws); - string_right(args, ws); - string_strim(args); + furi_string_set_n(light_name, args, 0, ws); + furi_string_right(args, ws); + furi_string_trim(args); } // Check light name - if(!string_cmp(light_name, "r")) { + if(!furi_string_cmp(light_name, "r")) { notification_led_message.type = NotificationMessageTypeLedRed; - } else if(!string_cmp(light_name, "g")) { + } else if(!furi_string_cmp(light_name, "g")) { notification_led_message.type = NotificationMessageTypeLedGreen; - } else if(!string_cmp(light_name, "b")) { + } else if(!furi_string_cmp(light_name, "b")) { notification_led_message.type = NotificationMessageTypeLedBlue; - } else if(!string_cmp(light_name, "bl")) { + } else if(!furi_string_cmp(light_name, "bl")) { notification_led_message.type = NotificationMessageTypeLedDisplayBacklight; } else { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); - string_clear(light_name); + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); + furi_string_free(light_name); return; } - string_clear(light_name); + furi_string_free(light_name); // Read light value from the rest of the string char* end_ptr; - uint32_t value = strtoul(string_get_cstr(args), &end_ptr, 0); + uint32_t value = strtoul(furi_string_get_cstr(args), &end_ptr, 0); if(!(value < 256 && *end_ptr == '\0')) { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); return; } @@ -249,7 +249,7 @@ void cli_command_led(Cli* cli, string_t args, void* context) { furi_record_close(RECORD_NOTIFICATION); } -void cli_command_ps(Cli* cli, string_t args, void* context) { +void cli_command_ps(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -272,7 +272,7 @@ void cli_command_ps(Cli* cli, string_t args, void* context) { printf("\r\nTotal: %d", thread_num); } -void cli_command_free(Cli* cli, string_t args, void* context) { +void cli_command_free(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -286,7 +286,7 @@ void cli_command_free(Cli* cli, string_t args, void* context) { printf("Maximum pool block: %d\r\n", memmgr_pool_get_max_block()); } -void cli_command_free_blocks(Cli* cli, string_t args, void* context) { +void cli_command_free_blocks(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -294,7 +294,7 @@ void cli_command_free_blocks(Cli* cli, string_t args, void* context) { memmgr_heap_printf_free_blocks(); } -void cli_command_i2c(Cli* cli, string_t args, void* context) { +void cli_command_i2c(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); diff --git a/applications/services/cli/cli_i.h b/applications/services/cli/cli_i.h index ba4582d0..858cd0c8 100644 --- a/applications/services/cli/cli_i.h +++ b/applications/services/cli/cli_i.h @@ -36,8 +36,8 @@ struct CliSession { BPTREE_DEF2( CliCommandTree, CLI_COMMANDS_TREE_RANK, - string_t, - STRING_OPLIST, + FuriString*, + FURI_STRING_OPLIST, CliCommand, M_POD_OPLIST) @@ -47,8 +47,8 @@ struct Cli { CliCommandTree_t commands; FuriMutex* mutex; FuriSemaphore* idle_sem; - string_t last_line; - string_t line; + FuriString* last_line; + FuriString* line; CliSession* session; size_t cursor_position; diff --git a/applications/services/crypto/crypto_cli.c b/applications/services/crypto/crypto_cli.c index 26e1fb9c..a64a3ad0 100644 --- a/applications/services/crypto/crypto_cli.c +++ b/applications/services/crypto/crypto_cli.c @@ -17,7 +17,7 @@ void crypto_cli_print_usage() { "\tstore_key \t - Store key in secure enclave. !!! NON-REVERSABLE OPERATION - READ MANUAL FIRST !!!\r\n"); }; -void crypto_cli_encrypt(Cli* cli, string_t args) { +void crypto_cli_encrypt(Cli* cli, FuriString* args) { int key_slot = 0; bool key_loaded = false; uint8_t iv[16]; @@ -41,8 +41,8 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { printf("Enter plain text and press Ctrl+C to complete encryption:\r\n"); - string_t input; - string_init(input); + FuriString* input; + input = furi_string_alloc(); char c; while(cli_read(cli, (uint8_t*)&c, 1) == 1) { if(c == CliSymbolAsciiETX) { @@ -51,14 +51,14 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { } else if(c >= 0x20 && c < 0x7F) { putc(c, stdout); fflush(stdout); - string_push_back(input, c); + furi_string_push_back(input, c); } else if(c == CliSymbolAsciiCR) { printf("\r\n"); - string_cat_str(input, "\r\n"); + furi_string_cat(input, "\r\n"); } } - size_t size = string_size(input); + size_t size = furi_string_size(input); if(size > 0) { // C-string null termination and block alignments size++; @@ -66,9 +66,10 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { if(remain) { size = size - remain + 16; } - string_reserve(input, size); + furi_string_reserve(input, size); uint8_t* output = malloc(size); - if(!furi_hal_crypto_encrypt((const uint8_t*)string_get_cstr(input), output, size)) { + if(!furi_hal_crypto_encrypt( + (const uint8_t*)furi_string_get_cstr(input), output, size)) { printf("Failed to encrypt input"); } else { printf("Hex-encoded encrypted data:\r\n"); @@ -83,7 +84,7 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { printf("No input"); } - string_clear(input); + furi_string_free(input); } while(0); if(key_loaded) { @@ -91,7 +92,7 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { } } -void crypto_cli_decrypt(Cli* cli, string_t args) { +void crypto_cli_decrypt(Cli* cli, FuriString* args) { int key_slot = 0; bool key_loaded = false; uint8_t iv[16]; @@ -115,8 +116,8 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { printf("Enter Hex-encoded data and press Ctrl+C to complete decryption:\r\n"); - string_t hex_input; - string_init(hex_input); + FuriString* hex_input; + hex_input = furi_string_alloc(); char c; while(cli_read(cli, (uint8_t*)&c, 1) == 1) { if(c == CliSymbolAsciiETX) { @@ -125,14 +126,14 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { } else if(c >= 0x20 && c < 0x7F) { putc(c, stdout); fflush(stdout); - string_push_back(hex_input, c); + furi_string_push_back(hex_input, c); } else if(c == CliSymbolAsciiCR) { printf("\r\n"); } } - string_strim(hex_input); - size_t hex_size = string_size(hex_input); + furi_string_trim(hex_input); + size_t hex_size = furi_string_size(hex_input); if(hex_size > 0 && hex_size % 2 == 0) { size_t size = hex_size / 2; uint8_t* input = malloc(size); @@ -155,7 +156,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { printf("Invalid or empty input"); } - string_clear(hex_input); + furi_string_free(hex_input); } while(0); if(key_loaded) { @@ -163,7 +164,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { } } -void crypto_cli_has_key(Cli* cli, string_t args) { +void crypto_cli_has_key(Cli* cli, FuriString* args) { UNUSED(cli); int key_slot = 0; uint8_t iv[16]; @@ -185,12 +186,12 @@ void crypto_cli_has_key(Cli* cli, string_t args) { } while(0); } -void crypto_cli_store_key(Cli* cli, string_t args) { +void crypto_cli_store_key(Cli* cli, FuriString* args) { UNUSED(cli); int key_slot = 0; int key_size = 0; - string_t key_type; - string_init(key_type); + FuriString* key_type; + key_type = furi_string_alloc(); uint8_t data[32 + 12] = {}; FuriHalCryptoKey key; @@ -207,19 +208,19 @@ void crypto_cli_store_key(Cli* cli, string_t args) { break; } - if(string_cmp_str(key_type, "master") == 0) { + if(furi_string_cmp_str(key_type, "master") == 0) { if(key_slot != 0) { printf("Master keyslot must be is 0"); break; } key.type = FuriHalCryptoKeyTypeMaster; - } else if(string_cmp_str(key_type, "simple") == 0) { + } else if(furi_string_cmp_str(key_type, "simple") == 0) { if(key_slot < 1 || key_slot > 99) { printf("Simple keyslot must be in range"); break; } key.type = FuriHalCryptoKeyTypeSimple; - } else if(string_cmp_str(key_type, "encrypted") == 0) { + } else if(furi_string_cmp_str(key_type, "encrypted") == 0) { key.type = FuriHalCryptoKeyTypeEncrypted; data_size += 12; } else { @@ -275,13 +276,13 @@ void crypto_cli_store_key(Cli* cli, string_t args) { } } while(0); - string_clear(key_type); + furi_string_free(key_type); } -static void crypto_cli(Cli* cli, string_t args, void* context) { +static void crypto_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -289,22 +290,22 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "encrypt") == 0) { + if(furi_string_cmp_str(cmd, "encrypt") == 0) { crypto_cli_encrypt(cli, args); break; } - if(string_cmp_str(cmd, "decrypt") == 0) { + if(furi_string_cmp_str(cmd, "decrypt") == 0) { crypto_cli_decrypt(cli, args); break; } - if(string_cmp_str(cmd, "has_key") == 0) { + if(furi_string_cmp_str(cmd, "has_key") == 0) { crypto_cli_has_key(cli, args); break; } - if(string_cmp_str(cmd, "store_key") == 0) { + if(furi_string_cmp_str(cmd, "store_key") == 0) { crypto_cli_store_key(cli, args); break; } @@ -312,7 +313,7 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { crypto_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void crypto_on_system_start() { diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index 1e2a521e..36c5b397 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,7 @@ struct AnimationManager { AnimationManagerSetNewIdleAnimationCallback new_idle_callback; AnimationManagerSetNewIdleAnimationCallback check_blocking_callback; void* context; - string_t freezed_animation_name; + FuriString* freezed_animation_name; int32_t freezed_animation_time_left; ViewStack* view_stack; }; @@ -279,7 +278,7 @@ AnimationManager* animation_manager_alloc(void) { animation_manager->view_stack = view_stack_alloc(); View* animation_view = bubble_animation_get_view(animation_manager->animation_view); view_stack_add_view(animation_manager->view_stack, animation_view); - string_init(animation_manager->freezed_animation_name); + animation_manager->freezed_animation_name = furi_string_alloc(); animation_manager->idle_animation_timer = furi_timer_alloc(animation_manager_timer_callback, FuriTimerTypeOnce, animation_manager); @@ -317,7 +316,7 @@ void animation_manager_free(AnimationManager* animation_manager) { storage_get_pubsub(storage), animation_manager->pubsub_subscription_storage); furi_record_close(RECORD_STORAGE); - string_clear(animation_manager->freezed_animation_name); + furi_string_free(animation_manager->freezed_animation_name); View* animation_view = bubble_animation_get_view(animation_manager->animation_view); view_stack_remove_view(animation_manager->view_stack, animation_view); bubble_animation_view_free(animation_manager->animation_view); @@ -433,7 +432,7 @@ bool animation_manager_is_animation_loaded(AnimationManager* animation_manager) void animation_manager_unload_and_stall_animation(AnimationManager* animation_manager) { furi_assert(animation_manager); furi_assert(animation_manager->current_animation); - furi_assert(!string_size(animation_manager->freezed_animation_name)); + furi_assert(!furi_string_size(animation_manager->freezed_animation_name)); furi_assert( (animation_manager->state == AnimationManagerStateIdle) || (animation_manager->state == AnimationManagerStateBlocked)); @@ -461,7 +460,7 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma StorageAnimationManifestInfo* meta = animation_storage_get_meta(animation_manager->current_animation); /* copy str, not move, because it can be internal animation */ - string_set_str(animation_manager->freezed_animation_name, meta->name); + furi_string_set(animation_manager->freezed_animation_name, meta->name); bubble_animation_freeze(animation_manager->animation_view); animation_storage_free_storage_animation(&animation_manager->current_animation); @@ -470,14 +469,14 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma void animation_manager_load_and_continue_animation(AnimationManager* animation_manager) { furi_assert(animation_manager); furi_assert(!animation_manager->current_animation); - furi_assert(string_size(animation_manager->freezed_animation_name)); + furi_assert(furi_string_size(animation_manager->freezed_animation_name)); furi_assert( (animation_manager->state == AnimationManagerStateFreezedIdle) || (animation_manager->state == AnimationManagerStateFreezedBlocked)); if(animation_manager->state == AnimationManagerStateFreezedBlocked) { StorageAnimation* restore_animation = animation_storage_find_animation( - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); /* all blocked animations must be in flipper -> we can * always find blocking animation */ furi_assert(restore_animation); @@ -489,7 +488,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m if(!blocked) { /* if no blocking - try restore last one idle */ StorageAnimation* restore_animation = animation_storage_find_animation( - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); if(restore_animation) { Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); @@ -517,7 +516,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m FURI_LOG_E( TAG, "Failed to restore \'%s\'", - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); } } } else { @@ -535,7 +534,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m animation_storage_get_meta(animation_manager->current_animation)->name); bubble_animation_unfreeze(animation_manager->animation_view); - string_reset(animation_manager->freezed_animation_name); + furi_string_reset(animation_manager->freezed_animation_name); furi_assert(animation_manager->current_animation); } diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index e0c6bf41..922d7dc8 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "animation_manager.h" #include "animation_storage.h" @@ -32,8 +31,8 @@ static bool animation_storage_load_single_manifest_info( Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); flipper_format_set_strict_mode(file, true); - string_t read_string; - string_init(read_string); + FuriString* read_string; + read_string = furi_string_alloc(); do { uint32_t u32value; @@ -41,20 +40,20 @@ static bool animation_storage_load_single_manifest_info( if(!flipper_format_file_open_existing(file, ANIMATION_MANIFEST_FILE)) break; if(!flipper_format_read_header(file, read_string, &u32value)) break; - if(string_cmp_str(read_string, "Flipper Animation Manifest")) break; + if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; manifest_info->name = NULL; /* skip other animation names */ flipper_format_set_strict_mode(file, false); while(flipper_format_read_string(file, "Name", read_string) && - string_cmp_str(read_string, name)) + furi_string_cmp_str(read_string, name)) ; - if(string_cmp_str(read_string, name)) break; + if(furi_string_cmp_str(read_string, name)) break; flipper_format_set_strict_mode(file, true); - manifest_info->name = malloc(string_size(read_string) + 1); - strcpy((char*)manifest_info->name, string_get_cstr(read_string)); + manifest_info->name = malloc(furi_string_size(read_string) + 1); + strcpy((char*)manifest_info->name, furi_string_get_cstr(read_string)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; manifest_info->min_butthurt = u32value; @@ -72,7 +71,7 @@ static bool animation_storage_load_single_manifest_info( if(!result && manifest_info->name) { free((void*)manifest_info->name); } - string_clear(read_string); + furi_string_free(read_string); flipper_format_free(file); furi_record_close(RECORD_STORAGE); @@ -88,8 +87,8 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis FlipperFormat* file = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(file, true); - string_t read_string; - string_init(read_string); + FuriString* read_string; + read_string = furi_string_alloc(); do { uint32_t u32value; @@ -98,7 +97,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis if(FSE_OK != storage_sd_status(storage)) break; if(!flipper_format_file_open_existing(file, ANIMATION_MANIFEST_FILE)) break; if(!flipper_format_read_header(file, read_string, &u32value)) break; - if(string_cmp_str(read_string, "Flipper Animation Manifest")) break; + if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; do { storage_animation = malloc(sizeof(StorageAnimation)); storage_animation->external = true; @@ -106,8 +105,9 @@ 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(string_size(read_string) + 1); - strcpy((char*)storage_animation->manifest_info.name, string_get_cstr(read_string)); + 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)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; storage_animation->manifest_info.min_butthurt = u32value; @@ -126,7 +126,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis animation_storage_free_storage_animation(&storage_animation); } while(0); - string_clear(read_string); + furi_string_free(read_string); flipper_format_free(file); // add hard-coded animations @@ -231,16 +231,16 @@ void animation_storage_free_storage_animation(StorageAnimation** storage_animati *storage_animation = NULL; } -static bool animation_storage_cast_align(string_t align_str, Align* align) { - if(!string_cmp_str(align_str, "Bottom")) { +static bool animation_storage_cast_align(FuriString* align_str, Align* align) { + if(!furi_string_cmp(align_str, "Bottom")) { *align = AlignBottom; - } else if(!string_cmp_str(align_str, "Top")) { + } else if(!furi_string_cmp(align_str, "Top")) { *align = AlignTop; - } else if(!string_cmp_str(align_str, "Left")) { + } else if(!furi_string_cmp(align_str, "Left")) { *align = AlignLeft; - } else if(!string_cmp_str(align_str, "Right")) { + } else if(!furi_string_cmp(align_str, "Right")) { *align = AlignRight; - } else if(!string_cmp_str(align_str, "Center")) { + } else if(!furi_string_cmp(align_str, "Center")) { *align = AlignCenter; } else { return false; @@ -291,15 +291,16 @@ static bool animation_storage_load_frames( bool frames_ok = false; File* file = storage_file_alloc(storage); FileInfo file_info; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); size_t max_filesize = ROUND_UP_TO(width, 8) * height + 1; for(int i = 0; i < icon->frame_count; ++i) { frames_ok = false; - string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); + furi_string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); - if(storage_common_stat(storage, string_get_cstr(filename), &file_info) != FSE_OK) break; + if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) != FSE_OK) + break; if(file_info.size > max_filesize) { FURI_LOG_E( TAG, @@ -310,14 +311,15 @@ static bool animation_storage_load_frames( height); break; } - if(!storage_file_open(file, string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_E(TAG, "Can't open file \'%s\'", string_get_cstr(filename)); + if(!storage_file_open( + file, furi_string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Can't open file \'%s\'", furi_string_get_cstr(filename)); break; } FURI_CONST_ASSIGN_PTR(icon->frames[i], malloc(file_info.size)); if(storage_file_read(file, (void*)icon->frames[i], file_info.size) != file_info.size) { - FURI_LOG_E(TAG, "Read failed: \'%s\'", string_get_cstr(filename)); + FURI_LOG_E(TAG, "Read failed: \'%s\'", furi_string_get_cstr(filename)); break; } storage_file_close(file); @@ -328,7 +330,7 @@ static bool animation_storage_load_frames( FURI_LOG_E( TAG, "Load \'%s\' failed, %dx%d, size: %d", - string_get_cstr(filename), + furi_string_get_cstr(filename), width, height, file_info.size); @@ -341,15 +343,15 @@ static bool animation_storage_load_frames( } storage_file_free(file); - string_clear(filename); + furi_string_free(filename); return frames_ok; } static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFormat* ff) { uint32_t u32value; - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); bool success = false; furi_assert(!animation->frame_bubble_sequences); @@ -396,12 +398,12 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo FURI_CONST_ASSIGN(bubble->bubble.y, u32value); if(!flipper_format_read_string(ff, "Text", str)) break; - if(string_size(str) > 100) break; + if(furi_string_size(str) > 100) break; - string_replace_all_str(str, "\\n", "\n"); + furi_string_replace_all(str, "\\n", "\n"); - FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(string_size(str) + 1)); - strcpy((char*)bubble->bubble.text, string_get_cstr(str)); + FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(furi_string_size(str) + 1)); + strcpy((char*)bubble->bubble.text, 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; @@ -423,7 +425,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo } } - string_clear(str); + furi_string_free(str); return success; } @@ -438,8 +440,8 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { FlipperFormat* ff = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(ff, true); - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); animation->frame_bubble_sequences = NULL; bool success = false; @@ -448,10 +450,10 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(FSE_OK != storage_sd_status(storage)) break; - string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); - if(!flipper_format_file_open_existing(ff, string_get_cstr(str))) break; + furi_string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); + if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(str))) break; if(!flipper_format_read_header(ff, str, &u32value)) break; - if(string_cmp_str(str, "Flipper Animation")) break; + if(furi_string_cmp_str(str, "Flipper Animation")) break; if(!flipper_format_read_uint32(ff, "Width", &width, 1)) break; if(!flipper_format_read_uint32(ff, "Height", &height, 1)) break; @@ -492,7 +494,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { success = true; } while(0); - string_clear(str); + furi_string_free(str); flipper_format_free(ff); if(u32array) { free(u32array); diff --git a/applications/services/desktop/animations/animation_storage.h b/applications/services/desktop/animations/animation_storage.h index e53c1133..16c0feab 100644 --- a/applications/services/desktop/animations/animation_storage.h +++ b/applications/services/desktop/animations/animation_storage.h @@ -2,7 +2,6 @@ #include #include #include "views/bubble_animation_view.h" -#include /** Main structure to handle animation data. * Contains all, including animation playing data (BubbleAnimation), diff --git a/applications/services/dialogs/dialogs.h b/applications/services/dialogs/dialogs.h index 2522c8b5..4e836e36 100644 --- a/applications/services/dialogs/dialogs.h +++ b/applications/services/dialogs/dialogs.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include "m-string.h" #include #ifdef __cplusplus @@ -56,8 +55,8 @@ void dialog_file_browser_set_basic_options( */ bool dialog_file_browser_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + FuriString* result_path, + FuriString* path, const DialogsFileBrowserOptions* options); /****************** MESSAGE ******************/ diff --git a/applications/services/dialogs/dialogs_api.c b/applications/services/dialogs/dialogs_api.c index fd3b2e96..6fd51782 100644 --- a/applications/services/dialogs/dialogs_api.c +++ b/applications/services/dialogs/dialogs_api.c @@ -1,14 +1,13 @@ #include "dialogs/dialogs_message.h" #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" /****************** File browser ******************/ bool dialog_file_browser_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + FuriString* result_path, + FuriString* path, const DialogsFileBrowserOptions* options) { FuriApiLock lock = API_LOCK_INIT_LOCKED(); furi_check(lock != NULL); diff --git a/applications/services/dialogs/dialogs_message.h b/applications/services/dialogs/dialogs_message.h index 2dc66f13..91e040ce 100644 --- a/applications/services/dialogs/dialogs_message.h +++ b/applications/services/dialogs/dialogs_message.h @@ -2,7 +2,6 @@ #include #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" #ifdef __cplusplus extern "C" { @@ -13,8 +12,8 @@ typedef struct { bool skip_assets; bool hide_ext; const Icon* file_icon; - string_ptr result_path; - string_ptr preselected_filename; + FuriString* result_path; + FuriString* preselected_filename; FileBrowserLoadItemCallback item_callback; void* item_callback_context; } DialogsAppMessageDataFileBrowser; diff --git a/applications/services/gui/elements.c b/applications/services/gui/elements.c index 58b44603..0f7cf73f 100644 --- a/applications/services/gui/elements.c +++ b/applications/services/gui/elements.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "canvas_i.h" @@ -189,12 +188,12 @@ static size_t end = text + strlen(text); } size_t text_size = end - text; - string_t str; - string_init_set_str(str, text); - string_left(str, text_size); + FuriString* str; + str = furi_string_alloc_set(text); + furi_string_left(str, text_size); size_t result = 0; - uint16_t len_px = canvas_string_width(canvas, string_get_cstr(str)); + uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(str)); uint8_t px_left = 0; if(horizontal == AlignCenter) { if(x > (canvas_width(canvas) / 2)) { @@ -224,7 +223,7 @@ static size_t result = text_size; } - string_clear(str); + furi_string_free(str); return result; } @@ -240,7 +239,7 @@ void elements_multiline_text_aligned( uint8_t lines_count = 0; uint8_t font_height = canvas_current_font_height(canvas); - string_t line; + FuriString* line; /* go through text line by line and count lines */ for(const char* start = text; start[0];) { @@ -261,14 +260,14 @@ void elements_multiline_text_aligned( size_t chars_fit = elements_get_max_chars_to_fit(canvas, horizontal, start, x); if((start[chars_fit] == '\n') || (start[chars_fit] == 0)) { - string_init_printf(line, "%.*s", chars_fit, start); + line = furi_string_alloc_printf("%.*s", chars_fit, start); } else if((y + font_height) > canvas_height(canvas)) { - string_init_printf(line, "%.*s...\n", chars_fit, start); + line = furi_string_alloc_printf("%.*s...\n", chars_fit, start); } else { - string_init_printf(line, "%.*s-\n", chars_fit, start); + line = furi_string_alloc_printf("%.*s-\n", chars_fit, start); } - canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, string_get_cstr(line)); - string_clear(line); + canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, furi_string_get_cstr(line)); + furi_string_free(line); y += font_height; if(y > canvas_height(canvas)) { break; @@ -284,22 +283,22 @@ void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, const char* t furi_assert(text); uint8_t font_height = canvas_current_font_height(canvas); - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); const char* start = text; char* end; do { end = strchr(start, '\n'); if(end) { - string_set_strn(str, start, end - start); + furi_string_set_strn(str, start, end - start); } else { - string_set_str(str, start); + furi_string_set(str, start); } - canvas_draw_str(canvas, x, y, string_get_cstr(str)); + canvas_draw_str(canvas, x, y, furi_string_get_cstr(str)); start = end + 1; y += font_height; } while(end && y < 64); - string_clear(str); + furi_string_free(str); } void elements_multiline_text_framed(Canvas* canvas, uint8_t x, uint8_t y, const char* text) { @@ -533,18 +532,18 @@ void elements_bubble_str( canvas_draw_line(canvas, x2, y2, x3, y3); } -void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width) { +void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width) { furi_assert(canvas); furi_assert(string); - uint16_t len_px = canvas_string_width(canvas, string_get_cstr(string)); + uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(string)); if(len_px > width) { width -= canvas_string_width(canvas, "..."); do { - string_left(string, string_size(string) - 1); - len_px = canvas_string_width(canvas, string_get_cstr(string)); + furi_string_left(string, furi_string_size(string) - 1); + len_px = canvas_string_width(canvas, furi_string_get_cstr(string)); } while(len_px > width); - string_cat(string, "..."); + furi_string_cat(string, "..."); } } diff --git a/applications/services/gui/elements.h b/applications/services/gui/elements.h index 2329ca27..b2d204de 100644 --- a/applications/services/gui/elements.h +++ b/applications/services/gui/elements.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include "canvas.h" #ifdef __cplusplus @@ -190,7 +190,7 @@ void elements_bubble_str( * @param string string to trim * @param width max width */ -void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width); +void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width); /** Draw text box element * diff --git a/applications/services/gui/modules/button_menu.c b/applications/services/gui/modules/button_menu.c index 84fea788..1dce014d 100644 --- a/applications/services/gui/modules/button_menu.c +++ b/applications/services/gui/modules/button_menu.c @@ -79,8 +79,8 @@ static void button_menu_draw_common_button( canvas_draw_rframe(canvas, item_x, item_y, ITEM_WIDTH, ITEM_HEIGHT, 5); } - string_t disp_str; - string_init_set_str(disp_str, text); + FuriString* disp_str; + disp_str = furi_string_alloc_set(text); elements_string_fit_width(canvas, disp_str, ITEM_WIDTH - 6); canvas_draw_str_aligned( @@ -89,9 +89,9 @@ static void button_menu_draw_common_button( item_y + (ITEM_HEIGHT / 2), AlignCenter, AlignCenter, - string_get_cstr(disp_str)); + furi_string_get_cstr(disp_str)); - string_clear(disp_str); + furi_string_free(disp_str); } static void button_menu_view_draw_callback(Canvas* canvas, void* _model) { @@ -116,12 +116,12 @@ static void button_menu_view_draw_callback(Canvas* canvas, void* _model) { } if(model->header) { - string_t disp_str; - string_init_set_str(disp_str, model->header); + FuriString* disp_str; + disp_str = furi_string_alloc_set(model->header); elements_string_fit_width(canvas, disp_str, ITEM_WIDTH - 6); canvas_draw_str_aligned( - canvas, 32, 10, AlignCenter, AlignCenter, string_get_cstr(disp_str)); - string_clear(disp_str); + canvas, 32, 10, AlignCenter, AlignCenter, furi_string_get_cstr(disp_str)); + furi_string_free(disp_str); } for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it); diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index 1c0c8c74..f15b09f6 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -5,7 +5,6 @@ #include #include #include "furi_hal_resources.h" -#include "m-string.h" #include #include #include @@ -28,23 +27,23 @@ typedef enum { } BrowserItemType; typedef struct { - string_t path; + FuriString* path; BrowserItemType type; uint8_t* custom_icon_data; - string_t display_name; + FuriString* display_name; } BrowserItem_t; static void BrowserItem_t_init(BrowserItem_t* obj) { obj->type = BrowserItemTypeLoading; - string_init(obj->path); - string_init(obj->display_name); + obj->path = furi_string_alloc(); + obj->display_name = furi_string_alloc(); obj->custom_icon_data = NULL; } static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src) { obj->type = src->type; - string_init_set(obj->path, src->path); - string_init_set(obj->display_name, src->display_name); + obj->path = furi_string_alloc_set(src->path); + obj->display_name = furi_string_alloc_set(src->display_name); if(src->custom_icon_data) { obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE); memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE); @@ -55,8 +54,8 @@ static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src) static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) { obj->type = src->type; - string_set(obj->path, src->path); - string_set(obj->display_name, src->display_name); + furi_string_set(obj->path, src->path); + furi_string_set(obj->display_name, src->display_name); if(src->custom_icon_data) { obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE); memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE); @@ -66,8 +65,8 @@ static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) { } static void BrowserItem_t_clear(BrowserItem_t* obj) { - string_clear(obj->path); - string_clear(obj->display_name); + furi_string_free(obj->path); + furi_string_free(obj->display_name); if(obj->custom_icon_data) { free(obj->custom_icon_data); } @@ -94,7 +93,7 @@ struct FileBrowser { FileBrowserLoadItemCallback item_callback; void* item_context; - string_ptr result_path; + FuriString* result_path; }; typedef struct { @@ -125,10 +124,11 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context); static void browser_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root); static void browser_list_load_cb(void* context, uint32_t list_load_offset); -static void browser_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last); +static void + browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last); static void browser_long_load_cb(void* context); -FileBrowser* file_browser_alloc(string_ptr result_path) { +FileBrowser* file_browser_alloc(FuriString* result_path) { furi_assert(result_path); FileBrowser* browser = malloc(sizeof(FileBrowser)); browser->view = view_alloc(); @@ -186,7 +186,7 @@ void file_browser_configure( }); } -void file_browser_start(FileBrowser* browser, string_t path) { +void file_browser_start(FileBrowser* browser, FuriString* path) { furi_assert(browser); browser->worker = file_browser_worker_alloc(path, browser->ext_filter, browser->skip_assets); file_browser_worker_set_callback_context(browser->worker, browser); @@ -336,7 +336,8 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { BrowserItem_t_clear(&back_item); } -static void browser_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last) { +static void + browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) { furi_assert(context); FileBrowser* browser = (FileBrowser*)context; @@ -344,8 +345,8 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold item.custom_icon_data = NULL; if(!is_last) { - string_init_set(item.path, item_path); - string_init(item.display_name); + item.path = furi_string_alloc_set(item_path); + item.display_name = furi_string_alloc(); if(is_folder) { item.type = BrowserItemTypeFolder; } else { @@ -363,7 +364,7 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold } } - if(string_empty_p(item.display_name)) { + if(furi_string_empty(item.display_name)) { path_extract_filename( item_path, item.display_name, @@ -376,8 +377,8 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold // TODO: calculate if element is visible return true; }); - string_clear(item.display_name); - string_clear(item.path); + furi_string_free(item.display_name); + furi_string_free(item.path); } else { with_view_model( browser->view, (FileBrowserModel * model) { @@ -427,8 +428,8 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { uint32_t array_size = items_array_size(model->items); bool show_scrollbar = model->item_cnt > LIST_ITEMS; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); for(uint32_t i = 0; i < MIN(model->item_cnt, LIST_ITEMS); i++) { int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); @@ -440,16 +441,16 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { BrowserItem_t* item = items_array_get( model->items, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); item_type = item->type; - string_set(filename, item->display_name); + furi_string_set(filename, item->display_name); if(item_type == BrowserItemTypeFile) { custom_icon_data = item->custom_icon_data; } } else { - string_set_str(filename, "---"); + furi_string_set(filename, "---"); } if(item_type == BrowserItemTypeBack) { - string_set_str(filename, ". ."); + furi_string_set(filename, ". ."); } elements_string_fit_width( @@ -471,7 +472,8 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { canvas_draw_icon( canvas, 2, Y_OFFSET + 1 + i * FRAME_HEIGHT, BrowserItemIcons[item_type]); } - canvas_draw_str(canvas, 15, Y_OFFSET + 9 + i * FRAME_HEIGHT, string_get_cstr(filename)); + canvas_draw_str( + canvas, 15, Y_OFFSET + 9 + i * FRAME_HEIGHT, furi_string_get_cstr(filename)); } if(show_scrollbar) { @@ -484,7 +486,7 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { model->item_cnt); } - string_clear(filename); + furi_string_free(filename); } static void file_browser_view_draw_callback(Canvas* canvas, void* _model) { @@ -568,7 +570,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { file_browser_worker_folder_enter( browser->worker, selected_item->path, select_index); } else if(selected_item->type == BrowserItemTypeFile) { - string_set(browser->result_path, selected_item->path); + furi_string_set(browser->result_path, selected_item->path); if(browser->callback) { browser->callback(browser->context); } diff --git a/applications/services/gui/modules/file_browser.h b/applications/services/gui/modules/file_browser.h index 57a9f096..c9fdddb5 100644 --- a/applications/services/gui/modules/file_browser.h +++ b/applications/services/gui/modules/file_browser.h @@ -5,7 +5,6 @@ #pragma once -#include "m-string.h" #include #ifdef __cplusplus @@ -15,10 +14,13 @@ extern "C" { typedef struct FileBrowser FileBrowser; typedef void (*FileBrowserCallback)(void* context); -typedef bool ( - *FileBrowserLoadItemCallback)(string_t path, void* context, uint8_t** icon, string_t item_name); +typedef bool (*FileBrowserLoadItemCallback)( + FuriString* path, + void* context, + uint8_t** icon, + FuriString* item_name); -FileBrowser* file_browser_alloc(string_ptr result_path); +FileBrowser* file_browser_alloc(FuriString* result_path); void file_browser_free(FileBrowser* browser); @@ -31,7 +33,7 @@ void file_browser_configure( const Icon* file_icon, bool hide_ext); -void file_browser_start(FileBrowser* browser, string_t path); +void file_browser_start(FileBrowser* browser, FuriString* path); void file_browser_stop(FileBrowser* browser); diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 36df6cc8..319304f9 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -1,7 +1,6 @@ #include "file_browser_worker.h" #include #include -#include "m-string.h" #include "storage/filesystem_api_defines.h" #include #include @@ -35,8 +34,8 @@ ARRAY_DEF(idx_last_array, int32_t) struct BrowserWorker { FuriThread* thread; - string_t filter_extension; - string_t path_next; + FuriString* filter_extension; + FuriString* path_next; int32_t item_sel_idx; uint32_t load_offset; uint32_t load_count; @@ -50,11 +49,11 @@ struct BrowserWorker { BrowserWorkerLongLoadCallback long_load_cb; }; -static bool browser_path_is_file(string_t path) { +static bool browser_path_is_file(FuriString* path) { bool state = false; FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if((file_info.flags & FSF_DIRECTORY) == 0) { state = true; } @@ -63,50 +62,50 @@ static bool browser_path_is_file(string_t path) { return state; } -static bool browser_path_trim(string_t path) { +static bool browser_path_trim(FuriString* path) { bool is_root = false; - size_t filename_start = string_search_rchar(path, '/'); - string_left(path, filename_start); - if((string_empty_p(path)) || (filename_start == STRING_FAILURE)) { - string_set_str(path, BROWSER_ROOT); + size_t filename_start = furi_string_search_rchar(path, '/'); + furi_string_left(path, filename_start); + if((furi_string_empty(path)) || (filename_start == FURI_STRING_FAILURE)) { + furi_string_set(path, BROWSER_ROOT); is_root = true; } return is_root; } -static bool browser_filter_by_name(BrowserWorker* browser, string_t name, bool is_folder) { +static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, bool is_folder) { if(is_folder) { // Skip assets folders (if enabled) if(browser->skip_assets) { - return ((string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)); + return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)); } else { return true; } } else { // Filter files by extension - if((string_empty_p(browser->filter_extension)) || - (string_cmp_str(browser->filter_extension, "*") == 0)) { + if((furi_string_empty(browser->filter_extension)) || + (furi_string_cmp_str(browser->filter_extension, "*") == 0)) { return true; } - if(string_end_with_string_p(name, browser->filter_extension)) { + if(furi_string_end_with(name, browser->filter_extension)) { return true; } } return false; } -static bool browser_folder_check_and_switch(string_t path) { +static bool browser_folder_check_and_switch(FuriString* path) { FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); bool is_root = false; - if(string_search_rchar(path, '/') == 0) { + if(furi_string_search_rchar(path, '/') == 0) { is_root = true; } while(1) { // Check if folder is existing and navigate back if not - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { break; } @@ -122,8 +121,8 @@ static bool browser_folder_check_and_switch(string_t path) { static bool browser_folder_init( BrowserWorker* browser, - string_t path, - string_t filename, + FuriString* path, + FuriString* filename, uint32_t* item_cnt, int32_t* file_idx) { bool state = false; @@ -134,13 +133,13 @@ static bool browser_folder_init( File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; - string_t name_str; - string_init(name_str); + FuriString* name_str; + name_str = furi_string_alloc(); *item_cnt = 0; *file_idx = -1; - if(storage_dir_open(directory, string_get_cstr(path))) { + if(storage_dir_open(directory, furi_string_get_cstr(path))) { state = true; while(1) { if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) { @@ -148,10 +147,10 @@ static bool browser_folder_init( } if((storage_file_get_error(directory) == FSE_OK) && (name_temp[0] != '\0')) { total_files_cnt++; - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - if(!string_empty_p(filename)) { - if(string_cmp(name_str, filename) == 0) { + if(!furi_string_empty(filename)) { + if(furi_string_cmp(name_str, filename) == 0) { *file_idx = *item_cnt; } } @@ -167,7 +166,7 @@ static bool browser_folder_init( } } - string_clear(name_str); + furi_string_free(name_str); storage_dir_close(directory); storage_file_free(directory); @@ -178,20 +177,20 @@ static bool browser_folder_init( } static bool - browser_folder_load(BrowserWorker* browser, string_t path, uint32_t offset, uint32_t count) { + browser_folder_load(BrowserWorker* browser, FuriString* path, uint32_t offset, uint32_t count) { FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; - string_t name_str; - string_init(name_str); + FuriString* name_str; + name_str = furi_string_alloc(); uint32_t items_cnt = 0; do { - if(!storage_dir_open(directory, string_get_cstr(path))) { + if(!storage_dir_open(directory, furi_string_get_cstr(path))) { break; } @@ -201,7 +200,7 @@ static bool break; } if(storage_file_get_error(directory) == FSE_OK) { - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { items_cnt++; } @@ -223,9 +222,9 @@ static bool break; } if(storage_file_get_error(directory) == FSE_OK) { - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - string_printf(name_str, "%s/%s", string_get_cstr(path), name_temp); + furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp); if(browser->list_item_cb) { browser->list_item_cb( browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false); @@ -241,7 +240,7 @@ static bool } } while(0); - string_clear(name_str); + furi_string_free(name_str); storage_dir_close(directory); storage_file_free(directory); @@ -257,12 +256,12 @@ static int32_t browser_worker(void* context) { FURI_LOG_D(TAG, "Start"); uint32_t items_cnt = 0; - string_t path; - string_init_set_str(path, BROWSER_ROOT); + FuriString* path; + path = furi_string_alloc_set(BROWSER_ROOT); browser->item_sel_idx = -1; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange); @@ -282,7 +281,7 @@ static int32_t browser_worker(void* context) { } if(flags & WorkerEvtFolderEnter) { - string_set(path, browser->path_next); + furi_string_set(path, browser->path_next); bool is_root = browser_folder_check_and_switch(path); // Push previous selected item index to history array @@ -293,13 +292,13 @@ static int32_t browser_worker(void* context) { FURI_LOG_D( TAG, "Enter folder: %s items: %u idx: %d", - string_get_cstr(path), + furi_string_get_cstr(path), items_cnt, file_idx); if(browser->folder_cb) { browser->folder_cb(browser->cb_ctx, items_cnt, file_idx, is_root); } - string_reset(filename); + furi_string_reset(filename); } if(flags & WorkerEvtFolderExit) { @@ -313,7 +312,11 @@ static int32_t browser_worker(void* context) { idx_last_array_pop_back(&file_idx, browser->idx_last); } FURI_LOG_D( - TAG, "Exit to: %s items: %u idx: %d", string_get_cstr(path), items_cnt, file_idx); + TAG, + "Exit to: %s items: %u idx: %d", + furi_string_get_cstr(path), + items_cnt, + file_idx); if(browser->folder_cb) { browser->folder_cb(browser->cb_ctx, items_cnt, file_idx, is_root); } @@ -323,12 +326,12 @@ static int32_t browser_worker(void* context) { bool is_root = browser_folder_check_and_switch(path); int32_t file_idx = 0; - string_reset(filename); + furi_string_reset(filename); browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, "Refresh folder: %s items: %u idx: %d", - string_get_cstr(path), + furi_string_get_cstr(path), items_cnt, browser->item_sel_idx); if(browser->folder_cb) { @@ -346,21 +349,22 @@ static int32_t browser_worker(void* context) { } } - string_clear(filename); - string_clear(path); + furi_string_free(filename); + furi_string_free(path); FURI_LOG_D(TAG, "End"); return 0; } -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets) { +BrowserWorker* + file_browser_worker_alloc(FuriString* path, const char* filter_ext, bool skip_assets) { BrowserWorker* browser = malloc(sizeof(BrowserWorker)); idx_last_array_init(browser->idx_last); - string_init_set_str(browser->filter_extension, filter_ext); + browser->filter_extension = furi_string_alloc_set(filter_ext); browser->skip_assets = skip_assets; - string_init_set(browser->path_next, path); + browser->path_next = furi_string_alloc_set(path); browser->thread = furi_thread_alloc(); furi_thread_set_name(browser->thread, "BrowserWorker"); @@ -379,8 +383,8 @@ void file_browser_worker_free(BrowserWorker* browser) { furi_thread_join(browser->thread); furi_thread_free(browser->thread); - string_clear(browser->filter_extension); - string_clear(browser->path_next); + furi_string_free(browser->filter_extension); + furi_string_free(browser->path_next); idx_last_array_clear(browser->idx_last); @@ -422,19 +426,19 @@ void file_browser_worker_set_long_load_callback( void file_browser_worker_set_config( BrowserWorker* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets) { furi_assert(browser); - string_set(browser->path_next, path); - string_set_str(browser->filter_extension, filter_ext); + furi_string_set(browser->path_next, path); + furi_string_set(browser->filter_extension, filter_ext); browser->skip_assets = skip_assets; furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange); } -void file_browser_worker_folder_enter(BrowserWorker* browser, string_t path, int32_t item_idx) { +void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx) { furi_assert(browser); - string_set(browser->path_next, path); + furi_string_set(browser->path_next, path); browser->item_sel_idx = item_idx; furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter); } diff --git a/applications/services/gui/modules/file_browser_worker.h b/applications/services/gui/modules/file_browser_worker.h index 18c0b481..230bb5b4 100644 --- a/applications/services/gui/modules/file_browser_worker.h +++ b/applications/services/gui/modules/file_browser_worker.h @@ -1,6 +1,5 @@ #pragma once -#include "m-string.h" #include #include @@ -17,12 +16,13 @@ typedef void (*BrowserWorkerFolderOpenCallback)( typedef void (*BrowserWorkerListLoadCallback)(void* context, uint32_t list_load_offset); typedef void (*BrowserWorkerListItemCallback)( void* context, - string_t item_path, + FuriString* item_path, bool is_folder, bool is_last); typedef void (*BrowserWorkerLongLoadCallback)(void* context); -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets); +BrowserWorker* + file_browser_worker_alloc(FuriString* path, const char* filter_ext, bool skip_assets); void file_browser_worker_free(BrowserWorker* browser); @@ -46,11 +46,11 @@ void file_browser_worker_set_long_load_callback( void file_browser_worker_set_config( BrowserWorker* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets); -void file_browser_worker_folder_enter(BrowserWorker* browser, string_t path, int32_t item_idx); +void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx); void file_browser_worker_folder_exit(BrowserWorker* browser); diff --git a/applications/services/gui/modules/submenu.c b/applications/services/gui/modules/submenu.c index 9fefeca0..8d40d97b 100644 --- a/applications/services/gui/modules/submenu.c +++ b/applications/services/gui/modules/submenu.c @@ -65,17 +65,17 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); } - string_t disp_str; - string_init_set_str(disp_str, SubmenuItemArray_cref(it)->label); + FuriString* disp_str; + disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label); elements_string_fit_width(canvas, disp_str, item_width - 20); canvas_draw_str( canvas, 6, y_offset + (item_position * item_height) + item_height - 4, - string_get_cstr(disp_str)); + furi_string_get_cstr(disp_str)); - string_clear(disp_str); + furi_string_free(disp_str); } position++; diff --git a/applications/services/gui/modules/text_box.c b/applications/services/gui/modules/text_box.c index 52307ec2..65ee2830 100644 --- a/applications/services/gui/modules/text_box.c +++ b/applications/services/gui/modules/text_box.c @@ -1,6 +1,5 @@ #include "text_box.h" #include "gui/canvas.h" -#include #include #include #include @@ -12,7 +11,7 @@ struct TextBox { typedef struct { const char* text; char* text_pos; - string_t text_formatted; + FuriString* text_formatted; int32_t scroll_pos; int32_t scroll_num; TextBoxFont font; @@ -66,17 +65,17 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { if(line_width + glyph_width > text_width) { line_num++; line_width = 0; - string_push_back(model->text_formatted, '\n'); + furi_string_push_back(model->text_formatted, '\n'); } line_width += glyph_width; } else { line_num++; line_width = 0; } - string_push_back(model->text_formatted, symb); + furi_string_push_back(model->text_formatted, symb); } line_num++; - model->text = string_get_cstr(model->text_formatted); + model->text = furi_string_get_cstr(model->text_formatted); model->text_pos = (char*)model->text; if(model->focus == TextBoxFocusEnd && line_num > 5) { // Set text position to 5th line from the end @@ -140,7 +139,7 @@ TextBox* text_box_alloc() { with_view_model( text_box->view, (TextBoxModel * model) { model->text = NULL; - string_init_set_str(model->text_formatted, ""); + model->text_formatted = furi_string_alloc_set(""); model->formatted = false; model->font = TextBoxFontText; return true; @@ -154,7 +153,7 @@ void text_box_free(TextBox* text_box) { with_view_model( text_box->view, (TextBoxModel * model) { - string_clear(model->text_formatted); + furi_string_free(model->text_formatted); return true; }); view_free(text_box->view); @@ -172,7 +171,7 @@ void text_box_reset(TextBox* text_box) { with_view_model( text_box->view, (TextBoxModel * model) { model->text = NULL; - string_set_str(model->text_formatted, ""); + furi_string_set(model->text_formatted, ""); model->font = TextBoxFontText; model->focus = TextBoxFocusStart; return true; @@ -186,8 +185,8 @@ void text_box_set_text(TextBox* text_box, const char* text) { with_view_model( text_box->view, (TextBoxModel * model) { model->text = text; - string_reset(model->text_formatted); - string_reserve(model->text_formatted, strlen(text)); + furi_string_reset(model->text_formatted); + furi_string_reserve(model->text_formatted, strlen(text)); model->formatted = false; return true; }); diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index b2aba03f..d7e00940 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -27,7 +27,7 @@ typedef struct { TextInputValidatorCallback validator_callback; void* validator_callback_context; - string_t validator_text; + FuriString* validator_text; bool valadator_message_visible; } TextInputModel; @@ -257,7 +257,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42); canvas_draw_rframe(canvas, 8, 8, 112, 50, 3); canvas_draw_rframe(canvas, 9, 9, 110, 48, 2); - elements_multiline_text(canvas, 62, 20, string_get_cstr(model->validator_text)); + elements_multiline_text(canvas, 62, 20, furi_string_get_cstr(model->validator_text)); canvas_set_font(canvas, FontKeyboard); } } @@ -447,7 +447,7 @@ TextInput* text_input_alloc() { with_view_model( text_input->view, (TextInputModel * model) { - string_init(model->validator_text); + model->validator_text = furi_string_alloc(); return false; }); @@ -460,7 +460,7 @@ void text_input_free(TextInput* text_input) { furi_assert(text_input); with_view_model( text_input->view, (TextInputModel * model) { - string_clear(model->validator_text); + furi_string_free(model->validator_text); return false; }); @@ -489,7 +489,7 @@ void text_input_reset(TextInput* text_input) { model->callback_context = NULL; model->validator_callback = NULL; model->validator_callback_context = NULL; - string_reset(model->validator_text); + furi_string_reset(model->validator_text); model->valadator_message_visible = false; return true; }); diff --git a/applications/services/gui/modules/text_input.h b/applications/services/gui/modules/text_input.h index d30fcd4c..893fbd53 100644 --- a/applications/services/gui/modules/text_input.h +++ b/applications/services/gui/modules/text_input.h @@ -7,7 +7,6 @@ #include #include "validators.h" -#include #ifdef __cplusplus extern "C" { @@ -16,7 +15,7 @@ extern "C" { /** Text input anonymous structure */ typedef struct TextInput TextInput; typedef void (*TextInputCallback)(void* context); -typedef bool (*TextInputValidatorCallback)(const char* text, string_t error, void* context); +typedef bool (*TextInputValidatorCallback)(const char* text, FuriString* error, void* context); /** Allocate and initialize text input * diff --git a/applications/services/gui/modules/validators.c b/applications/services/gui/modules/validators.c index d5fb0fa2..0463b1c2 100644 --- a/applications/services/gui/modules/validators.c +++ b/applications/services/gui/modules/validators.c @@ -8,7 +8,7 @@ struct ValidatorIsFile { char* current_name; }; -bool validator_is_file_callback(const char* text, string_t error, void* context) { +bool validator_is_file_callback(const char* text, FuriString* error, void* context) { furi_assert(context); ValidatorIsFile* instance = context; @@ -19,16 +19,16 @@ bool validator_is_file_callback(const char* text, string_t error, void* context) } bool ret = true; - string_t path; - string_init_printf(path, "%s/%s%s", instance->app_path_folder, text, instance->app_extension); + FuriString* path = furi_string_alloc_printf( + "%s/%s%s", instance->app_path_folder, text, instance->app_extension); Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK) { ret = false; - string_printf(error, "This name\nexists!\nChoose\nanother one."); + furi_string_printf(error, "This name\nexists!\nChoose\nanother one."); } else { ret = true; } - string_clear(path); + furi_string_free(path); furi_record_close(RECORD_STORAGE); return ret; diff --git a/applications/services/gui/modules/validators.h b/applications/services/gui/modules/validators.h index c4c4ef54..d9200b6d 100644 --- a/applications/services/gui/modules/validators.h +++ b/applications/services/gui/modules/validators.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus @@ -15,7 +14,7 @@ ValidatorIsFile* validator_is_file_alloc_init( void validator_is_file_free(ValidatorIsFile* instance); -bool validator_is_file_callback(const char* text, string_t error, void* context); +bool validator_is_file_callback(const char* text, FuriString* error, void* context); #ifdef __cplusplus } diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 4e5e4664..ec8fd3d2 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -8,7 +8,7 @@ struct VariableItem { const char* label; uint8_t current_value_index; - string_t current_value_text; + FuriString* current_value_text; uint8_t values_count; VariableItemChangeCallback change_callback; void* context; @@ -77,7 +77,7 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { item_text_y, AlignCenter, AlignBottom, - string_get_cstr(item->current_value_text)); + furi_string_get_cstr(item->current_value_text)); if(item->current_value_index < (item->values_count - 1)) { canvas_draw_str(canvas, 115, item_text_y, ">"); @@ -303,7 +303,7 @@ void variable_item_list_free(VariableItemList* variable_item_list) { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { - string_clear(VariableItemArray_ref(it)->current_value_text); + furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_clear(model->items); return false; @@ -320,7 +320,7 @@ void variable_item_list_reset(VariableItemList* variable_item_list) { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { - string_clear(VariableItemArray_ref(it)->current_value_text); + furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_reset(model->items); return false; @@ -350,7 +350,7 @@ VariableItem* variable_item_list_add( item->change_callback = change_callback; item->context = context; item->current_value_index = 0; - string_init(item->current_value_text); + item->current_value_text = furi_string_alloc(); return true; }); @@ -376,7 +376,7 @@ void variable_item_set_current_value_index(VariableItem* item, uint8_t current_v } void variable_item_set_current_value_text(VariableItem* item, const char* current_value_text) { - string_set_str(item->current_value_text, current_value_text); + furi_string_set(item->current_value_text, current_value_text); } uint8_t variable_item_get_current_value_index(VariableItem* item) { diff --git a/applications/services/gui/modules/widget_elements/widget_element_button.c b/applications/services/gui/modules/widget_elements/widget_element_button.c index 92be2590..be33b189 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_button.c +++ b/applications/services/gui/modules/widget_elements/widget_element_button.c @@ -1,10 +1,9 @@ #include "widget_element_i.h" #include -#include typedef struct { GuiButtonType button_type; - string_t text; + FuriString* text; ButtonCallback callback; void* context; } GuiButtonModel; @@ -18,11 +17,11 @@ static void gui_button_draw(Canvas* canvas, WidgetElement* element) { canvas_set_font(canvas, FontSecondary); if(model->button_type == GuiButtonTypeLeft) { - elements_button_left(canvas, string_get_cstr(model->text)); + elements_button_left(canvas, furi_string_get_cstr(model->text)); } else if(model->button_type == GuiButtonTypeRight) { - elements_button_right(canvas, string_get_cstr(model->text)); + elements_button_right(canvas, furi_string_get_cstr(model->text)); } else if(model->button_type == GuiButtonTypeCenter) { - elements_button_center(canvas, string_get_cstr(model->text)); + elements_button_center(canvas, furi_string_get_cstr(model->text)); } } @@ -50,7 +49,7 @@ static void gui_button_free(WidgetElement* gui_button) { furi_assert(gui_button); GuiButtonModel* model = gui_button->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_button->model); free(gui_button); } @@ -65,7 +64,7 @@ WidgetElement* widget_element_button_create( model->button_type = button_type; model->callback = callback; model->context = context; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_button = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_string.c b/applications/services/gui/modules/widget_elements/widget_element_string.c index a03c2b6d..feb22ad1 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_string.c +++ b/applications/services/gui/modules/widget_elements/widget_element_string.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include typedef struct { uint8_t x; @@ -7,7 +6,7 @@ typedef struct { Align horizontal; Align vertical; Font font; - string_t text; + FuriString* text; } GuiStringModel; static void gui_string_draw(Canvas* canvas, WidgetElement* element) { @@ -15,7 +14,7 @@ static void gui_string_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiStringModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { canvas_set_font(canvas, model->font); canvas_draw_str_aligned( canvas, @@ -23,7 +22,7 @@ static void gui_string_draw(Canvas* canvas, WidgetElement* element) { model->y, model->horizontal, model->vertical, - string_get_cstr(model->text)); + furi_string_get_cstr(model->text)); } } @@ -31,7 +30,7 @@ static void gui_string_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiStringModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -52,7 +51,7 @@ WidgetElement* widget_element_string_create( model->horizontal = horizontal; model->vertical = vertical; model->font = font; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_string = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c b/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c index 01a70a0d..9ad2a1a8 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c +++ b/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include typedef struct { @@ -8,7 +7,7 @@ typedef struct { Align horizontal; Align vertical; Font font; - string_t text; + FuriString* text; } GuiStringMultiLineModel; static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { @@ -16,7 +15,7 @@ static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiStringMultiLineModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { canvas_set_font(canvas, model->font); elements_multiline_text_aligned( canvas, @@ -24,7 +23,7 @@ static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { model->y, model->horizontal, model->vertical, - string_get_cstr(model->text)); + furi_string_get_cstr(model->text)); } } @@ -32,7 +31,7 @@ static void gui_string_multiline_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiStringMultiLineModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -53,7 +52,7 @@ WidgetElement* widget_element_string_multiline_create( model->horizontal = horizontal; model->vertical = vertical; model->font = font; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_string = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_text_box.c b/applications/services/gui/modules/widget_elements/widget_element_text_box.c index 4750f8f8..2c694820 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_text_box.c +++ b/applications/services/gui/modules/widget_elements/widget_element_text_box.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include typedef struct { @@ -9,7 +8,7 @@ typedef struct { uint8_t height; Align horizontal; Align vertical; - string_t text; + FuriString* text; bool strip_to_dots; } GuiTextBoxModel; @@ -18,7 +17,7 @@ static void gui_text_box_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiTextBoxModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { elements_text_box( canvas, model->x, @@ -27,7 +26,7 @@ static void gui_text_box_draw(Canvas* canvas, WidgetElement* element) { model->height, model->horizontal, model->vertical, - string_get_cstr(model->text), + furi_string_get_cstr(model->text), model->strip_to_dots); } } @@ -36,7 +35,7 @@ static void gui_text_box_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiTextBoxModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -60,7 +59,7 @@ WidgetElement* widget_element_text_box_create( model->height = height; model->horizontal = horizontal; model->vertical = vertical; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); model->strip_to_dots = strip_to_dots; // Allocate and init Element diff --git a/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c b/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c index 6682b106..a4d76638 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c +++ b/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include #include @@ -8,7 +7,7 @@ typedef struct { Font font; Align horizontal; - string_t text; + FuriString* text; } TextScrollLineArray; ARRAY_DEF(TextScrollLineArray, TextScrollLineArray, M_POD_OPLIST) @@ -19,19 +18,19 @@ typedef struct { uint8_t y; uint8_t width; uint8_t height; - string_t text; + FuriString* text; uint8_t scroll_pos_total; uint8_t scroll_pos_current; bool text_formatted; } WidgetElementTextScrollModel; static bool - widget_element_text_scroll_process_ctrl_symbols(TextScrollLineArray* line, string_t text) { + widget_element_text_scroll_process_ctrl_symbols(TextScrollLineArray* line, FuriString* text) { bool processed = false; do { - if(string_get_char(text, 0) != '\e') break; - char ctrl_symbol = string_get_char(text, 1); + if(furi_string_get_char(text, 0) != '\e') break; + char ctrl_symbol = furi_string_get_char(text, 1); if(ctrl_symbol == 'c') { line->horizontal = AlignCenter; } else if(ctrl_symbol == 'r') { @@ -39,7 +38,7 @@ static bool } else if(ctrl_symbol == '#') { line->font = FontPrimary; } - string_right(text, 2); + furi_string_right(text, 2); processed = true; } while(false); @@ -51,7 +50,7 @@ void widget_element_text_scroll_add_line(WidgetElement* element, TextScrollLineA TextScrollLineArray new_line; new_line.font = line->font; new_line.horizontal = line->horizontal; - string_init_set(new_line.text, line->text); + new_line.text = furi_string_alloc_set(line->text); TextScrollLineArray_push_back(model->line_array, new_line); } @@ -59,7 +58,7 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* WidgetElementTextScrollModel* model = element->model; TextScrollLineArray line_tmp; bool all_text_processed = false; - string_init(line_tmp.text); + line_tmp.text = furi_string_alloc(); bool reached_new_line = true; uint16_t total_height = 0; @@ -68,7 +67,7 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* // Set default line properties line_tmp.font = FontSecondary; line_tmp.horizontal = AlignLeft; - string_reset(line_tmp.text); + furi_string_reset(line_tmp.text); // Process control symbols while(widget_element_text_scroll_process_ctrl_symbols(&line_tmp, model->text)) ; @@ -84,38 +83,38 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* uint8_t line_width = 0; uint16_t char_i = 0; while(true) { - char next_char = string_get_char(model->text, char_i++); + char next_char = furi_string_get_char(model->text, char_i++); if(next_char == '\0') { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); total_height += params->leading_default - params->height; all_text_processed = true; break; } else if(next_char == '\n') { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); - string_right(model->text, char_i); + furi_string_right(model->text, char_i); total_height += params->leading_default - params->height; reached_new_line = true; break; } else { line_width += canvas_glyph_width(canvas, next_char); if(line_width > model->width) { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); - string_right(model->text, char_i - 1); - string_reset(line_tmp.text); + furi_string_right(model->text, char_i - 1); + furi_string_reset(line_tmp.text); total_height += params->leading_default - params->height; reached_new_line = false; break; } else { - string_push_back(line_tmp.text, next_char); + furi_string_push_back(line_tmp.text, next_char); } } } } - string_clear(line_tmp.text); + furi_string_free(line_tmp.text); } static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* element) { @@ -150,7 +149,7 @@ static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* eleme x = model->x + model->width; } canvas_draw_str_aligned( - canvas, x, y, line->horizontal, AlignTop, string_get_cstr(line->text)); + canvas, x, y, line->horizontal, AlignTop, furi_string_get_cstr(line->text)); y += params->leading_default; } // Draw scroll bar @@ -205,10 +204,10 @@ static void widget_element_text_scroll_free(WidgetElement* text_scroll) { for(TextScrollLineArray_it(it, model->line_array); !TextScrollLineArray_end_p(it); TextScrollLineArray_next(it)) { TextScrollLineArray* line = TextScrollLineArray_ref(it); - string_clear(line->text); + furi_string_free(line->text); } TextScrollLineArray_clear(model->line_array); - string_clear(model->text); + furi_string_free(model->text); free(text_scroll->model); furi_mutex_free(text_scroll->model_mutex); free(text_scroll); @@ -231,7 +230,7 @@ WidgetElement* widget_element_text_scroll_create( model->scroll_pos_current = 0; model->scroll_pos_total = 1; TextScrollLineArray_init(model->line_array); - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); WidgetElement* text_scroll = malloc(sizeof(WidgetElement)); text_scroll->parent = NULL; diff --git a/applications/services/input/input_cli.c b/applications/services/input/input_cli.c index 037ac53e..d9a8eaeb 100644 --- a/applications/services/input/input_cli.c +++ b/applications/services/input/input_cli.c @@ -19,7 +19,7 @@ static void input_cli_dump_events_callback(const void* value, void* ctx) { furi_message_queue_put(input_queue, value, FuriWaitForever); } -static void input_cli_dump(Cli* cli, string_t args, Input* input) { +static void input_cli_dump(Cli* cli, FuriString* args, Input* input) { UNUSED(args); FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); FuriPubSubSubscription* input_subscription = @@ -47,11 +47,11 @@ static void input_cli_send_print_usage() { printf("\t\t \t - one of 'press', 'release', 'short', 'long'\r\n"); } -static void input_cli_send(Cli* cli, string_t args, Input* input) { +static void input_cli_send(Cli* cli, FuriString* args, Input* input) { UNUSED(cli); InputEvent event; - string_t key_str; - string_init(key_str); + FuriString* key_str; + key_str = furi_string_alloc(); bool parsed = false; do { @@ -59,29 +59,29 @@ static void input_cli_send(Cli* cli, string_t args, Input* input) { if(!args_read_string_and_trim(args, key_str)) { break; } - if(!string_cmp(key_str, "up")) { + if(!furi_string_cmp(key_str, "up")) { event.key = InputKeyUp; - } else if(!string_cmp(key_str, "down")) { + } else if(!furi_string_cmp(key_str, "down")) { event.key = InputKeyDown; - } else if(!string_cmp(key_str, "left")) { + } else if(!furi_string_cmp(key_str, "left")) { event.key = InputKeyLeft; - } else if(!string_cmp(key_str, "right")) { + } else if(!furi_string_cmp(key_str, "right")) { event.key = InputKeyRight; - } else if(!string_cmp(key_str, "ok")) { + } else if(!furi_string_cmp(key_str, "ok")) { event.key = InputKeyOk; - } else if(!string_cmp(key_str, "back")) { + } else if(!furi_string_cmp(key_str, "back")) { event.key = InputKeyBack; } else { break; } // Parse Type - if(!string_cmp(args, "press")) { + if(!furi_string_cmp(args, "press")) { event.type = InputTypePress; - } else if(!string_cmp(args, "release")) { + } else if(!furi_string_cmp(args, "release")) { event.type = InputTypeRelease; - } else if(!string_cmp(args, "short")) { + } else if(!furi_string_cmp(args, "short")) { event.type = InputTypeShort; - } else if(!string_cmp(args, "long")) { + } else if(!furi_string_cmp(args, "long")) { event.type = InputTypeLong; } else { break; @@ -94,26 +94,26 @@ static void input_cli_send(Cli* cli, string_t args, Input* input) { } else { input_cli_send_print_usage(); } - string_clear(key_str); + furi_string_free(key_str); } -void input_cli(Cli* cli, string_t args, void* context) { +void input_cli(Cli* cli, FuriString* args, void* context) { furi_assert(cli); furi_assert(context); Input* input = context; - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { input_cli_usage(); break; } - if(string_cmp_str(cmd, "dump") == 0) { + if(furi_string_cmp_str(cmd, "dump") == 0) { input_cli_dump(cli, args, input); break; } - if(string_cmp_str(cmd, "send") == 0) { + if(furi_string_cmp_str(cmd, "send") == 0) { input_cli_send(cli, args, input); break; } @@ -121,5 +121,5 @@ void input_cli(Cli* cli, string_t args, void* context) { input_cli_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/services/input/input_i.h b/applications/services/input/input_i.h index f709e048..14d8b073 100644 --- a/applications/services/input/input_i.h +++ b/applications/services/input/input_i.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #define INPUT_DEBOUNCE_TICKS_HALF (INPUT_DEBOUNCE_TICKS / 2) @@ -46,4 +45,4 @@ void input_press_timer_callback(void* arg); void input_isr(void* _ctx); /** Input CLI command handler */ -void input_cli(Cli* cli, string_t args, void* context); +void input_cli(Cli* cli, FuriString* args, void* context); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index cf7e5a10..51cddec7 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -98,15 +98,15 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { return application; } -void loader_cli_open(Cli* cli, string_t args, Loader* instance) { +void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); if(loader_is_locked(instance)) { printf("Can't start, furi application is running"); return; } - string_t application_name; - string_init(application_name); + FuriString* application_name; + application_name = furi_string_alloc(); do { if(!args_read_probably_quoted_string_and_trim(args, application_name)) { @@ -115,14 +115,14 @@ void loader_cli_open(Cli* cli, string_t args, Loader* instance) { } const FlipperApplication* application = - loader_find_application_by_name(string_get_cstr(application_name)); + loader_find_application_by_name(furi_string_get_cstr(application_name)); if(!application) { - printf("%s doesn't exists\r\n", string_get_cstr(application_name)); + printf("%s doesn't exists\r\n", furi_string_get_cstr(application_name)); break; } - string_strim(args); - if(!loader_start_application(application, string_get_cstr(args))) { + furi_string_trim(args); + if(!loader_start_application(application, furi_string_get_cstr(args))) { printf("Can't start, furi application is running"); return; } else { @@ -134,10 +134,10 @@ void loader_cli_open(Cli* cli, string_t args, Loader* instance) { } } while(false); - string_clear(application_name); + furi_string_free(application_name); } -void loader_cli_list(Cli* cli, string_t args, Loader* instance) { +void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); UNUSED(args); UNUSED(instance); @@ -159,12 +159,12 @@ void loader_cli_list(Cli* cli, string_t args, Loader* instance) { } } -static void loader_cli(Cli* cli, string_t args, void* _ctx) { +static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { furi_assert(_ctx); Loader* instance = _ctx; - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -172,12 +172,12 @@ static void loader_cli(Cli* cli, string_t args, void* _ctx) { break; } - if(string_cmp_str(cmd, "list") == 0) { + if(furi_string_cmp_str(cmd, "list") == 0) { loader_cli_list(cli, args, instance); break; } - if(string_cmp_str(cmd, "open") == 0) { + if(furi_string_cmp_str(cmd, "open") == 0) { loader_cli_open(cli, args, instance); break; } @@ -185,7 +185,7 @@ static void loader_cli(Cli* cli, string_t args, void* _ctx) { loader_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } LoaderStatus loader_start(Loader* instance, const char* name, const char* args) { diff --git a/applications/services/power/power_cli.c b/applications/services/power/power_cli.c index 6af39631..5c28137e 100644 --- a/applications/services/power/power_cli.c +++ b/applications/services/power/power_cli.c @@ -5,7 +5,7 @@ #include #include -void power_cli_off(Cli* cli, string_t args) { +void power_cli_off(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); Power* power = furi_record_open(RECORD_POWER); @@ -14,13 +14,13 @@ void power_cli_off(Cli* cli, string_t args) { power_off(power); } -void power_cli_reboot(Cli* cli, string_t args) { +void power_cli_reboot(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); power_reboot(PowerBootModeNormal); } -void power_cli_reboot2dfu(Cli* cli, string_t args) { +void power_cli_reboot2dfu(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); power_reboot(PowerBootModeDfu); @@ -32,37 +32,37 @@ static void power_cli_info_callback(const char* key, const char* value, bool las printf("%-24s: %s\r\n", key, value); } -void power_cli_info(Cli* cli, string_t args) { +void power_cli_info(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); furi_hal_power_info_get(power_cli_info_callback, NULL); } -void power_cli_debug(Cli* cli, string_t args) { +void power_cli_debug(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); furi_hal_power_dump_state(); } -void power_cli_5v(Cli* cli, string_t args) { +void power_cli_5v(Cli* cli, FuriString* args) { UNUSED(cli); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_power_disable_otg(); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_power_enable_otg(); } else { - cli_print_usage("power_otg", "<1|0>", string_get_cstr(args)); + cli_print_usage("power_otg", "<1|0>", furi_string_get_cstr(args)); } } -void power_cli_3v3(Cli* cli, string_t args) { +void power_cli_3v3(Cli* cli, FuriString* args) { UNUSED(cli); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_power_disable_external_3_3v(); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_power_enable_external_3_3v(); } else { - cli_print_usage("power_ext", "<1|0>", string_get_cstr(args)); + cli_print_usage("power_ext", "<1|0>", furi_string_get_cstr(args)); } } @@ -82,10 +82,10 @@ static void power_cli_command_print_usage() { } } -void power_cli(Cli* cli, string_t args, void* context) { +void power_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -93,38 +93,38 @@ void power_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "off") == 0) { + if(furi_string_cmp_str(cmd, "off") == 0) { power_cli_off(cli, args); break; } - if(string_cmp_str(cmd, "reboot") == 0) { + if(furi_string_cmp_str(cmd, "reboot") == 0) { power_cli_reboot(cli, args); break; } - if(string_cmp_str(cmd, "reboot2dfu") == 0) { + if(furi_string_cmp_str(cmd, "reboot2dfu") == 0) { power_cli_reboot2dfu(cli, args); break; } - if(string_cmp_str(cmd, "info") == 0) { + if(furi_string_cmp_str(cmd, "info") == 0) { power_cli_info(cli, args); break; } - if(string_cmp_str(cmd, "debug") == 0) { + if(furi_string_cmp_str(cmd, "debug") == 0) { power_cli_debug(cli, args); break; } - if(string_cmp_str(cmd, "5v") == 0) { + if(furi_string_cmp_str(cmd, "5v") == 0) { power_cli_5v(cli, args); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "3v3") == 0) { + if(furi_string_cmp_str(cmd, "3v3") == 0) { power_cli_3v3(cli, args); break; } @@ -133,7 +133,7 @@ void power_cli(Cli* cli, string_t args, void* context) { power_cli_command_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void power_on_system_start() { diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index abba6ea4..4e8c29b4 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #define TAG "RpcSrv" diff --git a/applications/services/rpc/rpc_cli.c b/applications/services/rpc/rpc_cli.c index 8cb0f76a..d03e2198 100644 --- a/applications/services/rpc/rpc_cli.c +++ b/applications/services/rpc/rpc_cli.c @@ -37,7 +37,7 @@ static void rpc_cli_session_terminated_callback(void* context) { furi_semaphore_release(cli_rpc->terminate_semaphore); } -void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { +void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) { UNUSED(args); furi_assert(cli); furi_assert(context); diff --git a/applications/services/rpc/rpc_debug.c b/applications/services/rpc/rpc_debug.c index 9c04bd89..a060654d 100644 --- a/applications/services/rpc/rpc_debug.c +++ b/applications/services/rpc/rpc_debug.c @@ -1,15 +1,14 @@ #include "rpc_i.h" -#include static size_t rpc_debug_print_file_msg( - string_t str, + FuriString* str, const char* prefix, const PB_Storage_File* msg_file, size_t msg_files_size) { size_t cnt = 0; for(size_t i = 0; i < msg_files_size; ++i, ++msg_file) { - string_cat_printf( + furi_string_cat_printf( str, "%s[%c] size: %5ld", prefix, @@ -17,11 +16,11 @@ static size_t rpc_debug_print_file_msg( msg_file->size); if(msg_file->name) { - string_cat_printf(str, " \'%s\'", msg_file->name); + furi_string_cat_printf(str, " \'%s\'", msg_file->name); } if(msg_file->data && msg_file->data->size) { - string_cat_printf( + furi_string_cat_printf( str, " (%d):\'%.*s%s\'", msg_file->data->size, @@ -30,42 +29,42 @@ static size_t rpc_debug_print_file_msg( msg_file->data->size > 30 ? "..." : ""); } - string_cat_printf(str, "\r\n"); + furi_string_cat_printf(str, "\r\n"); } return cnt; } void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size) { - string_t str; - string_init(str); - string_reserve(str, 100 + size * 5); + FuriString* str; + str = furi_string_alloc(); + furi_string_reserve(str, 100 + size * 5); - string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size); + furi_string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size); for(size_t i = 0; i < size; ++i) { - string_cat_printf(str, "%d, ", buffer[i]); + furi_string_cat_printf(str, "%d, ", buffer[i]); } - string_cat_printf(str, "}\r\n"); + furi_string_cat_printf(str, "}\r\n"); - printf("%s", string_get_cstr(str)); - string_reset(str); - string_reserve(str, 100 + size * 3); + printf("%s", furi_string_get_cstr(str)); + furi_string_reset(str); + furi_string_reserve(str, 100 + size * 3); - string_cat_printf(str, "%s HEX(%d): {", prefix, size); + furi_string_cat_printf(str, "%s HEX(%d): {", prefix, size); for(size_t i = 0; i < size; ++i) { - string_cat_printf(str, "%02X", buffer[i]); + furi_string_cat_printf(str, "%02X", buffer[i]); } - string_cat_printf(str, "}\r\n\r\n"); + furi_string_cat_printf(str, "}\r\n\r\n"); - printf("%s", string_get_cstr(str)); - string_clear(str); + printf("%s", furi_string_get_cstr(str)); + furi_string_free(str); } void rpc_debug_print_message(const PB_Main* message) { - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); - string_cat_printf( + furi_string_cat_printf( str, "PB_Main: {\r\n\tresult: %d cmd_id: %ld (%s)\r\n", message->command_status, @@ -74,106 +73,106 @@ void rpc_debug_print_message(const PB_Main* message) { switch(message->which_content) { default: /* not implemented yet */ - string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content); + furi_string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content); break; case PB_Main_stop_session_tag: - string_cat_printf(str, "\tstop_session {\r\n"); + furi_string_cat_printf(str, "\tstop_session {\r\n"); break; case PB_Main_app_start_request_tag: { - string_cat_printf(str, "\tapp_start {\r\n"); + furi_string_cat_printf(str, "\tapp_start {\r\n"); const char* name = message->content.app_start_request.name; const char* args = message->content.app_start_request.args; if(name) { - string_cat_printf(str, "\t\tname: %s\r\n", name); + furi_string_cat_printf(str, "\t\tname: %s\r\n", name); } if(args) { - string_cat_printf(str, "\t\targs: %s\r\n", args); + furi_string_cat_printf(str, "\t\targs: %s\r\n", args); } break; } case PB_Main_app_lock_status_request_tag: { - string_cat_printf(str, "\tapp_lock_status_request {\r\n"); + furi_string_cat_printf(str, "\tapp_lock_status_request {\r\n"); break; } case PB_Main_app_lock_status_response_tag: { - string_cat_printf(str, "\tapp_lock_status_response {\r\n"); + furi_string_cat_printf(str, "\tapp_lock_status_response {\r\n"); bool lock_status = message->content.app_lock_status_response.locked; - string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false"); + furi_string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false"); break; } case PB_Main_storage_md5sum_request_tag: { - string_cat_printf(str, "\tmd5sum_request {\r\n"); + furi_string_cat_printf(str, "\tmd5sum_request {\r\n"); const char* path = message->content.storage_md5sum_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_md5sum_response_tag: { - string_cat_printf(str, "\tmd5sum_response {\r\n"); + furi_string_cat_printf(str, "\tmd5sum_response {\r\n"); const char* path = message->content.storage_md5sum_response.md5sum; if(path) { - string_cat_printf(str, "\t\tmd5sum: %s\r\n", path); + furi_string_cat_printf(str, "\t\tmd5sum: %s\r\n", path); } break; } case PB_Main_system_ping_request_tag: - string_cat_printf(str, "\tping_request {\r\n"); + furi_string_cat_printf(str, "\tping_request {\r\n"); break; case PB_Main_system_ping_response_tag: - string_cat_printf(str, "\tping_response {\r\n"); + furi_string_cat_printf(str, "\tping_response {\r\n"); break; case PB_Main_system_device_info_request_tag: - string_cat_printf(str, "\tdevice_info_request {\r\n"); + furi_string_cat_printf(str, "\tdevice_info_request {\r\n"); break; case PB_Main_system_device_info_response_tag: - string_cat_printf(str, "\tdevice_info_response {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\tdevice_info_response {\r\n"); + furi_string_cat_printf( str, "\t\t%s: %s\r\n", message->content.system_device_info_response.key, message->content.system_device_info_response.value); break; case PB_Main_storage_mkdir_request_tag: - string_cat_printf(str, "\tmkdir {\r\n"); + furi_string_cat_printf(str, "\tmkdir {\r\n"); break; case PB_Main_storage_delete_request_tag: { - string_cat_printf(str, "\tdelete {\r\n"); + furi_string_cat_printf(str, "\tdelete {\r\n"); const char* path = message->content.storage_delete_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_empty_tag: - string_cat_printf(str, "\tempty {\r\n"); + furi_string_cat_printf(str, "\tempty {\r\n"); break; case PB_Main_storage_info_request_tag: { - string_cat_printf(str, "\tinfo_request {\r\n"); + furi_string_cat_printf(str, "\tinfo_request {\r\n"); const char* path = message->content.storage_info_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_info_response_tag: { - string_cat_printf(str, "\tinfo_response {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\tinfo_response {\r\n"); + furi_string_cat_printf( str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space); - string_cat_printf( + furi_string_cat_printf( str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space); break; } case PB_Main_storage_stat_request_tag: { - string_cat_printf(str, "\tstat_request {\r\n"); + furi_string_cat_printf(str, "\tstat_request {\r\n"); const char* path = message->content.storage_stat_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_stat_response_tag: { - string_cat_printf(str, "\tstat_response {\r\n"); + furi_string_cat_printf(str, "\tstat_response {\r\n"); if(message->content.storage_stat_response.has_file) { const PB_Storage_File* msg_file = &message->content.storage_stat_response.file; rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1); @@ -181,26 +180,26 @@ void rpc_debug_print_message(const PB_Main* message) { break; } case PB_Main_storage_list_request_tag: { - string_cat_printf(str, "\tlist_request {\r\n"); + furi_string_cat_printf(str, "\tlist_request {\r\n"); const char* path = message->content.storage_list_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_read_request_tag: { - string_cat_printf(str, "\tread_request {\r\n"); + furi_string_cat_printf(str, "\tread_request {\r\n"); const char* path = message->content.storage_read_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_write_request_tag: { - string_cat_printf(str, "\twrite_request {\r\n"); + furi_string_cat_printf(str, "\twrite_request {\r\n"); const char* path = message->content.storage_write_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } if(message->content.storage_write_request.has_file) { const PB_Storage_File* msg_file = &message->content.storage_write_request.file; @@ -209,7 +208,7 @@ void rpc_debug_print_message(const PB_Main* message) { break; } case PB_Main_storage_read_response_tag: - string_cat_printf(str, "\tread_response {\r\n"); + furi_string_cat_printf(str, "\tread_response {\r\n"); if(message->content.storage_read_response.has_file) { const PB_Storage_File* msg_file = &message->content.storage_read_response.file; rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1); @@ -218,43 +217,43 @@ void rpc_debug_print_message(const PB_Main* message) { case PB_Main_storage_list_response_tag: { const PB_Storage_File* msg_file = message->content.storage_list_response.file; size_t msg_file_count = message->content.storage_list_response.file_count; - string_cat_printf(str, "\tlist_response {\r\n"); + furi_string_cat_printf(str, "\tlist_response {\r\n"); rpc_debug_print_file_msg(str, "\t\t", msg_file, msg_file_count); break; } case PB_Main_storage_rename_request_tag: { - string_cat_printf(str, "\trename_request {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\trename_request {\r\n"); + furi_string_cat_printf( str, "\t\told_path: %s\r\n", message->content.storage_rename_request.old_path); - string_cat_printf( + furi_string_cat_printf( str, "\t\tnew_path: %s\r\n", message->content.storage_rename_request.new_path); break; } case PB_Main_gui_start_screen_stream_request_tag: - string_cat_printf(str, "\tstart_screen_stream {\r\n"); + furi_string_cat_printf(str, "\tstart_screen_stream {\r\n"); break; case PB_Main_gui_stop_screen_stream_request_tag: - string_cat_printf(str, "\tstop_screen_stream {\r\n"); + furi_string_cat_printf(str, "\tstop_screen_stream {\r\n"); break; case PB_Main_gui_screen_frame_tag: - string_cat_printf(str, "\tscreen_frame {\r\n"); + furi_string_cat_printf(str, "\tscreen_frame {\r\n"); break; case PB_Main_gui_send_input_event_request_tag: - string_cat_printf(str, "\tsend_input_event {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\tsend_input_event {\r\n"); + furi_string_cat_printf( str, "\t\tkey: %d\r\n", message->content.gui_send_input_event_request.key); - string_cat_printf( + furi_string_cat_printf( str, "\t\type: %d\r\n", message->content.gui_send_input_event_request.type); break; case PB_Main_gui_start_virtual_display_request_tag: - string_cat_printf(str, "\tstart_virtual_display {\r\n"); + furi_string_cat_printf(str, "\tstart_virtual_display {\r\n"); break; case PB_Main_gui_stop_virtual_display_request_tag: - string_cat_printf(str, "\tstop_virtual_display {\r\n"); + furi_string_cat_printf(str, "\tstop_virtual_display {\r\n"); break; } - string_cat_printf(str, "\t}\r\n}\r\n"); - printf("%s", string_get_cstr(str)); + furi_string_cat_printf(str, "\t}\r\n}\r\n"); + printf("%s", furi_string_get_cstr(str)); - string_clear(str); + furi_string_free(str); } diff --git a/applications/services/rpc/rpc_i.h b/applications/services/rpc/rpc_i.h index 9ffd054a..af9033f0 100644 --- a/applications/services/rpc/rpc_i.h +++ b/applications/services/rpc/rpc_i.h @@ -38,6 +38,6 @@ void rpc_system_gpio_free(void* ctx); void rpc_debug_print_message(const PB_Main* message); void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size); -void rpc_cli_command_start_session(Cli* cli, string_t args, void* context); +void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context); PB_CommandStatus rpc_system_storage_get_error(FS_Error fs_error); diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index 1a7c9349..968b6904 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "filesystem_api_defines.h" #include "storage_sd_api.h" @@ -292,7 +291,7 @@ FS_Error storage_sd_status(Storage* api); /******************* Internal LFS Functions *******************/ -typedef void (*Storage_name_converter)(string_t); +typedef void (*Storage_name_converter)(FuriString*); /** Backs up internal storage to a tar archive * @param api pointer to the api @@ -350,7 +349,7 @@ void storage_get_next_filename( const char* dirname, const char* filename, const char* fileextension, - string_t nextfilename, + FuriString* nextfilename, uint8_t max_len); #ifdef __cplusplus diff --git a/applications/services/storage/storage_cli.c b/applications/services/storage/storage_cli.c index 802ebd54..5e72dce8 100644 --- a/applications/services/storage/storage_cli.c +++ b/applications/services/storage/storage_cli.c @@ -38,11 +38,11 @@ static void storage_cli_print_error(FS_Error error) { printf("Storage error: %s\r\n", storage_error_get_desc(error)); } -static void storage_cli_info(Cli* cli, string_t path) { +static void storage_cli_info(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { + if(furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; FS_Error error = @@ -57,7 +57,7 @@ static void storage_cli_info(Cli* cli, string_t path) { (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } - } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { + } else if(furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { SDInfo sd_info; FS_Error error = storage_sd_info(api, &sd_info); @@ -78,10 +78,10 @@ static void storage_cli_info(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); }; -static void storage_cli_format(Cli* cli, string_t path) { - if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { +static void storage_cli_format(Cli* cli, FuriString* path) { + if(furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { storage_cli_print_error(FSE_NOT_IMPLEMENTED); - } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { + } else if(furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { printf("Formatting SD card, All data will be lost! Are you sure (y/n)?\r\n"); char answer = cli_getc(cli); if(answer == 'y' || answer == 'Y') { @@ -104,9 +104,9 @@ static void storage_cli_format(Cli* cli, string_t path) { } }; -static void storage_cli_list(Cli* cli, string_t path) { +static void storage_cli_list(Cli* cli, FuriString* path) { UNUSED(cli); - if(string_cmp_str(path, "/") == 0) { + if(furi_string_cmp_str(path, "/") == 0) { printf("\t[D] int\r\n"); printf("\t[D] ext\r\n"); printf("\t[D] any\r\n"); @@ -114,7 +114,7 @@ static void storage_cli_list(Cli* cli, string_t path) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_dir_open(file, string_get_cstr(path))) { + if(storage_dir_open(file, furi_string_get_cstr(path))) { FileInfo fileinfo; char name[MAX_NAME_LENGTH]; bool read_done = false; @@ -141,28 +141,31 @@ static void storage_cli_list(Cli* cli, string_t path) { } } -static void storage_cli_tree(Cli* cli, string_t path) { - if(string_cmp_str(path, "/") == 0) { - string_set(path, STORAGE_INT_PATH_PREFIX); +static void storage_cli_tree(Cli* cli, FuriString* path) { + if(furi_string_cmp_str(path, "/") == 0) { + furi_string_set(path, STORAGE_INT_PATH_PREFIX); storage_cli_tree(cli, path); - string_set(path, STORAGE_EXT_PATH_PREFIX); + furi_string_set(path, STORAGE_EXT_PATH_PREFIX); storage_cli_tree(cli, path); } else { Storage* api = furi_record_open(RECORD_STORAGE); DirWalk* dir_walk = dir_walk_alloc(api); - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); - if(dir_walk_open(dir_walk, string_get_cstr(path))) { + if(dir_walk_open(dir_walk, furi_string_get_cstr(path))) { FileInfo fileinfo; bool read_done = false; while(dir_walk_read(dir_walk, name, &fileinfo) == DirWalkOK) { read_done = true; if(fileinfo.flags & FSF_DIRECTORY) { - printf("\t[D] %s\r\n", string_get_cstr(name)); + printf("\t[D] %s\r\n", furi_string_get_cstr(name)); } else { - printf("\t[F] %s %lub\r\n", string_get_cstr(name), (uint32_t)(fileinfo.size)); + printf( + "\t[F] %s %lub\r\n", + furi_string_get_cstr(name), + (uint32_t)(fileinfo.size)); } } @@ -173,18 +176,18 @@ static void storage_cli_tree(Cli* cli, string_t path) { storage_cli_print_error(dir_walk_get_error(dir_walk)); } - string_clear(name); + furi_string_free(name); dir_walk_free(dir_walk); furi_record_close(RECORD_STORAGE); } } -static void storage_cli_read(Cli* cli, string_t path) { +static void storage_cli_read(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { const uint16_t buffer_size = 128; uint16_t read_size = 0; uint8_t* data = malloc(buffer_size); @@ -210,14 +213,14 @@ static void storage_cli_read(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_write(Cli* cli, string_t path) { +static void storage_cli_write(Cli* cli, FuriString* path) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); const uint16_t buffer_size = 512; uint8_t* buffer = malloc(buffer_size); - if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { printf("Just write your text data. New line by Ctrl+Enter, exit by Ctrl+C.\r\n"); uint32_t read_index = 0; @@ -264,16 +267,16 @@ static void storage_cli_write(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { +static void storage_cli_read_chunks(Cli* cli, FuriString* path, FuriString* args) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; - int parsed_count = sscanf(string_get_cstr(args), "%lu", &buffer_size); + int parsed_count = sscanf(furi_string_get_cstr(args), "%lu", &buffer_size); if(parsed_count == EOF || parsed_count != 1) { storage_cli_print_usage(); - } else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + } else if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { uint64_t file_size = storage_file_size(file); printf("Size: %lu\r\n", (uint32_t)file_size); @@ -304,17 +307,17 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { +static void storage_cli_write_chunk(Cli* cli, FuriString* path, FuriString* args) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; - int parsed_count = sscanf(string_get_cstr(args), "%lu", &buffer_size); + int parsed_count = sscanf(furi_string_get_cstr(args), "%lu", &buffer_size); if(parsed_count == EOF || parsed_count != 1) { storage_cli_print_usage(); } else { - if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { printf("Ready\r\n"); if(buffer_size) { @@ -342,20 +345,20 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_stat(Cli* cli, string_t path) { +static void storage_cli_stat(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - if(string_cmp_str(path, "/") == 0) { + if(furi_string_cmp_str(path, "/") == 0) { printf("Storage\r\n"); } else if( - string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0 || - string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0 || - string_cmp_str(path, STORAGE_ANY_PATH_PREFIX) == 0) { + furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0 || + furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0 || + furi_string_cmp_str(path, STORAGE_ANY_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; FS_Error error = - storage_common_fs_info(api, string_get_cstr(path), &total_space, &free_space); + storage_common_fs_info(api, furi_string_get_cstr(path), &total_space, &free_space); if(error != FSE_OK) { storage_cli_print_error(error); @@ -367,7 +370,7 @@ static void storage_cli_stat(Cli* cli, string_t path) { } } else { FileInfo fileinfo; - FS_Error error = storage_common_stat(api, string_get_cstr(path), &fileinfo); + FS_Error error = storage_common_stat(api, furi_string_get_cstr(path), &fileinfo); if(error == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { @@ -383,31 +386,31 @@ static void storage_cli_stat(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { +static void storage_cli_copy(Cli* cli, FuriString* old_path, FuriString* args) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - string_t new_path; - string_init(new_path); + FuriString* new_path; + new_path = furi_string_alloc(); if(!args_read_probably_quoted_string_and_trim(args, new_path)) { storage_cli_print_usage(); } else { - FS_Error error = - storage_common_copy(api, string_get_cstr(old_path), string_get_cstr(new_path)); + FS_Error error = storage_common_copy( + api, furi_string_get_cstr(old_path), furi_string_get_cstr(new_path)); if(error != FSE_OK) { storage_cli_print_error(error); } } - string_clear(new_path); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); } -static void storage_cli_remove(Cli* cli, string_t path) { +static void storage_cli_remove(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - FS_Error error = storage_common_remove(api, string_get_cstr(path)); + FS_Error error = storage_common_remove(api, furi_string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); @@ -416,31 +419,31 @@ static void storage_cli_remove(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { +static void storage_cli_rename(Cli* cli, FuriString* old_path, FuriString* args) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - string_t new_path; - string_init(new_path); + FuriString* new_path; + new_path = furi_string_alloc(); if(!args_read_probably_quoted_string_and_trim(args, new_path)) { storage_cli_print_usage(); } else { - FS_Error error = - storage_common_rename(api, string_get_cstr(old_path), string_get_cstr(new_path)); + FS_Error error = storage_common_rename( + api, furi_string_get_cstr(old_path), furi_string_get_cstr(new_path)); if(error != FSE_OK) { storage_cli_print_error(error); } } - string_clear(new_path); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); } -static void storage_cli_mkdir(Cli* cli, string_t path) { +static void storage_cli_mkdir(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - FS_Error error = storage_common_mkdir(api, string_get_cstr(path)); + FS_Error error = storage_common_mkdir(api, furi_string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); @@ -449,12 +452,12 @@ static void storage_cli_mkdir(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_md5(Cli* cli, string_t path) { +static void storage_cli_md5(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { const uint16_t buffer_size = 512; const uint8_t hash_size = 16; uint8_t* data = malloc(buffer_size); @@ -487,12 +490,12 @@ static void storage_cli_md5(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -void storage_cli(Cli* cli, string_t args, void* context) { +void storage_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_t path; - string_init(cmd); - string_init(path); + FuriString* cmd; + FuriString* path; + cmd = furi_string_alloc(); + path = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -505,72 +508,72 @@ void storage_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "info") == 0) { + if(furi_string_cmp_str(cmd, "info") == 0) { storage_cli_info(cli, path); break; } - if(string_cmp_str(cmd, "format") == 0) { + if(furi_string_cmp_str(cmd, "format") == 0) { storage_cli_format(cli, path); break; } - if(string_cmp_str(cmd, "list") == 0) { + if(furi_string_cmp_str(cmd, "list") == 0) { storage_cli_list(cli, path); break; } - if(string_cmp_str(cmd, "tree") == 0) { + if(furi_string_cmp_str(cmd, "tree") == 0) { storage_cli_tree(cli, path); break; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { storage_cli_read(cli, path); break; } - if(string_cmp_str(cmd, "read_chunks") == 0) { + if(furi_string_cmp_str(cmd, "read_chunks") == 0) { storage_cli_read_chunks(cli, path, args); break; } - if(string_cmp_str(cmd, "write") == 0) { + if(furi_string_cmp_str(cmd, "write") == 0) { storage_cli_write(cli, path); break; } - if(string_cmp_str(cmd, "write_chunk") == 0) { + if(furi_string_cmp_str(cmd, "write_chunk") == 0) { storage_cli_write_chunk(cli, path, args); break; } - if(string_cmp_str(cmd, "copy") == 0) { + if(furi_string_cmp_str(cmd, "copy") == 0) { storage_cli_copy(cli, path, args); break; } - if(string_cmp_str(cmd, "remove") == 0) { + if(furi_string_cmp_str(cmd, "remove") == 0) { storage_cli_remove(cli, path); break; } - if(string_cmp_str(cmd, "rename") == 0) { + if(furi_string_cmp_str(cmd, "rename") == 0) { storage_cli_rename(cli, path, args); break; } - if(string_cmp_str(cmd, "mkdir") == 0) { + if(furi_string_cmp_str(cmd, "mkdir") == 0) { storage_cli_mkdir(cli, path); break; } - if(string_cmp_str(cmd, "md5") == 0) { + if(furi_string_cmp_str(cmd, "md5") == 0) { storage_cli_md5(cli, path); break; } - if(string_cmp_str(cmd, "stat") == 0) { + if(furi_string_cmp_str(cmd, "stat") == 0) { storage_cli_stat(cli, path); break; } @@ -578,11 +581,11 @@ void storage_cli(Cli* cli, string_t args, void* context) { storage_cli_print_usage(); } while(false); - string_clear(path); - string_clear(cmd); + furi_string_free(path); + furi_string_free(cmd); } -static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { +static void storage_cli_factory_reset(Cli* cli, FuriString* args, void* context) { UNUSED(args); UNUSED(context); printf("All data will be lost! Are you sure (y/n)?\r\n"); diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index 80cafb28..379fc4ed 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -1,6 +1,5 @@ #include #include -#include #include "storage.h" #include "storage_i.h" #include "storage_message.h" @@ -374,13 +373,13 @@ static FS_Error storage_copy_recursive(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_mkdir(storage, new_path); DirWalk* dir_walk = dir_walk_alloc(storage); - string_t path; - string_t tmp_new_path; - string_t tmp_old_path; + FuriString* path; + FuriString* tmp_new_path; + FuriString* tmp_old_path; FileInfo fileinfo; - string_init(path); - string_init(tmp_new_path); - string_init(tmp_old_path); + path = furi_string_alloc(); + tmp_new_path = furi_string_alloc(); + tmp_old_path = furi_string_alloc(); do { if(error != FSE_OK) break; @@ -399,15 +398,17 @@ static FS_Error } else if(res == DirWalkLast) { break; } else { - string_set(tmp_old_path, path); - string_right(path, strlen(old_path)); - string_printf(tmp_new_path, "%s%s", new_path, string_get_cstr(path)); + furi_string_set(tmp_old_path, path); + furi_string_right(path, strlen(old_path)); + furi_string_printf(tmp_new_path, "%s%s", new_path, furi_string_get_cstr(path)); if(fileinfo.flags & FSF_DIRECTORY) { - error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + error = storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path)); } else { error = storage_common_copy( - storage, string_get_cstr(tmp_old_path), string_get_cstr(tmp_new_path)); + storage, + furi_string_get_cstr(tmp_old_path), + furi_string_get_cstr(tmp_new_path)); } if(error != FSE_OK) break; @@ -416,9 +417,9 @@ static FS_Error } while(false); - string_clear(tmp_new_path); - string_clear(tmp_old_path); - string_clear(path); + furi_string_free(tmp_new_path); + furi_string_free(tmp_old_path); + furi_string_free(path); dir_walk_free(dir_walk); return error; } @@ -459,11 +460,11 @@ static FS_Error storage_merge_recursive(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_mkdir(storage, new_path); DirWalk* dir_walk = dir_walk_alloc(storage); - string_t path, file_basename, tmp_new_path; + FuriString *path, *file_basename, *tmp_new_path; FileInfo fileinfo; - string_init(path); - string_init(file_basename); - string_init(tmp_new_path); + path = furi_string_alloc(); + file_basename = furi_string_alloc(); + tmp_new_path = furi_string_alloc(); do { if((error != FSE_OK) && (error != FSE_EXIST)) break; @@ -483,14 +484,15 @@ static FS_Error } else if(res == DirWalkLast) { break; } else { - path_extract_basename(string_get_cstr(path), file_basename); - path_concat(new_path, string_get_cstr(file_basename), tmp_new_path); + path_extract_basename(furi_string_get_cstr(path), file_basename); + path_concat(new_path, furi_string_get_cstr(file_basename), tmp_new_path); if(fileinfo.flags & FSF_DIRECTORY) { - if(storage_common_stat(storage, string_get_cstr(tmp_new_path), &fileinfo) == - FSE_OK) { + if(storage_common_stat( + storage, furi_string_get_cstr(tmp_new_path), &fileinfo) == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { - error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + error = + storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path)); if(error != FSE_OK) { break; } @@ -498,7 +500,7 @@ static FS_Error } } error = storage_common_merge( - storage, string_get_cstr(path), string_get_cstr(tmp_new_path)); + storage, furi_string_get_cstr(path), furi_string_get_cstr(tmp_new_path)); if(error != FSE_OK) { break; @@ -508,9 +510,9 @@ static FS_Error } while(false); - string_clear(tmp_new_path); - string_clear(file_basename); - string_clear(path); + furi_string_free(tmp_new_path); + furi_string_free(file_basename); + furi_string_free(path); dir_walk_free(dir_walk); return error; } @@ -518,8 +520,8 @@ static FS_Error FS_Error storage_common_merge(Storage* storage, const char* old_path, const char* new_path) { FS_Error error; const char* new_path_tmp; - string_t new_path_next; - string_init(new_path_next); + FuriString* new_path_next; + new_path_next = furi_string_alloc(); FileInfo fileinfo; error = storage_common_stat(storage, old_path, &fileinfo); @@ -530,13 +532,13 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char } else { error = storage_common_stat(storage, new_path, &fileinfo); if(error == FSE_OK) { - string_set_str(new_path_next, new_path); - string_t dir_path; - string_t filename; + furi_string_set(new_path_next, new_path); + FuriString* dir_path; + FuriString* filename; char extension[MAX_EXT_LEN]; - string_init(dir_path); - string_init(filename); + dir_path = furi_string_alloc(); + filename = furi_string_alloc(); path_extract_filename(new_path_next, filename, true); path_extract_dirname(new_path, dir_path); @@ -544,17 +546,18 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char storage_get_next_filename( storage, - string_get_cstr(dir_path), - string_get_cstr(filename), + furi_string_get_cstr(dir_path), + furi_string_get_cstr(filename), extension, new_path_next, 255); - string_cat_printf(dir_path, "/%s%s", string_get_cstr(new_path_next), extension); - string_set(new_path_next, dir_path); + furi_string_cat_printf( + dir_path, "/%s%s", furi_string_get_cstr(new_path_next), extension); + furi_string_set(new_path_next, dir_path); - string_clear(dir_path); - string_clear(filename); - new_path_tmp = string_get_cstr(new_path_next); + furi_string_free(dir_path); + furi_string_free(filename); + new_path_tmp = furi_string_get_cstr(new_path_next); } else { new_path_tmp = new_path; } @@ -577,7 +580,7 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char } } - string_clear(new_path_next); + furi_string_free(new_path_next); return error; } @@ -707,8 +710,8 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { furi_assert(path); FileInfo fileinfo; bool result = false; - string_t fullname; - string_t cur_dir; + FuriString* fullname; + FuriString* cur_dir; if(storage_simply_remove(storage, path)) { return true; @@ -716,26 +719,26 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { char* name = malloc(MAX_NAME_LENGTH + 1); File* dir = storage_file_alloc(storage); - string_init_set_str(cur_dir, path); + cur_dir = furi_string_alloc_set(path); bool go_deeper = false; while(1) { - if(!storage_dir_open(dir, string_get_cstr(cur_dir))) { + if(!storage_dir_open(dir, furi_string_get_cstr(cur_dir))) { storage_dir_close(dir); break; } while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { if(fileinfo.flags & FSF_DIRECTORY) { - string_cat_printf(cur_dir, "/%s", name); + furi_string_cat_printf(cur_dir, "/%s", name); go_deeper = true; break; } - string_init_printf(fullname, "%s/%s", string_get_cstr(cur_dir), name); - FS_Error error = storage_common_remove(storage, string_get_cstr(fullname)); + fullname = furi_string_alloc_printf("%s/%s", furi_string_get_cstr(cur_dir), name); + FS_Error error = storage_common_remove(storage, furi_string_get_cstr(fullname)); furi_check(error == FSE_OK); - string_clear(fullname); + furi_string_free(fullname); } storage_dir_close(dir); @@ -744,13 +747,13 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { continue; } - FS_Error error = storage_common_remove(storage, string_get_cstr(cur_dir)); + FS_Error error = storage_common_remove(storage, furi_string_get_cstr(cur_dir)); furi_check(error == FSE_OK); - if(string_cmp(cur_dir, path)) { - size_t last_char = string_search_rchar(cur_dir, '/'); - furi_assert(last_char != STRING_FAILURE); - string_left(cur_dir, last_char); + if(furi_string_cmp(cur_dir, path)) { + size_t last_char = furi_string_search_rchar(cur_dir, '/'); + furi_assert(last_char != FURI_STRING_FAILURE); + furi_string_left(cur_dir, last_char); } else { result = true; break; @@ -758,7 +761,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { } storage_file_free(dir); - string_clear(cur_dir); + furi_string_free(cur_dir); free(name); return result; } @@ -780,22 +783,22 @@ void storage_get_next_filename( const char* dirname, const char* filename, const char* fileextension, - string_t nextfilename, + FuriString* nextfilename, uint8_t max_len) { - string_t temp_str; + FuriString* temp_str; uint16_t num = 0; - string_init_printf(temp_str, "%s/%s%s", dirname, filename, fileextension); + temp_str = furi_string_alloc_printf("%s/%s%s", dirname, filename, fileextension); - while(storage_common_stat(storage, string_get_cstr(temp_str), NULL) == FSE_OK) { + while(storage_common_stat(storage, furi_string_get_cstr(temp_str), NULL) == FSE_OK) { num++; - string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension); + furi_string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension); } if(num && (max_len > strlen(filename))) { - string_printf(nextfilename, "%s%d", filename, num); + furi_string_printf(nextfilename, "%s%d", filename, num); } else { - string_printf(nextfilename, "%s", filename); + furi_string_printf(nextfilename, "%s", filename); } - string_clear(temp_str); + furi_string_free(temp_str); } diff --git a/applications/services/storage/storage_glue.c b/applications/services/storage/storage_glue.c index d9d599c5..c5682f67 100644 --- a/applications/services/storage/storage_glue.c +++ b/applications/services/storage/storage_glue.c @@ -7,25 +7,25 @@ void storage_file_init(StorageFile* obj) { obj->file = NULL; obj->type = ST_ERROR; obj->file_data = NULL; - string_init(obj->path); + obj->path = furi_string_alloc(); } void storage_file_init_set(StorageFile* obj, const StorageFile* src) { obj->file = src->file; obj->type = src->type; obj->file_data = src->file_data; - string_init_set(obj->path, src->path); + obj->path = furi_string_alloc_set(src->path); } void storage_file_set(StorageFile* obj, const StorageFile* src) { obj->file = src->file; obj->type = src->type; obj->file_data = src->file_data; - string_set(obj->path, src->path); + furi_string_set(obj->path, src->path); } void storage_file_clear(StorageFile* obj) { - string_clear(obj->path); + furi_string_free(obj->path); } /****************** storage data ******************/ @@ -101,7 +101,7 @@ bool storage_has_file(const File* file, StorageData* storage_data) { return result; } -bool storage_path_already_open(string_t path, StorageFileList_t array) { +bool storage_path_already_open(FuriString* path, StorageFileList_t array) { bool open = false; StorageFileList_it_t it; @@ -109,7 +109,7 @@ bool storage_path_already_open(string_t path, StorageFileList_t array) { for(StorageFileList_it(it, array); !StorageFileList_end_p(it); StorageFileList_next(it)) { const StorageFile* storage_file = StorageFileList_cref(it); - if(string_cmp(storage_file->path, path) == 0) { + if(furi_string_cmp(storage_file->path, path) == 0) { open = true; break; } @@ -158,14 +158,18 @@ void* storage_get_storage_file_data(const File* file, StorageData* storage) { return founded_file->file_data; } -void storage_push_storage_file(File* file, string_t path, StorageType type, StorageData* storage) { +void storage_push_storage_file( + File* file, + FuriString* path, + StorageType type, + StorageData* storage) { StorageFile* storage_file = StorageFileList_push_new(storage->files); furi_check(storage_file != NULL); file->file_id = (uint32_t)storage_file; storage_file->file = file; storage_file->type = type; - string_set(storage_file->path, path); + furi_string_set(storage_file->path, path); } bool storage_pop_storage_file(File* file, StorageData* storage) { diff --git a/applications/services/storage/storage_glue.h b/applications/services/storage/storage_glue.h index 7cf2e072..53fa0de1 100644 --- a/applications/services/storage/storage_glue.h +++ b/applications/services/storage/storage_glue.h @@ -2,7 +2,6 @@ #include #include "filesystem_api_internal.h" -#include #include #ifdef __cplusplus @@ -21,7 +20,7 @@ typedef struct { File* file; StorageType type; void* file_data; - string_t path; + FuriString* path; } StorageFile; typedef enum { @@ -62,12 +61,16 @@ struct StorageData { }; bool storage_has_file(const File* file, StorageData* storage_data); -bool storage_path_already_open(string_t path, StorageFileList_t files); +bool storage_path_already_open(FuriString* path, StorageFileList_t files); void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage); void* storage_get_storage_file_data(const File* file, StorageData* storage); -void storage_push_storage_file(File* file, string_t path, StorageType type, StorageData* storage); +void storage_push_storage_file( + File* file, + FuriString* path, + StorageType type, + StorageData* storage); bool storage_pop_storage_file(File* file, StorageData* storage); #ifdef __cplusplus diff --git a/applications/services/storage/storage_internal_api.c b/applications/services/storage/storage_internal_api.c index 620eae36..6d620b9c 100644 --- a/applications/services/storage/storage_internal_api.c +++ b/applications/services/storage/storage_internal_api.c @@ -1,5 +1,4 @@ #include -#include #include "storage.h" #include diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index 46ca4e16..8643e974 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -1,7 +1,6 @@ #include "storage_processing.h" #include #include -#include #define FS_CALL(_storage, _fn) \ storage_data_lock(_storage); \ @@ -68,21 +67,22 @@ static StorageType storage_get_type_by_path(Storage* app, const char* path) { return type; } -static void storage_path_change_to_real_storage(string_t path, StorageType real_storage) { - if(memcmp(string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == +static void storage_path_change_to_real_storage(FuriString* path, StorageType real_storage) { + if(memcmp( + furi_string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == 0) { switch(real_storage) { case ST_EXT: - string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]); - string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]); - string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]); - string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]); + furi_string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]); + furi_string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]); + furi_string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]); + furi_string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]); break; case ST_INT: - string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]); - string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]); - string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]); - string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]); + furi_string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]); + furi_string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]); + furi_string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]); + furi_string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]); break; default: break; @@ -107,8 +107,8 @@ bool storage_process_file_open( file->error_id = FSE_INVALID_NAME; } else { storage = storage_get_storage_by_type(app, type); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); if(storage_path_already_open(real_path, storage->files)) { @@ -118,7 +118,7 @@ bool storage_process_file_open( FS_CALL(storage, file.open(storage, file, remove_vfs(path), access_mode, open_mode)); } - string_clear(real_path); + furi_string_free(real_path); } return ret; @@ -266,8 +266,8 @@ bool storage_process_dir_open(Storage* app, File* file, const char* path) { file->error_id = FSE_INVALID_NAME; } else { storage = storage_get_storage_by_type(app, type); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); if(storage_path_already_open(real_path, storage->files)) { @@ -276,7 +276,7 @@ bool storage_process_dir_open(Storage* app, File* file, const char* path) { storage_push_storage_file(file, real_path, type, storage); FS_CALL(storage, dir.open(storage, file, remove_vfs(path))); } - string_clear(real_path); + furi_string_free(real_path); } return ret; @@ -350,8 +350,8 @@ static FS_Error storage_process_common_remove(Storage* app, const char* path) { FS_Error ret = FSE_OK; StorageType type = storage_get_type_by_path(app, path); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); do { @@ -369,7 +369,7 @@ static FS_Error storage_process_common_remove(Storage* app, const char* path) { FS_CALL(storage, common.remove(storage, remove_vfs(path))); } while(false); - string_clear(real_path); + furi_string_free(real_path); return ret; } diff --git a/applications/services/storage/storage_test_app.c b/applications/services/storage/storage_test_app.c index 8bfa9826..852953e9 100644 --- a/applications/services/storage/storage_test_app.c +++ b/applications/services/storage/storage_test_app.c @@ -224,13 +224,12 @@ static void do_dir_test(Storage* api, const char* path) { } static void do_test_start(Storage* api, const char* path) { - string_t str_path; - string_init_printf(str_path, "%s/test-folder", path); + FuriString* str_path = furi_string_alloc_printf("%s/test-folder", path); FURI_LOG_I(TAG, "--------- START \"%s\" ---------", path); // mkdir - FS_Error result = storage_common_mkdir(api, string_get_cstr(str_path)); + FS_Error result = storage_common_mkdir(api, furi_string_get_cstr(str_path)); if(result == FSE_OK) { FURI_LOG_I(TAG, "mkdir ok"); @@ -240,7 +239,7 @@ static void do_test_start(Storage* api, const char* path) { // stat FileInfo fileinfo; - result = storage_common_stat(api, string_get_cstr(str_path), &fileinfo); + result = storage_common_stat(api, furi_string_get_cstr(str_path), &fileinfo); if(result == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { @@ -252,16 +251,14 @@ static void do_test_start(Storage* api, const char* path) { FURI_LOG_E(TAG, "stat #1, %s", storage_error_get_desc(result)); } - string_clear(str_path); + furi_string_free(str_path); } static void do_test_end(Storage* api, const char* path) { uint64_t total_space; uint64_t free_space; - string_t str_path_1; - string_t str_path_2; - string_init_printf(str_path_1, "%s/test-folder", path); - string_init_printf(str_path_2, "%s/test-folder2", path); + FuriString* str_path_1 = furi_string_alloc_printf("%s/test-folder", path); + FuriString* str_path_2 = furi_string_alloc_printf("%s/test-folder2", path); FURI_LOG_I(TAG, "--------- END \"%s\" ---------", path); @@ -277,7 +274,8 @@ static void do_test_end(Storage* api, const char* path) { } // rename #1 - result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + result = storage_common_rename( + api, furi_string_get_cstr(str_path_1), furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "rename #1 ok"); } else { @@ -285,7 +283,7 @@ static void do_test_end(Storage* api, const char* path) { } // remove #1 - result = storage_common_remove(api, string_get_cstr(str_path_2)); + result = storage_common_remove(api, furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "remove #1 ok"); } else { @@ -293,10 +291,11 @@ static void do_test_end(Storage* api, const char* path) { } // rename #2 - string_printf(str_path_1, "%s/test.txt", path); - string_printf(str_path_2, "%s/test2.txt", path); + furi_string_printf(str_path_1, "%s/test.txt", path); + furi_string_printf(str_path_2, "%s/test2.txt", path); - result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + result = storage_common_rename( + api, furi_string_get_cstr(str_path_1), furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "rename #2 ok"); } else { @@ -304,15 +303,15 @@ static void do_test_end(Storage* api, const char* path) { } // remove #2 - result = storage_common_remove(api, string_get_cstr(str_path_2)); + result = storage_common_remove(api, furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "remove #2 ok"); } else { FURI_LOG_E(TAG, "remove #2, %s", storage_error_get_desc(result)); } - string_clear(str_path_1); - string_clear(str_path_2); + furi_string_free(str_path_1); + furi_string_free(str_path_2); } int32_t storage_test_app(void* p) { diff --git a/applications/services/storage/storages/storage_int.c b/applications/services/storage/storages/storage_int.c index 75839735..ab025501 100644 --- a/applications/services/storage/storages/storage_int.c +++ b/applications/services/storage/storages/storage_int.c @@ -338,11 +338,12 @@ static bool storage_int_file_open( storage_set_storage_file_data(file, handle, storage); if(!enough_free_space) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_basename(path, filename); - bool is_dot_file = (!string_empty_p(filename) && (string_get_char(filename, 0) == '.')); - string_clear(filename); + bool is_dot_file = + (!furi_string_empty(filename) && (furi_string_get_char(filename, 0) == '.')); + furi_string_free(filename); /* Restrict write & creation access to all non-dot files */ if(!is_dot_file && (flags & (LFS_O_CREAT | LFS_O_WRONLY))) { diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index 6b4489f0..a42969b2 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -78,11 +77,11 @@ static DialogMessageButton icon2_screen(DialogsApp* dialogs, DialogMessage* mess static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); const char* my_name = furi_hal_version_get_name_ptr(); - string_cat_printf( + furi_string_cat_printf( buffer, "%d.F%dB%dC%d %s:%s %s\n", furi_hal_version_get_hw_version(), @@ -93,26 +92,26 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* furi_hal_region_get_name(), my_name ? my_name : "Unknown"); - string_cat_printf(buffer, "Serial Number:\n"); + furi_string_cat_printf(buffer, "Serial Number:\n"); const uint8_t* uid = furi_hal_version_uid(); for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { - string_cat_printf(buffer, "%02X", uid[i]); + furi_string_cat_printf(buffer, "%02X", uid[i]); } dialog_message_set_header(message, "HW Version Info:", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); + dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - string_clear(buffer); + furi_string_free(buffer); return result; } static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); const Version* ver = furi_hal_version_get_firmware_version(); const BleGlueC2Info* c2_ver = NULL; #ifdef SRV_BT @@ -120,9 +119,9 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* #endif if(!ver) { - string_cat_printf(buffer, "No info\n"); + furi_string_cat_printf(buffer, "No info\n"); } else { - string_cat_printf( + furi_string_cat_printf( buffer, "%s [%s]\n%s%s [%s] %s\n[%d] %s", version_get_version(ver), @@ -136,11 +135,11 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* } dialog_message_set_header(message, "FW Version Info:", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); + dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - string_clear(buffer); + furi_string_free(buffer); return result; } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c index ddeea4eb..71a3df78 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c @@ -92,19 +92,19 @@ static void storage_settings_scene_benchmark(StorageSettings* app) { app->fs_api, bench_size[i], bench_data, &bench_w_speed[i])) break; - if(i > 0) string_cat_printf(app->text_string, "\n"); - string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]); + if(i > 0) furi_string_cat_printf(app->text_string, "\n"); + furi_string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]); dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + dialog_ex, furi_string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); if(!storage_settings_scene_bench_read( app->fs_api, bench_size[i], bench_data, &bench_r_speed[i])) break; - string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]); + furi_string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + dialog_ex, furi_string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); } free(bench_data); @@ -159,5 +159,5 @@ void storage_settings_scene_benchmark_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c b/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c index a6947968..64d2b96b 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c @@ -49,13 +49,13 @@ bool storage_settings_scene_factory_reset_on_event(void* context, SceneManagerEv case DialogExResultRight: counter++; if(counter < STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT) { - string_printf( + furi_string_printf( app->text_string, "%ld presses left", STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT - counter); dialog_ex_set_text( app->dialog_ex, - string_get_cstr(app->text_string), + furi_string_get_cstr(app->text_string), 64, 32, AlignCenter, @@ -83,5 +83,5 @@ void storage_settings_scene_factory_reset_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c index 76c7fd0e..d2d4ecd8 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c @@ -25,14 +25,14 @@ void storage_settings_scene_internal_info_on_enter(void* context) { dialog_ex_set_text( dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); } else { - string_printf( + furi_string_printf( app->text_string, "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + dialog_ex, furi_string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); } view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); @@ -58,5 +58,5 @@ void storage_settings_scene_internal_info_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c index cfb4f310..f5d286c7 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c @@ -24,7 +24,7 @@ void storage_settings_scene_sd_info_on_enter(void* context) { dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { - string_printf( + furi_string_printf( app->text_string, "Label: %s\nType: %s\n%lu KB total\n%lu KB free", sd_info.label, @@ -32,7 +32,7 @@ void storage_settings_scene_sd_info_on_enter(void* context) { sd_info.kb_total, sd_info.kb_free); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + dialog_ex, furi_string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); } view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); @@ -70,5 +70,5 @@ void storage_settings_scene_sd_info_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/storage_settings.c b/applications/settings/storage_settings/storage_settings.c index f580e636..77a8f0f2 100644 --- a/applications/settings/storage_settings/storage_settings.c +++ b/applications/settings/storage_settings/storage_settings.c @@ -21,7 +21,7 @@ static StorageSettings* storage_settings_alloc() { app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&storage_settings_scene_handlers, app); - string_init(app->text_string); + app->text_string = furi_string_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); view_dispatcher_set_event_callback_context(app->view_dispatcher, app); @@ -60,7 +60,7 @@ static void storage_settings_free(StorageSettings* app) { furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_NOTIFICATION); - string_clear(app->text_string); + furi_string_free(app->text_string); free(app); } diff --git a/applications/settings/storage_settings/storage_settings.h b/applications/settings/storage_settings/storage_settings.h index f2d071c4..4cf185e0 100644 --- a/applications/settings/storage_settings/storage_settings.h +++ b/applications/settings/storage_settings/storage_settings.h @@ -34,7 +34,7 @@ typedef struct { DialogEx* dialog_ex; // text - string_t text_string; + FuriString* text_string; } StorageSettings; typedef enum { diff --git a/applications/system/storage_move_to_sd/storage_move_to_sd.c b/applications/system/storage_move_to_sd/storage_move_to_sd.c index e5b195d5..2027bd23 100644 --- a/applications/system/storage_move_to_sd/storage_move_to_sd.c +++ b/applications/system/storage_move_to_sd/storage_move_to_sd.c @@ -2,7 +2,6 @@ #include #include #include "loader/loader.h" -#include "m-string.h" #include #include #include @@ -28,25 +27,26 @@ bool storage_move_to_sd_perform(void) { dir_walk_set_recursive(dir_walk, false); dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); - string_t path_src, path_dst; + FuriString *path_src, *path_dst; - string_init(path_dst); - string_init(path_src); + path_dst = furi_string_alloc(); + path_src = furi_string_alloc(); if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { while(dir_walk_read(dir_walk, path_src, NULL) == DirWalkOK) { - string_set(path_dst, path_src); - string_replace_at( + furi_string_set(path_dst, path_src); + furi_string_replace_at( path_dst, 0, strlen(STORAGE_INT_PATH_PREFIX), STORAGE_EXT_PATH_PREFIX); - storage_common_merge(storage, string_get_cstr(path_src), string_get_cstr(path_dst)); - storage_simply_remove_recursive(storage, string_get_cstr(path_src)); + storage_common_merge( + storage, furi_string_get_cstr(path_src), furi_string_get_cstr(path_dst)); + storage_simply_remove_recursive(storage, furi_string_get_cstr(path_src)); } } dir_walk_free(dir_walk); - string_clear(path_dst); - string_clear(path_src); + furi_string_free(path_dst); + furi_string_free(path_src); furi_record_close(RECORD_STORAGE); @@ -62,8 +62,8 @@ static bool storage_move_to_sd_check(void) { dir_walk_set_recursive(dir_walk, false); dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { // if at least 1 entry is present, we should migrate @@ -71,7 +71,7 @@ static bool storage_move_to_sd_check(void) { } dir_walk_free(dir_walk); - string_clear(name); + furi_string_free(name); furi_record_close(RECORD_STORAGE); diff --git a/applications/system/updater/cli/updater_cli.c b/applications/system/updater/cli/updater_cli.c index ec209bd1..c3cdbb5f 100644 --- a/applications/system/updater/cli/updater_cli.c +++ b/applications/system/updater/cli/updater_cli.c @@ -1,7 +1,6 @@ #include #include -#include #include #include #include @@ -12,16 +11,16 @@ #include #include -typedef void (*cmd_handler)(string_t args); +typedef void (*cmd_handler)(FuriString* args); typedef struct { const char* command; const cmd_handler handler; } CliSubcommand; -static void updater_cli_install(string_t manifest_path) { - printf("Verifying update package at '%s'\r\n", string_get_cstr(manifest_path)); +static void updater_cli_install(FuriString* manifest_path) { + printf("Verifying update package at '%s'\r\n", furi_string_get_cstr(manifest_path)); - UpdatePrepareResult result = update_operation_prepare(string_get_cstr(manifest_path)); + UpdatePrepareResult result = update_operation_prepare(furi_string_get_cstr(manifest_path)); if(result != UpdatePrepareResultOK) { printf( "Error: %s. Stopping update.\r\n", @@ -33,23 +32,23 @@ static void updater_cli_install(string_t manifest_path) { furi_hal_power_reset(); } -static void updater_cli_backup(string_t args) { - printf("Backup /int to '%s'\r\n", string_get_cstr(args)); +static void updater_cli_backup(FuriString* args) { + printf("Backup /int to '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_create(storage, string_get_cstr(args)); + bool success = lfs_backup_create(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } -static void updater_cli_restore(string_t args) { - printf("Restore /int from '%s'\r\n", string_get_cstr(args)); +static void updater_cli_restore(FuriString* args) { + printf("Restore /int from '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_unpack(storage, string_get_cstr(args)); + bool success = lfs_backup_unpack(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } -static void updater_cli_help(string_t args) { +static void updater_cli_help(FuriString* args) { UNUSED(args); printf("Commands:\r\n" "\tinstall /ext/path/to/update.fuf - verify & apply update package\r\n" @@ -64,25 +63,25 @@ static const CliSubcommand update_cli_subcommands[] = { {.command = "help", .handler = updater_cli_help}, }; -static void updater_cli_ep(Cli* cli, string_t args, void* context) { +static void updater_cli_ep(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - string_t subcommand; - string_init(subcommand); - if(!args_read_string_and_trim(args, subcommand) || string_empty_p(args)) { + FuriString* subcommand; + subcommand = furi_string_alloc(); + if(!args_read_string_and_trim(args, subcommand) || furi_string_empty(args)) { updater_cli_help(args); - string_clear(subcommand); + furi_string_free(subcommand); return; } for(size_t idx = 0; idx < COUNT_OF(update_cli_subcommands); ++idx) { const CliSubcommand* subcmd_def = &update_cli_subcommands[idx]; - if(string_cmp_str(subcommand, subcmd_def->command) == 0) { - string_clear(subcommand); + if(furi_string_cmp_str(subcommand, subcmd_def->command) == 0) { + furi_string_free(subcommand); subcmd_def->handler(args); return; } } - string_clear(subcommand); + furi_string_free(subcommand); updater_cli_help(args); } diff --git a/applications/system/updater/scenes/updater_scene_loadcfg.c b/applications/system/updater/scenes/updater_scene_loadcfg.c index c7f48c78..14f7b203 100644 --- a/applications/system/updater/scenes/updater_scene_loadcfg.c +++ b/applications/system/updater/scenes/updater_scene_loadcfg.c @@ -25,7 +25,7 @@ void updater_scene_loadcfg_on_enter(void* context) { malloc(sizeof(UpdaterManifestProcessingState)); pending_upd->manifest = update_manifest_alloc(); - if(update_manifest_init(pending_upd->manifest, string_get_cstr(updater->startup_arg))) { + if(update_manifest_init(pending_upd->manifest, furi_string_get_cstr(updater->startup_arg))) { widget_add_string_element( updater->widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, "Update"); @@ -37,7 +37,7 @@ void updater_scene_loadcfg_on_enter(void* context) { 32, AlignCenter, AlignCenter, - string_get_cstr(pending_upd->manifest->version), + furi_string_get_cstr(pending_upd->manifest->version), true); widget_add_button_element( @@ -72,7 +72,7 @@ bool updater_scene_loadcfg_on_event(void* context, SceneManagerEvent event) { switch(event.event) { case UpdaterCustomEventStartUpdate: updater->preparation_result = - update_operation_prepare(string_get_cstr(updater->startup_arg)); + update_operation_prepare(furi_string_get_cstr(updater->startup_arg)); if(updater->preparation_result == UpdatePrepareResultOK) { furi_hal_power_reset(); } else { @@ -99,7 +99,7 @@ void updater_scene_loadcfg_on_exit(void* context) { if(updater->pending_update) { update_manifest_free(updater->pending_update->manifest); - string_clear(updater->pending_update->message); + furi_string_free(updater->pending_update->message); } widget_reset(updater->widget); diff --git a/applications/system/updater/updater.c b/applications/system/updater/updater.c index e9bedc72..e749f3ce 100644 --- a/applications/system/updater/updater.c +++ b/applications/system/updater/updater.c @@ -35,10 +35,10 @@ static void Updater* updater_alloc(const char* arg) { Updater* updater = malloc(sizeof(Updater)); if(arg && strlen(arg)) { - string_init_set_str(updater->startup_arg, arg); - string_replace_str(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); + updater->startup_arg = furi_string_alloc_set(arg); + furi_string_replace(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); } else { - string_init(updater->startup_arg); + updater->startup_arg = furi_string_alloc(); } updater->storage = furi_record_open(RECORD_STORAGE); @@ -94,7 +94,7 @@ Updater* updater_alloc(const char* arg) { void updater_free(Updater* updater) { furi_assert(updater); - string_clear(updater->startup_arg); + furi_string_free(updater->startup_arg); if(updater->update_task) { update_task_set_progress_cb(updater->update_task, NULL, NULL); update_task_free(updater->update_task); diff --git a/applications/system/updater/updater_i.h b/applications/system/updater/updater_i.h index 8a021a08..ae249f38 100644 --- a/applications/system/updater/updater_i.h +++ b/applications/system/updater/updater_i.h @@ -35,7 +35,7 @@ typedef enum { typedef struct UpdaterManifestProcessingState { UpdateManifest* manifest; - string_t message; + FuriString* message; bool ready_to_be_applied; } UpdaterManifestProcessingState; @@ -54,7 +54,7 @@ typedef struct { UpdateTask* update_task; Widget* widget; - string_t startup_arg; + FuriString* startup_arg; int32_t idle_ticks; } Updater; diff --git a/applications/system/updater/util/update_task.c b/applications/system/updater/util/update_task.c index b0477319..de172dd4 100644 --- a/applications/system/updater/util/update_task.c +++ b/applications/system/updater/util/update_task.c @@ -69,19 +69,19 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { static UpdateTaskStageGroup update_task_get_task_groups(UpdateTask* update_task) { UpdateTaskStageGroup ret = UpdateTaskStageGroupPreUpdate | UpdateTaskStageGroupPostUpdate; UpdateManifest* manifest = update_task->manifest; - if(!string_empty_p(manifest->radio_image)) { + if(!furi_string_empty(manifest->radio_image)) { ret |= UpdateTaskStageGroupRadio; } if(update_manifest_has_obdata(manifest)) { ret |= UpdateTaskStageGroupOptionBytes; } - if(!string_empty_p(manifest->firmware_dfu_image)) { + if(!furi_string_empty(manifest->firmware_dfu_image)) { ret |= UpdateTaskStageGroupFirmware; } - if(!string_empty_p(manifest->resource_bundle)) { + if(!furi_string_empty(manifest->resource_bundle)) { ret |= UpdateTaskStageGroupResources; } - if(!string_empty_p(manifest->splash_file)) { + if(!furi_string_empty(manifest->splash_file)) { ret |= UpdateTaskStageGroupSplashscreen; } return ret; @@ -109,14 +109,14 @@ void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, ui } /* Build error message with code "[stage_idx-stage_percent]" */ if(stage >= UpdateTaskStageError) { - string_printf( + furi_string_printf( update_task->state.status, "%s #[%d-%d]", update_task_stage_descr[stage], update_task->state.stage, update_task->state.stage_progress); } else { - string_set_str(update_task->state.status, update_task_stage_descr[stage]); + furi_string_set(update_task->state.status, update_task_stage_descr[stage]); } /* Store stage update */ update_task->state.stage = stage; @@ -149,7 +149,7 @@ void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, ui if(update_task->status_change_cb) { (update_task->status_change_cb)( - string_get_cstr(update_task->state.status), + furi_string_get_cstr(update_task->state.status), adapted_progress, update_stage_is_error(update_task->state.stage), update_task->status_change_cb_state); @@ -165,26 +165,26 @@ static void update_task_close_file(UpdateTask* update_task) { storage_file_close(update_task->file); } -static bool update_task_check_file_exists(UpdateTask* update_task, string_t filename) { +static bool update_task_check_file_exists(UpdateTask* update_task, FuriString* filename) { furi_assert(update_task); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(filename)); - bool exists = storage_file_exists(update_task->storage, string_get_cstr(tmp_path)); - string_clear(tmp_path); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(filename)); + bool exists = storage_file_exists(update_task->storage, furi_string_get_cstr(tmp_path)); + furi_string_free(tmp_path); return exists; } -bool update_task_open_file(UpdateTask* update_task, string_t filename) { +bool update_task_open_file(UpdateTask* update_task, FuriString* filename) { furi_assert(update_task); update_task_close_file(update_task); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(filename)); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(filename)); bool open_success = storage_file_open( - update_task->file, string_get_cstr(tmp_path), FSAM_READ, FSOM_OPEN_EXISTING); - string_clear(tmp_path); + update_task->file, furi_string_get_cstr(tmp_path), FSAM_READ, FSOM_OPEN_EXISTING); + furi_string_free(tmp_path); return open_success; } @@ -207,14 +207,14 @@ UpdateTask* update_task_alloc() { update_task->state.stage = UpdateTaskStageProgress; update_task->state.stage_progress = 0; update_task->state.overall_progress = 0; - string_init(update_task->state.status); + update_task->state.status = furi_string_alloc(); update_task->manifest = update_manifest_alloc(); update_task->storage = furi_record_open(RECORD_STORAGE); update_task->file = storage_file_alloc(update_task->storage); update_task->status_change_cb = NULL; update_task->boot_mode = furi_hal_rtc_get_boot_mode(); - string_init(update_task->update_path); + update_task->update_path = furi_string_alloc(); FuriThread* thread = update_task->thread = furi_thread_alloc(); @@ -246,7 +246,7 @@ void update_task_free(UpdateTask* update_task) { update_manifest_free(update_task->manifest); furi_record_close(RECORD_STORAGE); - string_clear(update_task->update_path); + furi_string_free(update_task->update_path); free(update_task); } @@ -261,8 +261,8 @@ bool update_task_parse_manifest(UpdateTask* update_task) { update_task_set_progress(update_task, UpdateTaskStageReadManifest, 0); bool result = false; - string_t manifest_path; - string_init(manifest_path); + FuriString* manifest_path; + manifest_path = furi_string_alloc(); do { update_task_set_progress(update_task, UpdateTaskStageProgress, 13); @@ -276,11 +276,11 @@ bool update_task_parse_manifest(UpdateTask* update_task) { break; } - path_extract_dirname(string_get_cstr(manifest_path), update_task->update_path); + path_extract_dirname(furi_string_get_cstr(manifest_path), update_task->update_path); update_task_set_progress(update_task, UpdateTaskStageProgress, 30); UpdateManifest* manifest = update_task->manifest; - if(!update_manifest_init(manifest, string_get_cstr(manifest_path))) { + if(!update_manifest_init(manifest, furi_string_get_cstr(manifest_path))) { break; } @@ -320,7 +320,7 @@ bool update_task_parse_manifest(UpdateTask* update_task) { result = true; } while(false); - string_clear(manifest_path); + furi_string_free(manifest_path); return result; } diff --git a/applications/system/updater/util/update_task.h b/applications/system/updater/util/update_task.h index ad8c5085..b3ac3f2f 100644 --- a/applications/system/updater/util/update_task.h +++ b/applications/system/updater/util/update_task.h @@ -8,7 +8,6 @@ extern "C" { #include #include -#include #define UPDATE_DELAY_OPERATION_OK 10 #define UPDATE_DELAY_OPERATION_ERROR INT_MAX @@ -59,7 +58,7 @@ typedef enum { typedef struct { UpdateTaskStage stage; uint8_t overall_progress, stage_progress; - string_t status; + FuriString* status; UpdateTaskStageGroup groups; uint32_t total_progress_points; uint32_t completed_stages_points; diff --git a/applications/system/updater/util/update_task_i.h b/applications/system/updater/util/update_task_i.h index 95c63f64..0dbeca5f 100644 --- a/applications/system/updater/util/update_task_i.h +++ b/applications/system/updater/util/update_task_i.h @@ -8,7 +8,7 @@ typedef struct UpdateTask { UpdateTaskState state; - string_t update_path; + FuriString* update_path; UpdateManifest* manifest; FuriThread* thread; Storage* storage; @@ -20,7 +20,7 @@ typedef struct UpdateTask { void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress); bool update_task_parse_manifest(UpdateTask* update_task); -bool update_task_open_file(UpdateTask* update_task, string_t filename); +bool update_task_open_file(UpdateTask* update_task, FuriString* filename); int32_t update_task_worker_flash_writer(void* context); int32_t update_task_worker_backup_restore(void* context); diff --git a/applications/system/updater/util/update_task_worker_backup.c b/applications/system/updater/util/update_task_worker_backup.c index 046be372..ce62da2a 100644 --- a/applications/system/updater/util/update_task_worker_backup.c +++ b/applications/system/updater/util/update_task_worker_backup.c @@ -22,19 +22,22 @@ static bool update_task_pre_update(UpdateTask* update_task) { bool success = false; - string_t backup_file_path; - string_init(backup_file_path); + FuriString* backup_file_path; + backup_file_path = furi_string_alloc(); path_concat( - string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, backup_file_path); + furi_string_get_cstr(update_task->update_path), + LFS_BACKUP_DEFAULT_FILENAME, + backup_file_path); update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); /* to avoid bootloops */ furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); - if((success = lfs_backup_create(update_task->storage, string_get_cstr(backup_file_path)))) { + if((success = + lfs_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate); } - string_clear(backup_file_path); + furi_string_free(backup_file_path); return success; } @@ -79,12 +82,12 @@ static void /* For this stage, first 30% of progress = cleanup */ (n_processed_files++ * 30) / (n_approx_file_entries + 1)); - string_t file_path; - string_init(file_path); - path_concat(STORAGE_EXT_PATH_PREFIX, string_get_cstr(entry_ptr->name), file_path); - FURI_LOG_D(TAG, "Removing %s", string_get_cstr(file_path)); - storage_simply_remove(update_task->storage, string_get_cstr(file_path)); - string_clear(file_path); + FuriString* file_path = furi_string_alloc(); + path_concat( + STORAGE_EXT_PATH_PREFIX, furi_string_get_cstr(entry_ptr->name), file_path); + FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path)); + storage_simply_remove(update_task->storage, furi_string_get_cstr(file_path)); + furi_string_free(file_path); } } } while(false); @@ -94,17 +97,19 @@ static void static bool update_task_post_update(UpdateTask* update_task) { bool success = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); TarArchive* archive = tar_archive_alloc(update_task->storage); do { path_concat( - string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, file_path); + furi_string_get_cstr(update_task->update_path), + LFS_BACKUP_DEFAULT_FILENAME, + file_path); update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); - CHECK_RESULT(lfs_backup_unpack(update_task->storage, string_get_cstr(file_path))); + CHECK_RESULT(lfs_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); if(update_task->state.groups & UpdateTaskStageGroupResources) { TarUnpackProgress progress = { @@ -115,13 +120,13 @@ static bool update_task_post_update(UpdateTask* update_task) { update_task_set_progress(update_task, UpdateTaskStageResourcesUpdate, 0); path_concat( - string_get_cstr(update_task->update_path), - string_get_cstr(update_task->manifest->resource_bundle), + furi_string_get_cstr(update_task->update_path), + furi_string_get_cstr(update_task->manifest->resource_bundle), file_path); tar_archive_set_file_callback(archive, update_task_resource_unpack_cb, &progress); CHECK_RESULT( - tar_archive_open(archive, string_get_cstr(file_path), TAR_OPEN_MODE_READ)); + tar_archive_open(archive, furi_string_get_cstr(file_path), TAR_OPEN_MODE_READ)); progress.total_files = tar_archive_get_entries_count(archive); if(progress.total_files > 0) { @@ -133,23 +138,23 @@ static bool update_task_post_update(UpdateTask* update_task) { if(update_task->state.groups & UpdateTaskStageGroupSplashscreen) { update_task_set_progress(update_task, UpdateTaskStageSplashscreenInstall, 0); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(update_task->manifest->splash_file)); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(update_task->manifest->splash_file)); if(storage_common_copy( update_task->storage, - string_get_cstr(tmp_path), + furi_string_get_cstr(tmp_path), INT_PATH(SLIDESHOW_FILE_NAME)) != FSE_OK) { // actually, not critical } - string_clear(tmp_path); + furi_string_free(tmp_path); update_task_set_progress(update_task, UpdateTaskStageSplashscreenInstall, 100); } success = true; } while(false); tar_archive_free(archive); - string_clear(file_path); + furi_string_free(file_path); return success; } diff --git a/applications/system/updater/views/updater_main.c b/applications/system/updater/views/updater_main.c index 72541b9a..8d6694d8 100644 --- a/applications/system/updater/views/updater_main.c +++ b/applications/system/updater/views/updater_main.c @@ -18,7 +18,7 @@ struct UpdaterMainView { static const uint8_t PROGRESS_RENDER_STEP = 1; /* percent, to limit rendering rate */ typedef struct { - string_t status; + FuriString* status; uint8_t progress, rendered_progress; bool failed; } UpdaterProgressModel; @@ -32,8 +32,8 @@ void updater_main_model_set_state( main_view->view, (UpdaterProgressModel * model) { model->failed = failed; model->progress = progress; - if(string_cmp_str(model->status, message)) { - string_set(model->status, message); + if(furi_string_cmp_str(model->status, message)) { + furi_string_set(model->status, message); model->rendered_progress = progress; return true; } @@ -80,7 +80,7 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 42, 16, AlignLeft, AlignTop, "Update Failed!"); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( - canvas, 42, 32, AlignLeft, AlignTop, string_get_cstr(model->status)); + canvas, 42, 32, AlignLeft, AlignTop, furi_string_get_cstr(model->status)); canvas_draw_icon(canvas, 7, 16, &I_Warning_30x23); canvas_draw_str_aligned( @@ -91,7 +91,7 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 55, 14, AlignLeft, AlignTop, "UPDATING"); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( - canvas, 64, 51, AlignCenter, AlignTop, string_get_cstr(model->status)); + canvas, 64, 51, AlignCenter, AlignTop, furi_string_get_cstr(model->status)); canvas_draw_icon(canvas, 4, 5, &I_Updating_32x40); elements_progress_bar(canvas, 42, 29, 80, (float)model->progress / 100); } @@ -105,7 +105,7 @@ UpdaterMainView* updater_main_alloc() { with_view_model( main_view->view, (UpdaterProgressModel * model) { - string_init_set(model->status, "Waiting for SD card"); + model->status = furi_string_alloc_set("Waiting for SD card"); return true; }); @@ -120,7 +120,7 @@ void updater_main_free(UpdaterMainView* main_view) { furi_assert(main_view); with_view_model( main_view->view, (UpdaterProgressModel * model) { - string_clear(model->status); + furi_string_free(model->status); return false; }); view_free(main_view->view); diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index 36204829..722a7b61 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -54,20 +54,21 @@ static bool flipper_update_init() { return flipper_update_mount_sd(); } -static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* manifest) { +static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest* manifest) { FIL file; FILINFO stat; - string_t loader_img_path; - string_init_set(loader_img_path, work_dir); - path_append(loader_img_path, string_get_cstr(manifest->staged_loader_file)); + FuriString* loader_img_path; + loader_img_path = furi_string_alloc_set(work_dir); + path_append(loader_img_path, furi_string_get_cstr(manifest->staged_loader_file)); - if((f_stat(string_get_cstr(loader_img_path), &stat) != FR_OK) || - (f_open(&file, string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) != FR_OK)) { - string_clear(loader_img_path); + if((f_stat(furi_string_get_cstr(loader_img_path), &stat) != FR_OK) || + (f_open(&file, furi_string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) != + FR_OK)) { + furi_string_free(loader_img_path); return false; } - string_clear(loader_img_path); + furi_string_free(loader_img_path); void* img = malloc(stat.fsize); uint32_t bytes_read = 0; @@ -110,13 +111,13 @@ static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* m return false; } -static bool flipper_update_get_manifest_path(string_t out_path) { +static bool flipper_update_get_manifest_path(FuriString* out_path) { FIL file; FILINFO stat; uint16_t size_read = 0; char manifest_name_buf[UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN] = {0}; - string_reset(out_path); + furi_string_reset(out_path); CHECK_FRESULT(f_stat(UPDATE_POINTER_FILE_PATH, &stat)); CHECK_FRESULT(f_open(&file, UPDATE_POINTER_FILE_PATH, FA_OPEN_EXISTING | FA_READ)); do { @@ -128,19 +129,19 @@ static bool flipper_update_get_manifest_path(string_t out_path) { if((size_read == 0) || (size_read == UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN)) { break; } - string_set_str(out_path, manifest_name_buf); - string_right(out_path, strlen(STORAGE_EXT_PATH_PREFIX)); + furi_string_set(out_path, manifest_name_buf); + furi_string_right(out_path, strlen(STORAGE_EXT_PATH_PREFIX)); } while(0); f_close(&file); - return !string_empty_p(out_path); + return !furi_string_empty(out_path); } -static UpdateManifest* flipper_update_process_manifest(const string_t manifest_path) { +static UpdateManifest* flipper_update_process_manifest(const FuriString* manifest_path) { FIL file; FILINFO stat; - CHECK_FRESULT(f_stat(string_get_cstr(manifest_path), &stat)); - CHECK_FRESULT(f_open(&file, string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); + CHECK_FRESULT(f_stat(furi_string_get_cstr(manifest_path), &stat)); + CHECK_FRESULT(f_open(&file, furi_string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); uint8_t* manifest_data = malloc(stat.fsize); uint32_t bytes_read = 0; @@ -177,9 +178,9 @@ void flipper_boot_update_exec() { return; } - string_t work_dir, manifest_path; - string_init(work_dir); - string_init(manifest_path); + FuriString* work_dir = furi_string_alloc(); + FuriString* manifest_path = furi_string_alloc(); + do { if(!flipper_update_get_manifest_path(manifest_path)) { break; @@ -190,12 +191,12 @@ void flipper_boot_update_exec() { break; } - path_extract_dirname(string_get_cstr(manifest_path), work_dir); + path_extract_dirname(furi_string_get_cstr(manifest_path), work_dir); if(!flipper_update_load_stage(work_dir, manifest)) { update_manifest_free(manifest); } } while(false); - string_clear(manifest_path); - string_clear(work_dir); + furi_string_free(manifest_path); + furi_string_free(work_dir); free(pfs); } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 2cbdae77..a140ff0b 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,1.13,, +Version,+,2.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -440,12 +440,12 @@ Function,-,arc4random,__uint32_t, Function,-,arc4random_buf,void,"void*, size_t" Function,-,arc4random_uniform,__uint32_t,__uint32_t Function,+,args_char_to_hex,_Bool,"char, char, uint8_t*" -Function,+,args_get_first_word_length,size_t,string_t -Function,+,args_length,size_t,string_t -Function,+,args_read_hex_bytes,_Bool,"string_t, uint8_t*, size_t" -Function,+,args_read_int_and_trim,_Bool,"string_t, int*" -Function,+,args_read_probably_quoted_string_and_trim,_Bool,"string_t, string_t" -Function,+,args_read_string_and_trim,_Bool,"string_t, string_t" +Function,+,args_get_first_word_length,size_t,FuriString* +Function,+,args_length,size_t,FuriString* +Function,+,args_read_hex_bytes,_Bool,"FuriString*, uint8_t*, size_t" +Function,+,args_read_int_and_trim,_Bool,"FuriString*, int*" +Function,+,args_read_probably_quoted_string_and_trim,_Bool,"FuriString*, FuriString*" +Function,+,args_read_string_and_trim,_Bool,"FuriString*, FuriString*" Function,-,asin,double,double Function,-,asinf,float,float Function,-,asinh,double,double @@ -642,7 +642,7 @@ Function,+,dialog_ex_set_result_callback,void,"DialogEx*, DialogExResultCallback Function,+,dialog_ex_set_right_button_text,void,"DialogEx*, const char*" Function,+,dialog_ex_set_text,void,"DialogEx*, const char*, uint8_t, uint8_t, Align, Align" Function,+,dialog_file_browser_set_basic_options,void,"DialogsFileBrowserOptions*, const char*, const Icon*" -Function,+,dialog_file_browser_show,_Bool,"DialogsApp*, string_ptr, string_ptr, const DialogsFileBrowserOptions*" +Function,+,dialog_file_browser_show,_Bool,"DialogsApp*, FuriString*, FuriString*, const DialogsFileBrowserOptions*" Function,+,dialog_message_alloc,DialogMessage*, Function,+,dialog_message_free,void,DialogMessage* Function,+,dialog_message_set_buttons,void,"DialogMessage*, const char*, const char*, const char*" @@ -665,7 +665,7 @@ Function,+,dir_walk_close,void,DirWalk* Function,+,dir_walk_free,void,DirWalk* Function,+,dir_walk_get_error,FS_Error,DirWalk* Function,+,dir_walk_open,_Bool,"DirWalk*, const char*" -Function,+,dir_walk_read,DirWalkResult,"DirWalk*, string_t, FileInfo*" +Function,+,dir_walk_read,DirWalkResult,"DirWalk*, FuriString*, FileInfo*" Function,+,dir_walk_set_filter_cb,void,"DirWalk*, DirWalkFilterCb, void*" Function,+,dir_walk_set_recursive,void,"DirWalk*, _Bool" Function,-,div,div_t,"int, int" @@ -698,7 +698,7 @@ Function,+,elements_scrollbar,void,"Canvas*, uint16_t, uint16_t" Function,+,elements_scrollbar_pos,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint16_t, uint16_t" Function,+,elements_slightly_rounded_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t" Function,+,elements_slightly_rounded_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t" -Function,+,elements_string_fit_width,void,"Canvas*, string_t, uint8_t" +Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, uint8_t" Function,+,elements_text_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool" Function,+,empty_screen_alloc,EmptyScreen*, Function,+,empty_screen_free,void,EmptyScreen* @@ -746,22 +746,22 @@ Function,-,fgetc_unlocked,int,FILE* Function,-,fgetpos,int,"FILE*, fpos_t*" Function,-,fgets,char*,"char*, int, FILE*" Function,-,fgets_unlocked,char*,"char*, int, FILE*" -Function,+,file_browser_alloc,FileBrowser*,string_ptr +Function,+,file_browser_alloc,FileBrowser*,FuriString* Function,+,file_browser_configure,void,"FileBrowser*, const char*, _Bool, const Icon*, _Bool" Function,+,file_browser_free,void,FileBrowser* Function,+,file_browser_get_view,View*,FileBrowser* Function,+,file_browser_set_callback,void,"FileBrowser*, FileBrowserCallback, void*" Function,+,file_browser_set_item_callback,void,"FileBrowser*, FileBrowserLoadItemCallback, void*" -Function,+,file_browser_start,void,"FileBrowser*, string_t" +Function,+,file_browser_start,void,"FileBrowser*, FuriString*" Function,+,file_browser_stop,void,FileBrowser* -Function,+,file_browser_worker_alloc,BrowserWorker*,"string_t, const char*, _Bool" -Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, string_t, int32_t" +Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, _Bool" +Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, int32_t" Function,+,file_browser_worker_folder_exit,void,BrowserWorker* Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" Function,+,file_browser_worker_free,void,BrowserWorker* Function,+,file_browser_worker_load,void,"BrowserWorker*, uint32_t, uint32_t" Function,+,file_browser_worker_set_callback_context,void,"BrowserWorker*, void*" -Function,+,file_browser_worker_set_config,void,"BrowserWorker*, string_t, const char*, _Bool" +Function,+,file_browser_worker_set_config,void,"BrowserWorker*, FuriString*, const char*, _Bool" Function,+,file_browser_worker_set_folder_callback,void,"BrowserWorker*, BrowserWorkerFolderOpenCallback" Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback" Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback" @@ -806,17 +806,17 @@ Function,+,flipper_format_insert_or_update_bool,_Bool,"FlipperFormat*, const cha Function,+,flipper_format_insert_or_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" Function,+,flipper_format_insert_or_update_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_insert_or_update_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_insert_or_update_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_insert_or_update_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_insert_or_update_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_insert_or_update_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,+,flipper_format_key_exist,_Bool,"FlipperFormat*, const char*" Function,+,flipper_format_read_bool,_Bool,"FlipperFormat*, const char*, _Bool*, const uint16_t" Function,+,flipper_format_read_float,_Bool,"FlipperFormat*, const char*, float*, const uint16_t" -Function,+,flipper_format_read_header,_Bool,"FlipperFormat*, string_t, uint32_t*" +Function,+,flipper_format_read_header,_Bool,"FlipperFormat*, FuriString*, uint32_t*" Function,+,flipper_format_read_hex,_Bool,"FlipperFormat*, const char*, uint8_t*, const uint16_t" Function,+,flipper_format_read_hex_uint64,_Bool,"FlipperFormat*, const char*, uint64_t*, const uint16_t" Function,+,flipper_format_read_int32,_Bool,"FlipperFormat*, const char*, int32_t*, const uint16_t" -Function,+,flipper_format_read_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_read_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32_t*, const uint16_t" Function,+,flipper_format_rewind,_Bool,FlipperFormat* Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat* @@ -826,19 +826,19 @@ Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" Function,+,flipper_format_update_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_update_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_update_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_update_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_update_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_update_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,+,flipper_format_write_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t" -Function,+,flipper_format_write_comment,_Bool,"FlipperFormat*, string_t" +Function,+,flipper_format_write_comment,_Bool,"FlipperFormat*, FuriString*" Function,+,flipper_format_write_comment_cstr,_Bool,"FlipperFormat*, const char*" Function,+,flipper_format_write_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" -Function,+,flipper_format_write_header,_Bool,"FlipperFormat*, string_t, const uint32_t" +Function,+,flipper_format_write_header,_Bool,"FlipperFormat*, FuriString*, const uint32_t" Function,+,flipper_format_write_header_cstr,_Bool,"FlipperFormat*, const char*, const uint32_t" Function,+,flipper_format_write_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_write_hex_uint64,_Bool,"FlipperFormat*, const char*, const uint64_t*, const uint16_t" Function,+,flipper_format_write_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_write_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_write_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_write_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_write_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,-,flockfile,void,FILE* @@ -899,7 +899,7 @@ Function,+,furi_event_flag_wait,uint32_t,"FuriEventFlag*, uint32_t, uint32_t, ui Function,+,furi_get_tick,uint32_t, Function,+,furi_hal_bt_change_app,_Bool,"FuriHalBtProfile, GapEventCallback, void*" Function,+,furi_hal_bt_clear_white_list,_Bool, -Function,+,furi_hal_bt_dump_state,void,string_t +Function,+,furi_hal_bt_dump_state,void,FuriString* Function,+,furi_hal_bt_ensure_c2_mode,_Bool,BleGlueC2Mode Function,+,furi_hal_bt_get_key_storage_buff,void,"uint8_t**, uint16_t*" Function,+,furi_hal_bt_get_radio_stack,FuriHalBtStack, @@ -1342,6 +1342,60 @@ Function,+,furi_semaphore_alloc,FuriSemaphore*,"uint32_t, uint32_t" Function,+,furi_semaphore_free,void,FuriSemaphore* Function,+,furi_semaphore_get_count,uint32_t,FuriSemaphore* Function,+,furi_semaphore_release,FuriStatus,FuriSemaphore* +Function,+,furi_string_alloc,FuriString*, +Function,+,furi_string_alloc_move,FuriString*,FuriString* +Function,+,furi_string_alloc_printf,FuriString*,"const char[], ..." +Function,+,furi_string_alloc_set,FuriString*,const FuriString* +Function,+,furi_string_alloc_set_str,FuriString*,const char[] +Function,+,furi_string_alloc_vprintf,FuriString*,"const char[], va_list" +Function,+,furi_string_cat,void,"FuriString*, const FuriString*" +Function,+,furi_string_cat_printf,int,"FuriString*, const char[], ..." +Function,+,furi_string_cat_str,void,"FuriString*, const char[]" +Function,+,furi_string_cat_vprintf,int,"FuriString*, const char[], va_list" +Function,+,furi_string_cmp,int,"const FuriString*, const FuriString*" +Function,+,furi_string_cmp_str,int,"const FuriString*, const char[]" +Function,+,furi_string_cmpi,int,"const FuriString*, const FuriString*" +Function,+,furi_string_cmpi_str,int,"const FuriString*, const char[]" +Function,+,furi_string_empty,_Bool,const FuriString* +Function,+,furi_string_end_with,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_end_with_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_equal,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_equal_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_free,void,FuriString* +Function,+,furi_string_get_char,char,"const FuriString*, size_t" +Function,+,furi_string_get_cstr,const char*,const FuriString* +Function,+,furi_string_hash,size_t,const FuriString* +Function,+,furi_string_left,void,"FuriString*, size_t" +Function,+,furi_string_mid,void,"FuriString*, size_t, size_t" +Function,+,furi_string_move,void,"FuriString*, FuriString*" +Function,+,furi_string_printf,int,"FuriString*, const char[], ..." +Function,+,furi_string_push_back,void,"FuriString*, char" +Function,+,furi_string_replace,size_t,"FuriString*, FuriString*, FuriString*, size_t" +Function,+,furi_string_replace_all,void,"FuriString*, const FuriString*, const FuriString*" +Function,+,furi_string_replace_all_str,void,"FuriString*, const char[], const char[]" +Function,+,furi_string_replace_at,void,"FuriString*, size_t, size_t, const char[]" +Function,+,furi_string_replace_str,size_t,"FuriString*, const char[], const char[], size_t" +Function,+,furi_string_reserve,void,"FuriString*, size_t" +Function,+,furi_string_reset,void,FuriString* +Function,+,furi_string_right,void,"FuriString*, size_t" +Function,+,furi_string_search,size_t,"const FuriString*, const FuriString*, size_t" +Function,+,furi_string_search_char,size_t,"const FuriString*, char, size_t" +Function,+,furi_string_search_rchar,size_t,"const FuriString*, char, size_t" +Function,+,furi_string_search_str,size_t,"const FuriString*, const char[], size_t" +Function,+,furi_string_set,void,"FuriString*, FuriString*" +Function,+,furi_string_set_char,void,"FuriString*, size_t, const char" +Function,+,furi_string_set_n,void,"FuriString*, const FuriString*, size_t, size_t" +Function,+,furi_string_set_str,void,"FuriString*, const char[]" +Function,+,furi_string_set_strn,void,"FuriString*, const char[], size_t" +Function,+,furi_string_size,size_t,const FuriString* +Function,+,furi_string_start_with,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_start_with_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_swap,void,"FuriString*, FuriString*" +Function,+,furi_string_trim,void,"FuriString*, const char[]" +Function,+,furi_string_utf8_decode,void,"char, FuriStringUTF8State*, FuriStringUnicodeValue*" +Function,+,furi_string_utf8_length,size_t,FuriString* +Function,+,furi_string_utf8_push,void,"FuriString*, FuriStringUnicodeValue" +Function,+,furi_string_vprintf,int,"FuriString*, const char[], va_list" Function,+,furi_thread_alloc,FuriThread*, Function,+,furi_thread_catch,void, Function,-,furi_thread_disable_heap_trace,void,FuriThread* @@ -1684,14 +1738,14 @@ Function,+,onewire_slave_set_result_callback,void,"OneWireSlave*, OneWireSlaveRe Function,+,onewire_slave_start,void,OneWireSlave* Function,+,onewire_slave_stop,void,OneWireSlave* Function,-,open_memstream,FILE*,"char**, size_t*" -Function,+,path_append,void,"string_t, const char*" -Function,+,path_concat,void,"const char*, const char*, string_t" +Function,+,path_append,void,"FuriString*, const char*" +Function,+,path_concat,void,"const char*, const char*, FuriString*" Function,+,path_contains_only_ascii,_Bool,const char* -Function,+,path_extract_basename,void,"const char*, string_t" -Function,+,path_extract_dirname,void,"const char*, string_t" -Function,+,path_extract_extension,void,"string_t, char*, size_t" -Function,+,path_extract_filename,void,"string_t, string_t, _Bool" -Function,+,path_extract_filename_no_ext,void,"const char*, string_t" +Function,+,path_extract_basename,void,"const char*, FuriString*" +Function,+,path_extract_dirname,void,"const char*, FuriString*" +Function,+,path_extract_extension,void,"FuriString*, char*, size_t" +Function,+,path_extract_filename,void,"FuriString*, FuriString*, _Bool" +Function,+,path_extract_filename_no_ext,void,"const char*, FuriString*" Function,-,pcTaskGetName,char*,TaskHandle_t Function,-,pcTimerGetName,const char*,TimerHandle_t Function,-,pclose,int,FILE* @@ -1745,8 +1799,8 @@ Function,+,protocol_dict_get_name,const char*,"ProtocolDict*, size_t" Function,+,protocol_dict_get_protocol_by_name,ProtocolId,"ProtocolDict*, const char*" Function,+,protocol_dict_get_validate_count,uint32_t,"ProtocolDict*, size_t" Function,+,protocol_dict_get_write_data,_Bool,"ProtocolDict*, size_t, void*" -Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, string_t, size_t" -Function,+,protocol_dict_render_data,void,"ProtocolDict*, string_t, size_t" +Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, FuriString*, size_t" +Function,+,protocol_dict_render_data,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_set_data,void,"ProtocolDict*, size_t, const uint8_t*, size_t" Function,-,pselect,int,"int, fd_set*, fd_set*, fd_set*, const timespec*, const sigset_t*" Function,-,putc,int,"int, FILE*" @@ -2073,7 +2127,7 @@ Function,-,storage_file_sync,_Bool,File* Function,+,storage_file_tell,uint64_t,File* Function,+,storage_file_truncate,_Bool,File* Function,+,storage_file_write,uint16_t,"File*, const void*, uint16_t" -Function,+,storage_get_next_filename,void,"Storage*, const char*, const char*, const char*, string_t, uint8_t" +Function,+,storage_get_next_filename,void,"Storage*, const char*, const char*, const char*, FuriString*, uint8_t" Function,+,storage_get_pubsub,FuriPubSub*,Storage* Function,+,storage_int_backup,FS_Error,"Storage*, const char*" Function,+,storage_int_restore,FS_Error,"Storage*, const char*, Storage_name_converter" @@ -2106,7 +2160,7 @@ Function,+,stream_delete_and_insert,_Bool,"Stream*, size_t, StreamWriteCB, const Function,+,stream_delete_and_insert_char,_Bool,"Stream*, size_t, char" Function,+,stream_delete_and_insert_cstring,_Bool,"Stream*, size_t, const char*" Function,+,stream_delete_and_insert_format,_Bool,"Stream*, size_t, const char*, ..." -Function,+,stream_delete_and_insert_string,_Bool,"Stream*, size_t, string_t" +Function,+,stream_delete_and_insert_string,_Bool,"Stream*, size_t, FuriString*" Function,+,stream_delete_and_insert_vaformat,_Bool,"Stream*, size_t, const char*, va_list" Function,+,stream_dump_data,void,Stream* Function,+,stream_eof,_Bool,Stream* @@ -2115,11 +2169,11 @@ Function,+,stream_insert,_Bool,"Stream*, const uint8_t*, size_t" Function,+,stream_insert_char,_Bool,"Stream*, char" Function,+,stream_insert_cstring,_Bool,"Stream*, const char*" Function,+,stream_insert_format,_Bool,"Stream*, const char*, ..." -Function,+,stream_insert_string,_Bool,"Stream*, string_t" +Function,+,stream_insert_string,_Bool,"Stream*, FuriString*" Function,+,stream_insert_vaformat,_Bool,"Stream*, const char*, va_list" Function,+,stream_load_from_file,size_t,"Stream*, Storage*, const char*" Function,+,stream_read,size_t,"Stream*, uint8_t*, size_t" -Function,+,stream_read_line,_Bool,"Stream*, string_t" +Function,+,stream_read_line,_Bool,"Stream*, FuriString*" Function,+,stream_rewind,_Bool,Stream* Function,+,stream_save_to_file,size_t,"Stream*, Storage*, const char*, FS_OpenMode" Function,+,stream_seek,_Bool,"Stream*, int32_t, StreamOffset" @@ -2130,7 +2184,7 @@ Function,+,stream_write,size_t,"Stream*, const uint8_t*, size_t" Function,+,stream_write_char,size_t,"Stream*, char" Function,+,stream_write_cstring,size_t,"Stream*, const char*" Function,+,stream_write_format,size_t,"Stream*, const char*, ..." -Function,+,stream_write_string,size_t,"Stream*, string_t" +Function,+,stream_write_string,size_t,"Stream*, FuriString*" Function,+,stream_write_vaformat,size_t,"Stream*, const char*, va_list" Function,-,strerror,char*,int Function,-,strerror_l,char*,"int, locale_t" @@ -2191,14 +2245,14 @@ Function,-,subghz_keystore_raw_get_data,_Bool,"const char*, size_t, uint8_t*, si Function,-,subghz_keystore_save,_Bool,"SubGhzKeystore*, const char*, uint8_t*" Function,-,subghz_protocol_decoder_base_deserialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*" Function,-,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase* -Function,-,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, string_t" +Function,-,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*" Function,+,subghz_protocol_decoder_base_serialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzPresetDefinition*" Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*" Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*" Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t" Function,+,subghz_protocol_decoder_raw_free,void,void* -Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, string_t" +Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*" Function,+,subghz_protocol_decoder_raw_reset,void,void* Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_encoder_raw_deserialize,_Bool,"void*, FlipperFormat*" @@ -2389,7 +2443,7 @@ Function,-,vTimerSetReloadMode,void,"TimerHandle_t, const UBaseType_t" Function,-,vTimerSetTimerID,void,"TimerHandle_t, void*" Function,-,vTimerSetTimerNumber,void,"TimerHandle_t, UBaseType_t" Function,+,validator_is_file_alloc_init,ValidatorIsFile*,"const char*, const char*, const char*" -Function,+,validator_is_file_callback,_Bool,"const char*, string_t, void*" +Function,+,validator_is_file_callback,_Bool,"const char*, FuriString*, void*" Function,+,validator_is_file_free,void,ValidatorIsFile* Function,+,variable_item_get_context,void*,VariableItem* Function,+,variable_item_get_current_value_index,uint8_t,VariableItem* diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c index ecfa08b1..8bdb2eea 100755 --- a/firmware/targets/f7/ble_glue/dev_info_service.c +++ b/firmware/targets/f7/ble_glue/dev_info_service.c @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -16,7 +15,7 @@ typedef struct { uint16_t firmware_rev_char_handle; uint16_t software_rev_char_handle; uint16_t rpc_version_char_handle; - string_t version_string; + FuriString* version_string; char hardware_revision[4]; } DevInfoSvc; @@ -31,8 +30,7 @@ static const uint8_t dev_info_rpc_version_uuid[] = void dev_info_svc_start() { dev_info_svc = malloc(sizeof(DevInfoSvc)); - string_init_printf( - dev_info_svc->version_string, + dev_info_svc->version_string = furi_string_alloc_printf( "%s %s %s %s", version_get_githash(NULL), version_get_gitbranch(NULL), @@ -104,7 +102,7 @@ void dev_info_svc_start() { dev_info_svc->service_handle, UUID_TYPE_16, (Char_UUID_t*)&uuid, - string_size(dev_info_svc->version_string), + furi_string_size(dev_info_svc->version_string), CHAR_PROP_READ, ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, @@ -161,8 +159,8 @@ void dev_info_svc_start() { dev_info_svc->service_handle, dev_info_svc->software_rev_char_handle, 0, - string_size(dev_info_svc->version_string), - (uint8_t*)string_get_cstr(dev_info_svc->version_string)); + furi_string_size(dev_info_svc->version_string), + (uint8_t*)furi_string_get_cstr(dev_info_svc->version_string)); if(status) { FURI_LOG_E(TAG, "Failed to update software revision char: %d", status); } @@ -180,7 +178,7 @@ void dev_info_svc_start() { void dev_info_svc_stop() { tBleStatus status; if(dev_info_svc) { - string_clear(dev_info_svc->version_string); + furi_string_free(dev_info_svc->version_string); // Delete service characteristics status = aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->man_name_char_handle); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 1a2b436d..fc1c25c7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -340,7 +340,7 @@ bool furi_hal_bt_clear_white_list() { return status != BLE_STATUS_SUCCESS; } -void furi_hal_bt_dump_state(string_t buffer) { +void furi_hal_bt_dump_state(FuriString* buffer) { if(furi_hal_bt_is_alive()) { uint8_t HCI_Version; uint16_t HCI_Revision; @@ -351,7 +351,7 @@ void furi_hal_bt_dump_state(string_t buffer) { tBleStatus ret = hci_read_local_version_information( &HCI_Version, &HCI_Revision, &LMP_PAL_Version, &Manufacturer_Name, &LMP_PAL_Subversion); - string_cat_printf( + furi_string_cat_printf( buffer, "Ret: %d, HCI_Version: %d, HCI_Revision: %d, LMP_PAL_Version: %d, Manufacturer_Name: %d, LMP_PAL_Subversion: %d", ret, @@ -361,7 +361,7 @@ void furi_hal_bt_dump_state(string_t buffer) { Manufacturer_Name, LMP_PAL_Subversion); } else { - string_cat_printf(buffer, "BLE not ready"); + furi_string_cat_printf(buffer, "BLE not ready"); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.c b/firmware/targets/f7/furi_hal/furi_hal_console.c index e5db927b..2bdc5725 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.c +++ b/firmware/targets/f7/furi_hal/furi_hal_console.c @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -88,13 +87,13 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size } void furi_hal_console_printf(const char format[], ...) { - string_t string; + FuriString* string; va_list args; va_start(args, format); - string_init_vprintf(string, format, args); + string = furi_string_alloc_vprintf(format, args); va_end(args); - furi_hal_console_tx((const uint8_t*)string_get_cstr(string), string_size(string)); - string_clear(string); + furi_hal_console_tx((const uint8_t*)furi_string_get_cstr(string), furi_string_size(string)); + furi_string_free(string); } void furi_hal_console_puts(const char* data) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index 25ea42bb..15ce41a2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -5,12 +5,12 @@ #include #include -#include +#include #include void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); // Device Info version out("device_info_major", "2", false, context); @@ -20,36 +20,36 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("hardware_model", furi_hal_version_get_model_name(), false, context); // Unique ID - string_reset(value); + furi_string_reset(value); const uint8_t* uid = furi_hal_version_uid(); for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { - string_cat_printf(value, "%02X", uid[i]); + furi_string_cat_printf(value, "%02X", uid[i]); } - out("hardware_uid", string_get_cstr(value), false, context); + out("hardware_uid", furi_string_get_cstr(value), false, context); // OTP Revision - string_printf(value, "%d", furi_hal_version_get_otp_version()); - out("hardware_otp_ver", string_get_cstr(value), false, context); - string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); - out("hardware_timestamp", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_otp_version()); + out("hardware_otp_ver", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); + out("hardware_timestamp", furi_string_get_cstr(value), false, context); // Board Revision - string_printf(value, "%d", furi_hal_version_get_hw_version()); - out("hardware_ver", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_target()); - out("hardware_target", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_body()); - out("hardware_body", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_connect()); - out("hardware_connect", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_display()); - out("hardware_display", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_version()); + out("hardware_ver", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_target()); + out("hardware_target", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_body()); + out("hardware_body", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_connect()); + out("hardware_connect", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_display()); + out("hardware_display", furi_string_get_cstr(value), false, context); // Board Personification - string_printf(value, "%d", furi_hal_version_get_hw_color()); - out("hardware_color", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_region()); - out("hardware_region", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_color()); + out("hardware_color", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_region()); + out("hardware_region", furi_string_get_cstr(value), false, context); out("hardware_region_provisioned", furi_hal_region_get_name(), false, context); const char* name = furi_hal_version_get_name_ptr(); if(name) { @@ -68,8 +68,8 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("firmware_branch_num", version_get_gitbranchnum(firmware_version), false, context); out("firmware_version", version_get_version(firmware_version), false, context); out("firmware_build_date", version_get_builddate(firmware_version), false, context); - string_printf(value, "%d", version_get_target(firmware_version)); - out("firmware_target", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", version_get_target(firmware_version)); + out("firmware_target", furi_string_get_cstr(value), false, context); } if(furi_hal_bt_is_alive()) { @@ -78,64 +78,64 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("radio_mode", ble_c2_info->mode == BleGlueC2ModeFUS ? "FUS" : "Stack", false, context); // FUS Info - string_printf(value, "%d", ble_c2_info->FusVersionMajor); - out("radio_fus_major", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->FusVersionMinor); - out("radio_fus_minor", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->FusVersionSub); - out("radio_fus_sub", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2B); - out("radio_fus_sram2b", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2A); - out("radio_fus_sram2a", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeFlash * 4); - out("radio_fus_flash", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionMajor); + out("radio_fus_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionMinor); + out("radio_fus_minor", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionSub); + out("radio_fus_sub", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2B); + out("radio_fus_sram2b", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2A); + out("radio_fus_sram2a", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeFlash * 4); + out("radio_fus_flash", furi_string_get_cstr(value), false, context); // Stack Info - string_printf(value, "%d", ble_c2_info->StackType); - out("radio_stack_type", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionMajor); - out("radio_stack_major", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionMinor); - out("radio_stack_minor", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionSub); - out("radio_stack_sub", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionBranch); - out("radio_stack_branch", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionReleaseType); - out("radio_stack_release", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram2B); - out("radio_stack_sram2b", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram2A); - out("radio_stack_sram2a", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram1); - out("radio_stack_sram1", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeFlash * 4); - out("radio_stack_flash", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->StackType); + out("radio_stack_type", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionMajor); + out("radio_stack_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionMinor); + out("radio_stack_minor", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionSub); + out("radio_stack_sub", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionBranch); + out("radio_stack_branch", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionReleaseType); + out("radio_stack_release", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram2B); + out("radio_stack_sram2b", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram2A); + out("radio_stack_sram2a", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram1); + out("radio_stack_sram1", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeFlash * 4); + out("radio_stack_flash", furi_string_get_cstr(value), false, context); // Mac address - string_reset(value); + furi_string_reset(value); const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); for(size_t i = 0; i < 6; i++) { - string_cat_printf(value, "%02X", ble_mac[i]); + furi_string_cat_printf(value, "%02X", ble_mac[i]); } - out("radio_ble_mac", string_get_cstr(value), false, context); + out("radio_ble_mac", furi_string_get_cstr(value), false, context); // Signature verification uint8_t enclave_keys = 0; uint8_t enclave_valid_keys = 0; bool enclave_valid = furi_hal_crypto_verify_enclave(&enclave_keys, &enclave_valid_keys); - string_printf(value, "%d", enclave_valid_keys); - out("enclave_valid_keys", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", enclave_valid_keys); + out("enclave_valid_keys", furi_string_get_cstr(value), false, context); out("enclave_valid", enclave_valid ? "true" : "false", false, context); } else { out("radio_alive", "false", false, context); } - string_printf(value, "%u", PROTOBUF_MAJOR_VERSION); - out("protobuf_version_major", string_get_cstr(value), false, context); - string_printf(value, "%u", PROTOBUF_MINOR_VERSION); - out("protobuf_version_minor", string_get_cstr(value), true, context); + furi_string_printf(value, "%u", PROTOBUF_MAJOR_VERSION); + out("protobuf_version_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%u", PROTOBUF_MINOR_VERSION); + out("protobuf_version_minor", furi_string_get_cstr(value), true, context); - string_clear(value); + furi_string_free(value); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index de67bbc3..069ac4ea 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -743,7 +742,8 @@ void furi_hal_nfc_sleep() { rfalLowPowerModeStart(); } -FuriHalNfcReturn furi_hal_nfc_ll_set_mode(FuriHalNfcMode mode, FuriHalNfcBitrate txBR, FuriHalNfcBitrate rxBR) { +FuriHalNfcReturn + furi_hal_nfc_ll_set_mode(FuriHalNfcMode mode, FuriHalNfcBitrate txBR, FuriHalNfcBitrate rxBR) { return rfalSetMode((rfalMode)mode, (rfalBitRate)txBR, (rfalBitRate)rxBR); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 524fae0b..bc98f108 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -529,8 +529,8 @@ void furi_hal_power_suppress_charge_exit() { void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { furi_assert(out); - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); // Power Info version out("power_info_major", "1", false, context); @@ -538,45 +538,45 @@ void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { uint8_t charge = furi_hal_power_get_pct(); - string_printf(value, "%u", charge); - out("charge_level", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", charge); + out("charge_level", furi_string_get_cstr(value), false, context); if(furi_hal_power_is_charging()) { if(charge < 100) { - string_printf(value, "charging"); + furi_string_printf(value, "charging"); } else { - string_printf(value, "charged"); + furi_string_printf(value, "charged"); } } else { - string_printf(value, "discharging"); + furi_string_printf(value, "discharging"); } - out("charge_state", string_get_cstr(value), false, context); + out("charge_state", furi_string_get_cstr(value), false, context); uint16_t voltage = (uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f); - string_printf(value, "%u", voltage); - out("battery_voltage", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", voltage); + out("battery_voltage", furi_string_get_cstr(value), false, context); int16_t current = (int16_t)(furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge) * 1000.f); - string_printf(value, "%d", current); - out("battery_current", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", current); + out("battery_current", furi_string_get_cstr(value), false, context); int16_t temperature = (int16_t)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge); - string_printf(value, "%d", temperature); - out("gauge_temp", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", temperature); + out("gauge_temp", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); - out("battery_health", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); + out("battery_health", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_remaining_capacity()); - out("capacity_remain", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", furi_hal_power_get_battery_remaining_capacity()); + out("capacity_remain", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_full_capacity()); - out("capacity_full", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", furi_hal_power_get_battery_full_capacity()); + out("capacity_full", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_design_capacity()); - out("capacity_design", string_get_cstr(value), true, context); + furi_string_printf(value, "%u", furi_hal_power_get_battery_design_capacity()); + out("capacity_design", furi_string_get_cstr(value), true, context); - string_clear(value); + furi_string_free(value); } diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 3f1169d1..800fc3fe 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -5,7 +5,7 @@ #pragma once -#include +#include #include #include #include @@ -122,9 +122,9 @@ void furi_hal_bt_stop_advertising(); /** Get BT/BLE system component state * - * @param[in] buffer string_t buffer to write to + * @param[in] buffer FuriString* buffer to write to */ -void furi_hal_bt_dump_state(string_t buffer); +void furi_hal_bt_dump_state(FuriString* buffer); /** Get BT/BLE system component state * diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index f8eaa5c3..e94877af 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/furi/core/check.c b/furi/core/check.c index 3d0cd7a0..613b52f4 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -9,6 +9,7 @@ #include #include #include +#include extern size_t xPortGetTotalHeapSize(void); extern size_t xPortGetFreeHeapSize(void); diff --git a/furi/core/kernel.h b/furi/core/kernel.h index 28afffd4..f30f109b 100644 --- a/furi/core/kernel.h +++ b/furi/core/kernel.h @@ -1,5 +1,5 @@ /** - * @file kenrel.h + * @file kernel.h * Furi Kernel primitives */ #pragma once diff --git a/furi/core/log.c b/furi/core/log.c index 8a36a930..bb163c95 100644 --- a/furi/core/log.c +++ b/furi/core/log.c @@ -25,8 +25,8 @@ void furi_log_init() { void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) { if(level <= furi_log.log_level && furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) { - string_t string; - string_init(string); + FuriString* string; + string = furi_string_alloc(); const char* color = FURI_LOG_CLR_RESET; const char* log_letter = " "; @@ -56,23 +56,23 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form } // Timestamp - string_printf( + furi_string_printf( string, "%lu %s[%s][%s] " FURI_LOG_CLR_RESET, furi_log.timetamp(), color, log_letter, tag); - furi_log.puts(string_get_cstr(string)); - string_reset(string); + furi_log.puts(furi_string_get_cstr(string)); + furi_string_reset(string); va_list args; va_start(args, format); - string_vprintf(string, format, args); + furi_string_vprintf(string, format, args); va_end(args); - furi_log.puts(string_get_cstr(string)); - string_clear(string); + furi_log.puts(furi_string_get_cstr(string)); + furi_string_free(string); furi_log.puts("\r\n"); diff --git a/furi/core/record.c b/furi/core/record.c index 63dfdbe4..773585e7 100644 --- a/furi/core/record.c +++ b/furi/core/record.c @@ -4,7 +4,6 @@ #include "mutex.h" #include "event_flag.h" -#include #include #include diff --git a/furi/core/string.c b/furi/core/string.c new file mode 100644 index 00000000..099f70c1 --- /dev/null +++ b/furi/core/string.c @@ -0,0 +1,302 @@ +#include "string.h" +#include + +struct FuriString { + string_t string; +}; + +#undef furi_string_alloc_set +#undef furi_string_set +#undef furi_string_cmp +#undef furi_string_cmpi +#undef furi_string_search +#undef furi_string_search_str +#undef furi_string_equal +#undef furi_string_replace +#undef furi_string_replace_str +#undef furi_string_replace_all +#undef furi_string_start_with +#undef furi_string_end_with +#undef furi_string_search_char +#undef furi_string_search_rchar +#undef furi_string_trim +#undef furi_string_cat + +FuriString* furi_string_alloc() { + FuriString* string = malloc(sizeof(FuriString)); + string_init(string->string); + return string; +} + +FuriString* furi_string_alloc_set(const FuriString* s) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_set(string->string, s->string); + return string; +} + +FuriString* furi_string_alloc_set_str(const char cstr[]) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_set(string->string, cstr); + return string; +} + +FuriString* furi_string_alloc_printf(const char format[], ...) { + va_list args; + va_start(args, format); + FuriString* string = furi_string_alloc_vprintf(format, args); + va_end(args); + return string; +} + +FuriString* furi_string_alloc_vprintf(const char format[], va_list args) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_vprintf(string->string, format, args); + return string; +} + +FuriString* furi_string_alloc_move(FuriString* s) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_move(string->string, s->string); + free(s); + return string; +} + +void furi_string_free(FuriString* s) { + string_clear(s->string); + free(s); +} + +void furi_string_reserve(FuriString* s, size_t alloc) { + string_reserve(s->string, alloc); +} + +void furi_string_reset(FuriString* s) { + string_reset(s->string); +} + +void furi_string_swap(FuriString* v1, FuriString* v2) { + string_swap(v1->string, v2->string); +} + +void furi_string_move(FuriString* v1, FuriString* v2) { + string_clear(v1->string); + string_init_move(v1->string, v2->string); + free(v2); +} + +size_t furi_string_hash(const FuriString* v) { + return string_hash(v->string); +} + +char furi_string_get_char(const FuriString* v, size_t index) { + return string_get_char(v->string, index); +} + +const char* furi_string_get_cstr(const FuriString* s) { + return string_get_cstr(s->string); +} + +void furi_string_set(FuriString* s, FuriString* source) { + string_set(s->string, source->string); +} + +void furi_string_set_str(FuriString* s, const char cstr[]) { + string_set(s->string, cstr); +} + +void furi_string_set_strn(FuriString* s, const char str[], size_t n) { + string_set_strn(s->string, str, n); +} + +void furi_string_set_char(FuriString* s, size_t index, const char c) { + string_set_char(s->string, index, c); +} + +int furi_string_cmp(const FuriString* s1, const FuriString* s2) { + return string_cmp(s1->string, s2->string); +} + +int furi_string_cmp_str(const FuriString* s1, const char str[]) { + return string_cmp(s1->string, str); +} + +int furi_string_cmpi(const FuriString* v1, const FuriString* v2) { + return string_cmpi(v1->string, v2->string); +} + +int furi_string_cmpi_str(const FuriString* v1, const char p2[]) { + return string_cmpi_str(v1->string, p2); +} + +size_t furi_string_search(const FuriString* v, const FuriString* needle, size_t start) { + return string_search(v->string, needle->string, start); +} + +size_t furi_string_search_str(const FuriString* v, const char needle[], size_t start) { + return string_search(v->string, needle, start); +} + +bool furi_string_equal(const FuriString* v1, const FuriString* v2) { + return string_equal_p(v1->string, v2->string); +} + +bool furi_string_equal_str(const FuriString* v1, const char v2[]) { + return string_equal_p(v1->string, v2); +} + +void furi_string_push_back(FuriString* v, char c) { + string_push_back(v->string, c); +} + +size_t furi_string_size(const FuriString* s) { + return string_size(s->string); +} + +int furi_string_printf(FuriString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = furi_string_vprintf(v, format, args); + va_end(args); + return result; +} + +int furi_string_vprintf(FuriString* v, const char format[], va_list args) { + return string_vprintf(v->string, format, args); +} + +int furi_string_cat_printf(FuriString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = furi_string_cat_vprintf(v, format, args); + va_end(args); + return result; +} + +int furi_string_cat_vprintf(FuriString* v, const char format[], va_list args) { + FuriString* string = furi_string_alloc(); + int ret = furi_string_vprintf(string, format, args); + furi_string_cat(v, string); + furi_string_free(string); + return ret; +} + +bool furi_string_empty(const FuriString* v) { + return string_empty_p(v->string); +} + +void furi_string_replace_at(FuriString* v, size_t pos, size_t len, const char str2[]) { + string_replace_at(v->string, pos, len, str2); +} + +size_t + furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start) { + return string_replace(string->string, needle->string, replace->string, start); +} + +size_t furi_string_replace_str(FuriString* v, const char str1[], const char str2[], size_t start) { + return string_replace_str(v->string, str1, str2, start); +} + +void furi_string_replace_all_str(FuriString* v, const char str1[], const char str2[]) { + string_replace_all_str(v->string, str1, str2); +} + +void furi_string_replace_all(FuriString* v, const FuriString* str1, const FuriString* str2) { + string_replace_all(v->string, str1->string, str2->string); +} + +bool furi_string_start_with(const FuriString* v, const FuriString* v2) { + return string_start_with_string_p(v->string, v2->string); +} + +bool furi_string_start_with_str(const FuriString* v, const char str[]) { + return string_start_with_str_p(v->string, str); +} + +bool furi_string_end_with(const FuriString* v, const FuriString* v2) { + return string_end_with_string_p(v->string, v2->string); +} + +bool furi_string_end_with_str(const FuriString* v, const char str[]) { + return string_end_with_str_p(v->string, str); +} + +size_t furi_string_search_char(const FuriString* v, char c, size_t start) { + return string_search_char(v->string, c, start); +} + +size_t furi_string_search_rchar(const FuriString* v, char c, size_t start) { + return string_search_rchar(v->string, c, start); +} + +void furi_string_left(FuriString* v, size_t index) { + string_left(v->string, index); +} + +void furi_string_right(FuriString* v, size_t index) { + string_right(v->string, index); +} + +void furi_string_mid(FuriString* v, size_t index, size_t size) { + string_mid(v->string, index, size); +} + +void furi_string_trim(FuriString* v, const char charac[]) { + string_strim(v->string, charac); +} + +void furi_string_cat(FuriString* v, const FuriString* v2) { + string_cat(v->string, v2->string); +} + +void furi_string_cat_str(FuriString* v, const char str[]) { + string_cat(v->string, str); +} + +void furi_string_set_n(FuriString* v, const FuriString* ref, size_t offset, size_t length) { + string_set_n(v->string, ref->string, offset, length); +} + +size_t furi_string_utf8_length(FuriString* str) { + return string_length_u(str->string); +} + +void furi_string_utf8_push(FuriString* str, FuriStringUnicodeValue u) { + string_push_u(str->string, u); +} + +static m_str1ng_utf8_state_e furi_state_to_state(FuriStringUTF8State state) { + switch(state) { + case FuriStringUTF8StateStarting: + return M_STRING_UTF8_STARTING; + case FuriStringUTF8StateDecoding1: + return M_STRING_UTF8_DECODING_1; + case FuriStringUTF8StateDecoding2: + return M_STRING_UTF8_DECODING_2; + case FuriStringUTF8StateDecoding3: + return M_STRING_UTF8_DOCODING_3; + default: + return M_STRING_UTF8_ERROR; + } +} + +static FuriStringUTF8State state_to_furi_state(m_str1ng_utf8_state_e state) { + switch(state) { + case M_STRING_UTF8_STARTING: + return FuriStringUTF8StateStarting; + case M_STRING_UTF8_DECODING_1: + return FuriStringUTF8StateDecoding1; + case M_STRING_UTF8_DECODING_2: + return FuriStringUTF8StateDecoding2; + case M_STRING_UTF8_DOCODING_3: + return FuriStringUTF8StateDecoding3; + default: + return FuriStringUTF8StateError; + } +} + +void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode) { + m_str1ng_utf8_state_e m_state = furi_state_to_state(*state); + m_str1ng_utf8_decode(c, &m_state, unicode); + *state = state_to_furi_state(m_state); +} \ No newline at end of file diff --git a/furi/core/string.h b/furi/core/string.h new file mode 100644 index 00000000..b6700c9c --- /dev/null +++ b/furi/core/string.h @@ -0,0 +1,738 @@ +/** + * @file string.h + * Furi string primitive + */ +#pragma once + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Furi string failure constant. + */ +#define FURI_STRING_FAILURE ((size_t)-1) + +/** + * @brief Furi string primitive. + */ +typedef struct FuriString FuriString; + +//--------------------------------------------------------------------------- +// Constructors +//--------------------------------------------------------------------------- + +/** + * @brief Allocate new FuriString. + * @return FuriString* + */ +FuriString* furi_string_alloc(); + +/** + * @brief Allocate new FuriString and set it to string. + * Allocate & Set the string a to the string. + * @param source + * @return FuriString* + */ +FuriString* furi_string_alloc_set(const FuriString* source); + +/** + * @brief Allocate new FuriString and set it to C string. + * Allocate & Set the string a to the C string. + * @param cstr_source + * @return FuriString* + */ +FuriString* furi_string_alloc_set_str(const char cstr_source[]); + +/** + * @brief Allocate new FuriString and printf to it. + * Initialize and set a string to the given formatted value. + * @param format + * @param ... + * @return FuriString* + */ +FuriString* furi_string_alloc_printf(const char format[], ...); + +/** + * @brief Allocate new FuriString and printf to it. + * Initialize and set a string to the given formatted value. + * @param format + * @param args + * @return FuriString* + */ +FuriString* furi_string_alloc_vprintf(const char format[], va_list args); + +/** + * @brief Allocate new FuriString and move source string content to it. + * Allocate the string, set it to the other one, and destroy the other one. + * @param source + * @return FuriString* + */ +FuriString* furi_string_alloc_move(FuriString* source); + +//--------------------------------------------------------------------------- +// Destructors +//--------------------------------------------------------------------------- + +/** + * @brief Free FuriString. + * @param string + */ +void furi_string_free(FuriString* string); + +//--------------------------------------------------------------------------- +// String memory management +//--------------------------------------------------------------------------- + +/** + * @brief Reserve memory for string. + * Modify the string capacity to be able to handle at least 'alloc' characters (including final null char). + * @param string + * @param size + */ +void furi_string_reserve(FuriString* string, size_t size); + +/** + * @brief Reset string. + * Make the string empty. + * @param s + */ +void furi_string_reset(FuriString* string); + +/** + * @brief Swap two strings. + * Swap the two strings string_1 and string_2. + * @param string_1 + * @param string_2 + */ +void furi_string_swap(FuriString* string_1, FuriString* string_2); + +/** + * @brief Move string_2 content to string_1. + * Set the string to the other one, and destroy the other one. + * @param string_1 + * @param string_2 + */ +void furi_string_move(FuriString* string_1, FuriString* string_2); + +/** + * @brief Compute a hash for the string. + * @param string + * @return size_t + */ +size_t furi_string_hash(const FuriString* string); + +/** + * @brief Get string size (usually length, but not for UTF-8) + * @param string + * @return size_t + */ +size_t furi_string_size(const FuriString* string); + +/** + * @brief Check that string is empty or not + * @param string + * @return bool + */ +bool furi_string_empty(const FuriString* string); + +//--------------------------------------------------------------------------- +// Getters +//--------------------------------------------------------------------------- + +/** + * @brief Get the character at the given index. + * Return the selected character of the string. + * @param string + * @param index + * @return char + */ +char furi_string_get_char(const FuriString* string, size_t index); + +/** + * @brief Return the string view a classic C string. + * @param string + * @return const char* + */ +const char* furi_string_get_cstr(const FuriString* string); + +//--------------------------------------------------------------------------- +// Setters +//--------------------------------------------------------------------------- + +/** + * @brief Set the string to the other string. + * Set the string to the source string. + * @param string + * @param source + */ +void furi_string_set(FuriString* string, FuriString* source); + +/** + * @brief Set the string to the other C string. + * Set the string to the source C string. + * @param string + * @param source + */ +void furi_string_set_str(FuriString* string, const char source[]); + +/** + * @brief Set the string to the n first characters of the C string. + * @param string + * @param source + * @param length + */ +void furi_string_set_strn(FuriString* string, const char source[], size_t length); + +/** + * @brief Set the character at the given index. + * @param string + * @param index + * @param c + */ +void furi_string_set_char(FuriString* string, size_t index, const char c); + +/** + * @brief Set the string to the n first characters of other one. + * @param string + * @param source + * @param offset + * @param length + */ +void furi_string_set_n(FuriString* string, const FuriString* source, size_t offset, size_t length); + +/** + * @brief Format in the string the given printf format + * @param string + * @param format + * @param ... + * @return int + */ +int furi_string_printf(FuriString* string, const char format[], ...); + +/** + * @brief Format in the string the given printf format + * @param string + * @param format + * @param args + * @return int + */ +int furi_string_vprintf(FuriString* string, const char format[], va_list args); + +//--------------------------------------------------------------------------- +// Appending +//--------------------------------------------------------------------------- + +/** + * @brief Append a character to the string. + * @param string + * @param c + */ +void furi_string_push_back(FuriString* string, char c); + +/** + * @brief Append a string to the string. + * Concatenate the string with the other string. + * @param string_1 + * @param string_2 + */ +void furi_string_cat(FuriString* string_1, const FuriString* string_2); + +/** + * @brief Append a C string to the string. + * Concatenate the string with the C string. + * @param string_1 + * @param cstring_2 + */ +void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); + +/** + * @brief Append to the string the formatted string of the given printf format. + * @param string + * @param format + * @param ... + * @return int + */ +int furi_string_cat_printf(FuriString* string, const char format[], ...); + +/** + * @brief Append to the string the formatted string of the given printf format. + * @param string + * @param format + * @param args + * @return int + */ +int furi_string_cat_vprintf(FuriString* string, const char format[], va_list args); + +//--------------------------------------------------------------------------- +// Comparators +//--------------------------------------------------------------------------- + +/** + * @brief Compare two strings and return the sort order. + * @param string_1 + * @param string_2 + * @return int + */ +int furi_string_cmp(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Compare string with C string and return the sort order. + * @param string_1 + * @param cstring_2 + * @return int + */ +int furi_string_cmp_str(const FuriString* string_1, const char cstring_2[]); + +/** + * @brief Compare two strings (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * @param string_1 + * @param string_2 + * @return int + */ +int furi_string_cmpi(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Compare string with C string (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * @param string_1 + * @param cstring_2 + * @return int + */ +int furi_string_cmpi_str(const FuriString* string_1, const char cstring_2[]); + +//--------------------------------------------------------------------------- +// Search +//--------------------------------------------------------------------------- + +/** + * @brief Search the first occurrence of the needle in the string from the position start. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param needle + * @param start + * @return size_t + */ +size_t furi_string_search(const FuriString* string, const FuriString* needle, size_t start); + +/** + * @brief Search the first occurrence of the needle in the string from the position start. + * Return STRING_FAILURE if not found. + * @param string + * @param needle + * @param start + * @return size_t + */ +size_t furi_string_search_str(const FuriString* string, const char needle[], size_t start); + +/** + * @brief Search for the position of the character c from the position start (include) in the string. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param c + * @param start + * @return size_t + */ +size_t furi_string_search_char(const FuriString* string, char c, size_t start); + +/** + * @brief Reverse search for the position of the character c from the position start (include) in the string. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param c + * @param start + * @return size_t + */ +size_t furi_string_search_rchar(const FuriString* string, char c, size_t start); + +//--------------------------------------------------------------------------- +// Equality +//--------------------------------------------------------------------------- + +/** + * @brief Test if two strings are equal. + * @param string_1 + * @param string_2 + * @return bool + */ +bool furi_string_equal(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Test if the string is equal to the C string. + * @param string_1 + * @param cstring_2 + * @return bool + */ +bool furi_string_equal_str(const FuriString* string_1, const char cstring_2[]); + +//--------------------------------------------------------------------------- +// Replace +//--------------------------------------------------------------------------- + +/** + * @brief Replace in the string the sub-string at position 'pos' for 'len' bytes into the C string 'replace'. + * @param string + * @param pos + * @param len + * @param replace + */ +void furi_string_replace_at(FuriString* string, size_t pos, size_t len, const char replace[]); + +/** + * @brief Replace a string 'needle' to string 'replace' in a string from 'start' position. + * By default, start is zero. + * Return STRING_FAILURE if 'needle' not found or replace position. + * @param string + * @param needle + * @param replace + * @param start + * @return size_t + */ +size_t + furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start); + +/** + * @brief Replace a C string 'needle' to C string 'replace' in a string from 'start' position. + * By default, start is zero. + * Return STRING_FAILURE if 'needle' not found or replace position. + * @param string + * @param needle + * @param replace + * @param start + * @return size_t + */ +size_t furi_string_replace_str( + FuriString* string, + const char needle[], + const char replace[], + size_t start); + +/** + * @brief Replace all occurrences of 'needle' string into 'replace' string. + * @param string + * @param needle + * @param replace + */ +void furi_string_replace_all( + FuriString* string, + const FuriString* needle, + const FuriString* replace); + +/** + * @brief Replace all occurrences of 'needle' C string into 'replace' C string. + * @param string + * @param needle + * @param replace + */ +void furi_string_replace_all_str(FuriString* string, const char needle[], const char replace[]); + +//--------------------------------------------------------------------------- +// Start / End tests +//--------------------------------------------------------------------------- + +/** + * @brief Test if the string starts with the given string. + * @param string + * @param start + * @return bool + */ +bool furi_string_start_with(const FuriString* string, const FuriString* start); + +/** + * @brief Test if the string starts with the given C string. + * @param string + * @param start + * @return bool + */ +bool furi_string_start_with_str(const FuriString* string, const char start[]); + +/** + * @brief Test if the string ends with the given string. + * @param string + * @param end + * @return bool + */ +bool furi_string_end_with(const FuriString* string, const FuriString* end); + +/** + * @brief Test if the string ends with the given C string. + * @param string + * @param end + * @return bool + */ +bool furi_string_end_with_str(const FuriString* string, const char end[]); + +//--------------------------------------------------------------------------- +// Trim +//--------------------------------------------------------------------------- + +/** + * @brief Trim the string left to the first 'index' bytes. + * @param string + * @param index + */ +void furi_string_left(FuriString* string, size_t index); + +/** + * @brief Trim the string right from the 'index' position to the last position. + * @param string + * @param index + */ +void furi_string_right(FuriString* string, size_t index); + +/** + * @brief Trim the string from position index to size bytes. + * See also furi_string_set_n. + * @param string + * @param index + * @param size + */ +void furi_string_mid(FuriString* string, size_t index, size_t size); + +/** + * @brief Trim a string from the given set of characters (default is " \n\r\t"). + * @param string + * @param chars + */ +void furi_string_trim(FuriString* string, const char chars[]); + +//--------------------------------------------------------------------------- +// UTF8 +//--------------------------------------------------------------------------- + +/** + * @brief An unicode value. + */ +typedef unsigned int FuriStringUnicodeValue; + +/** + * @brief Compute the length in UTF8 characters in the string. + * @param string + * @return size_t + */ +size_t furi_string_utf8_length(FuriString* string); + +/** + * @brief Push unicode into string, encoding it in UTF8. + * @param string + * @param unicode + */ +void furi_string_utf8_push(FuriString* string, FuriStringUnicodeValue unicode); + +/** + * @brief State of the UTF8 decoding machine state. + */ +typedef enum { + FuriStringUTF8StateStarting, + FuriStringUTF8StateDecoding1, + FuriStringUTF8StateDecoding2, + FuriStringUTF8StateDecoding3, + FuriStringUTF8StateError +} FuriStringUTF8State; + +/** + * @brief Main generic UTF8 decoder. + * It takes a character, and the previous state and the previous value of the unicode value. + * It updates the state and the decoded unicode value. + * A decoded unicode encoded value is valid only when the state is FuriStringUTF8StateStarting. + * @param c + * @param state + * @param unicode + */ +void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode); + +//--------------------------------------------------------------------------- +// Lasciate ogne speranza, voi ch’entrate +//--------------------------------------------------------------------------- + +/** + * + * Select either the string function or the str function depending on + * the b operand to the function. + * func1 is the string function / func2 is the str function. + */ + +/** + * @brief Select for 1 argument + */ +#define FURI_STRING_SELECT1(func1, func2, a) \ + _Generic((a), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a) + +/** + * @brief Select for 2 arguments + */ +#define FURI_STRING_SELECT2(func1, func2, a, b) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b) + +/** + * @brief Select for 3 arguments + */ +#define FURI_STRING_SELECT3(func1, func2, a, b, c) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b, c) + +/** + * @brief Select for 4 arguments + */ +#define FURI_STRING_SELECT4(func1, func2, a, b, c, d) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b, c, d) + +/** + * @brief Allocate new FuriString and set it content to string (or C string). + * ([c]string) + */ +#define furi_string_alloc_set(a) \ + FURI_STRING_SELECT1(furi_string_alloc_set, furi_string_alloc_set_str, a) + +/** + * @brief Set the string content to string (or C string). + * (string, [c]string) + */ +#define furi_string_set(a, b) FURI_STRING_SELECT2(furi_string_set, furi_string_set_str, a, b) + +/** + * @brief Compare string with string (or C string) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * (string, [c]string) + */ +#define furi_string_cmp(a, b) FURI_STRING_SELECT2(furi_string_cmp, furi_string_cmp_str, a, b) + +/** + * @brief Compare string with string (or C string) (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * (string, [c]string) + */ +#define furi_string_cmpi(a, b) FURI_STRING_SELECT2(furi_string_cmpi, furi_string_cmpi_str, a, b) + +/** + * @brief Test if the string is equal to the string (or C string). + * (string, [c]string) + */ +#define furi_string_equal(a, b) FURI_STRING_SELECT2(furi_string_equal, furi_string_equal_str, a, b) + +/** + * @brief Replace all occurrences of string into string (or C string to another C string) in a string. + * (string, [c]string, [c]string) + */ +#define furi_string_replace_all(a, b, c) \ + FURI_STRING_SELECT3(furi_string_replace_all, furi_string_replace_all_str, a, b, c) + +/** + * @brief Search for a string (or C string) in a string + * (string, [c]string[, start=0]) + */ +#define furi_string_search(v, ...) \ + M_APPLY( \ + FURI_STRING_SELECT3, \ + furi_string_search, \ + furi_string_search_str, \ + v, \ + M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Search for a C string in a string + * (string, cstring[, start=0]) + */ +#define furi_string_search_str(v, ...) \ + M_APPLY(furi_string_search_str, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Test if the string starts with the given string (or C string). + * (string, [c]string) + */ +#define furi_string_start_with(a, b) \ + FURI_STRING_SELECT2(furi_string_start_with, furi_string_start_with_str, a, b) + +/** + * @brief Test if the string ends with the given string (or C string). + * (string, [c]string) + */ +#define furi_string_end_with(a, b) \ + FURI_STRING_SELECT2(furi_string_end_with, furi_string_end_with_str, a, b) + +/** + * @brief Append a string (or C string) to the string. + * (string, [c]string) + */ +#define furi_string_cat(a, b) FURI_STRING_SELECT2(furi_string_cat, furi_string_cat_str, a, b) + +/** + * @brief Trim a string from the given set of characters (default is " \n\r\t"). + * (string[, set=" \n\r\t"]) + */ +#define furi_string_trim(...) M_APPLY(furi_string_trim, M_IF_DEFAULT1(" \n\r\t", __VA_ARGS__)) + +/** + * @brief Search for a character in a string. + * (string, character[, start=0]) + */ +#define furi_string_search_char(v, ...) \ + M_APPLY(furi_string_search_char, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Reverse Search for a character in a string. + * (string, character[, start=0]) + */ +#define furi_string_search_rchar(v, ...) \ + M_APPLY(furi_string_search_rchar, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Replace a string to another string (or C string to another C string) in a string. + * (string, [c]string, [c]string[, start=0]) + */ +#define furi_string_replace(a, b, ...) \ + M_APPLY( \ + FURI_STRING_SELECT4, \ + furi_string_replace, \ + furi_string_replace_str, \ + a, \ + b, \ + M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Replace a C string to another C string in a string. + * (string, cstring, cstring[, start=0]) + */ +#define furi_string_replace_str(a, b, ...) \ + M_APPLY(furi_string_replace_str, a, b, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief INIT OPLIST for FuriString. + */ +#define F_STR_INIT(a) ((a) = furi_string_alloc()) + +/** + * @brief INIT SET OPLIST for FuriString. + */ +#define F_STR_INIT_SET(a, b) ((a) = furi_string_alloc_set(b)) + +/** + * @brief OPLIST for FuriString. + */ +#define FURI_STRING_OPLIST \ + (INIT(F_STR_INIT), \ + INIT_SET(F_STR_INIT_SET), \ + SET(furi_string_set), \ + INIT_MOVE(furi_string_alloc_move), \ + MOVE(furi_string_move), \ + SWAP(furi_string_swap), \ + RESET(furi_string_reset), \ + EMPTY_P(furi_string_empty), \ + CLEAR(furi_string_free), \ + HASH(furi_string_hash), \ + EQUAL(furi_string_equal), \ + CMP(furi_string_cmp), \ + TYPE(FuriString*)) + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/furi/core/thread.c b/furi/core/thread.c index d06fa8b3..3ebca807 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -5,10 +5,10 @@ #include "check.h" #include "common_defines.h" #include "mutex.h" +#include "string.h" #include #include "log.h" -#include #include #include @@ -18,7 +18,7 @@ typedef struct FuriThreadStdout FuriThreadStdout; struct FuriThreadStdout { FuriThreadStdoutWriteCallback write_callback; - string_t buffer; + FuriString* buffer; }; struct FuriThread { @@ -109,7 +109,7 @@ static void furi_thread_body(void* context) { FuriThread* furi_thread_alloc() { FuriThread* thread = malloc(sizeof(FuriThread)); - string_init(thread->output.buffer); + thread->output.buffer = furi_string_alloc(); thread->is_service = false; return thread; } @@ -119,7 +119,7 @@ void furi_thread_free(FuriThread* thread) { furi_assert(thread->state == FuriThreadStateStopped); if(thread->name) free((void*)thread->name); - string_clear(thread->output.buffer); + furi_string_free(thread->output.buffer); free(thread); } @@ -485,11 +485,11 @@ static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, s } static int32_t __furi_thread_stdout_flush(FuriThread* thread) { - string_ptr buffer = thread->output.buffer; - size_t size = string_size(buffer); + FuriString* buffer = thread->output.buffer; + size_t size = furi_string_size(buffer); if(size > 0) { - __furi_thread_stdout_write(thread, string_get_cstr(buffer), size); - string_reset(buffer); + __furi_thread_stdout_write(thread, furi_string_get_cstr(buffer), size); + furi_string_reset(buffer); } return 0; } @@ -516,7 +516,7 @@ size_t furi_thread_stdout_write(const char* data, size_t size) { } else { // string_cat doesn't work here because we need to write the exact size data for(size_t i = 0; i < size; i++) { - string_push_back(thread->output.buffer, data[i]); + furi_string_push_back(thread->output.buffer, data[i]); if(data[i] == '\n') { __furi_thread_stdout_flush(thread); } diff --git a/furi/furi.h b/furi/furi.h index 68914b50..306c9b94 100644 --- a/furi/furi.h +++ b/furi/furi.h @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index e2616549..b66e27d9 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -61,7 +61,7 @@ static void elf_file_put_section(ELFFile* elf, const char* name, ELFSection* sec ELFSectionDict_set_at(elf->sections, strdup(name), *section); } -static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, FuriString* name) { bool result = false; off_t old = storage_file_tell(elf->fd); @@ -74,7 +74,7 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam while(true) { uint16_t read = storage_file_read(elf->fd, buffer, ELF_NAME_BUFFER_LEN); - string_cat_str(name, buffer); + furi_string_cat(name, buffer); if(strlen(buffer) < ELF_NAME_BUFFER_LEN) { result = true; break; @@ -89,11 +89,11 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam return result; } -static bool elf_read_section_name(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_section_name(ELFFile* elf, off_t offset, FuriString* name) { return elf_read_string_from_offset(elf, elf->section_table_strings + offset, name); } -static bool elf_read_symbol_name(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_symbol_name(ELFFile* elf, off_t offset, FuriString* name) { return elf_read_string_from_offset(elf, elf->symbol_table_strings + offset, name); } @@ -103,8 +103,11 @@ static bool elf_read_section_header(ELFFile* elf, size_t section_idx, Elf32_Shdr storage_file_read(elf->fd, section_header, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr); } -static bool - elf_read_section(ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, string_t name) { +static bool elf_read_section( + ELFFile* elf, + size_t section_idx, + Elf32_Shdr* section_header, + FuriString* name) { if(!elf_read_section_header(elf, section_idx, section_header)) { return false; } @@ -116,7 +119,7 @@ static bool return true; } -static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, string_t name) { +static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, FuriString* name) { bool success = false; off_t old = storage_file_tell(elf->fd); off_t pos = elf->symbol_table + n * sizeof(Elf32_Sym); @@ -276,19 +279,17 @@ static void elf_relocate_mov(Elf32_Addr relAddr, int type, Elf32_Addr symAddr) { int32_t addend = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; /* imm16 */ uint32_t addr = (symAddr + addend); - if (type == R_ARM_THM_MOVT_ABS) { + if(type == R_ARM_THM_MOVT_ABS) { addr >>= 16; /* upper 16 bits */ } else { addr &= 0x0000FFFF; /* lower 16 bits */ } /* Re-encode */ - ((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0) - | (((addr >> 11) & 1) << 10) /* i */ - | ((addr >> 12) & 0x000F); /* imm4 */ - ((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00) - | (((addr >> 8) & 0x7) << 12) /* imm3 */ - | (addr & 0x00FF); /* imm8 */ + ((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0) | (((addr >> 11) & 1) << 10) /* i */ + | ((addr >> 12) & 0x000F); /* imm4 */ + ((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00) | (((addr >> 8) & 0x7) << 12) /* imm3 */ + | (addr & 0x00FF); /* imm8 */ } static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf32_Addr symAddr) { @@ -307,7 +308,10 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3 case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: elf_relocate_mov(relAddr, type, symAddr); - FURI_LOG_D(TAG, " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr)); + FURI_LOG_D( + TAG, + " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", + (unsigned int)*((uint32_t*)relAddr)); break; default: FURI_LOG_E(TAG, " Undefined relocation %d", type); @@ -325,8 +329,8 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { FURI_LOG_D(TAG, " Offset Info Type Name"); int relocate_result = true; - string_t symbol_name; - string_init(symbol_name); + FuriString* symbol_name; + symbol_name = furi_string_alloc(); for(relCount = 0; relCount < relEntries; relCount++) { if(relCount % RESOLVER_THREAD_YIELD_STEP == 0) { @@ -336,7 +340,7 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { if(storage_file_read(elf->fd, &rel, sizeof(Elf32_Rel)) != sizeof(Elf32_Rel)) { FURI_LOG_E(TAG, " reloc read fail"); - string_clear(symbol_name); + furi_string_free(symbol_name); return false; } @@ -348,10 +352,10 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { if(!address_cache_get(elf->relocation_cache, symEntry, &symAddr)) { Elf32_Sym sym; - string_reset(symbol_name); + furi_string_reset(symbol_name); if(!elf_read_symbol(elf, symEntry, &sym, symbol_name)) { FURI_LOG_E(TAG, " symbol read fail"); - string_clear(symbol_name); + furi_string_free(symbol_name); return false; } @@ -361,9 +365,9 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { (unsigned int)rel.r_offset, (unsigned int)rel.r_info, elf_reloc_type_to_str(relType), - string_get_cstr(symbol_name)); + furi_string_get_cstr(symbol_name)); - symAddr = elf_address_of(elf, &sym, string_get_cstr(symbol_name)); + symAddr = elf_address_of(elf, &sym, furi_string_get_cstr(symbol_name)); address_cache_put(elf->relocation_cache, symEntry, symAddr); } @@ -377,11 +381,11 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { relocate_result = false; } } else { - FURI_LOG_E(TAG, " No symbol address of %s", string_get_cstr(symbol_name)); + FURI_LOG_E(TAG, " No symbol address of %s", furi_string_get_cstr(symbol_name)); relocate_result = false; } } - string_clear(symbol_name); + furi_string_free(symbol_name); return relocate_result; } else { @@ -445,9 +449,9 @@ static SectionType elf_preload_section( ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, - string_t name_string, + FuriString* name_string, FlipperApplicationManifest* manifest) { - const char* name = string_get_cstr(name_string); + const char* name = furi_string_get_cstr(name_string); const struct { const char* prefix; @@ -670,19 +674,19 @@ bool elf_file_open(ELFFile* elf, const char* path) { bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) { bool result = false; - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); FURI_LOG_D(TAG, "Looking for manifest section"); for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { Elf32_Shdr section_header; - string_reset(name); + furi_string_reset(name); if(!elf_read_section(elf, section_idx, §ion_header, name)) { break; } - if(string_cmp(name, ".fapmeta") == 0) { + if(furi_string_cmp(name, ".fapmeta") == 0) { if(elf_load_metadata(elf, §ion_header, manifest)) { FURI_LOG_D(TAG, "Load manifest done"); result = true; @@ -693,26 +697,27 @@ bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) } } - string_clear(name); + furi_string_free(name); return result; } bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manifest) { SectionType loaded_sections = SectionTypeERROR; - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); FURI_LOG_D(TAG, "Scan ELF indexs..."); for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { Elf32_Shdr section_header; - string_reset(name); + furi_string_reset(name); if(!elf_read_section(elf, section_idx, §ion_header, name)) { loaded_sections = SectionTypeERROR; break; } - FURI_LOG_D(TAG, "Preloading data for section #%d %s", section_idx, string_get_cstr(name)); + FURI_LOG_D( + TAG, "Preloading data for section #%d %s", section_idx, furi_string_get_cstr(name)); SectionType section_type = elf_preload_section(elf, section_idx, §ion_header, name, manifest); loaded_sections |= section_type; @@ -723,7 +728,7 @@ bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manif } } - string_clear(name); + furi_string_free(name); FURI_LOG_D(TAG, "Load symbols done"); return IS_FLAGS_SET(loaded_sections, SectionTypeValid); diff --git a/lib/flipper_format/flipper_format.c b/lib/flipper_format/flipper_format.c index 62005127..292dab5f 100644 --- a/lib/flipper_format/flipper_format.c +++ b/lib/flipper_format/flipper_format.c @@ -137,7 +137,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key) { bool flipper_format_read_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, uint32_t* version) { furi_assert(flipper_format); return flipper_format_read_string(flipper_format, flipper_format_filetype_key, filetype) && @@ -146,10 +146,11 @@ bool flipper_format_read_header( bool flipper_format_write_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, const uint32_t version) { furi_assert(flipper_format); - return flipper_format_write_header_cstr(flipper_format, string_get_cstr(filetype), version); + return flipper_format_write_header_cstr( + flipper_format, furi_string_get_cstr(filetype), version); } bool flipper_format_write_header_cstr( @@ -171,18 +172,18 @@ bool flipper_format_get_value_count( flipper_format->stream, key, count, flipper_format->strict_mode); } -bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); return flipper_format_stream_read_value_line( flipper_format->stream, key, FlipperStreamValueStr, data, 1, flipper_format->strict_mode); } -bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); FlipperStreamWriteData write_data = { .key = key, .type = FlipperStreamValueStr, - .data = string_get_cstr(data), + .data = furi_string_get_cstr(data), .data_size = 1, }; bool result = flipper_format_stream_write_value_line(flipper_format->stream, &write_data); @@ -386,9 +387,9 @@ bool flipper_format_write_hex( return result; } -bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data) { +bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data) { furi_assert(flipper_format); - return flipper_format_write_comment_cstr(flipper_format, string_get_cstr(data)); + return flipper_format_write_comment_cstr(flipper_format, furi_string_get_cstr(data)); } bool flipper_format_write_comment_cstr(FlipperFormat* flipper_format, const char* data) { @@ -409,12 +410,12 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key) { return result; } -bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); FlipperStreamWriteData write_data = { .key = key, .type = FlipperStreamValueStr, - .data = string_get_cstr(data), + .data = furi_string_get_cstr(data), .data_size = 1, }; bool result = flipper_format_stream_delete_key_and_write( @@ -522,7 +523,7 @@ bool flipper_format_update_hex( bool flipper_format_insert_or_update_string( FlipperFormat* flipper_format, const char* key, - string_t data) { + FuriString* data) { bool result = false; if(!flipper_format_key_exist(flipper_format, key)) { diff --git a/lib/flipper_format/flipper_format.h b/lib/flipper_format/flipper_format.h index 9e82bb31..743918e3 100644 --- a/lib/flipper_format/flipper_format.h +++ b/lib/flipper_format/flipper_format.h @@ -70,13 +70,13 @@ * * do { * uint32_t version = 1; - * string_t file_type; - * string_t string_value; + * FuriString* file_type; + * FuriString* string_value; * uint32_t uint32_value = 1; * uint16_t array_size = 4; * uint8_t* array[array_size] = {0}; - * string_init(file_type); - * string_init(string_value); + * file_type = furi_string_alloc(); + * string_value = furi_string_alloc(); * * if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test"))) break; * if(!flipper_format_read_header(file, file_type, &version)) break; @@ -94,7 +94,6 @@ #pragma once #include -#include #include #ifdef __cplusplus @@ -227,7 +226,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key); */ bool flipper_format_read_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, uint32_t* version); /** @@ -239,7 +238,7 @@ bool flipper_format_read_header( */ bool flipper_format_write_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, const uint32_t version); /** @@ -273,7 +272,7 @@ bool flipper_format_get_value_count( * @param data Value * @return True on success */ -bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Write key and string @@ -282,7 +281,7 @@ bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, * @param data Value * @return True on success */ -bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Write key and string. Plain C string version. @@ -470,7 +469,7 @@ bool flipper_format_write_hex( * @param data Comment text * @return True on success */ -bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data); +bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data); /** * Write comment. Plain C string version. @@ -495,7 +494,7 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key); * @param data Value * @return True on success */ -bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Updates the value of the first matching key to a string value. Plain C version. Sets the RW pointer to a position at the end of inserted data. @@ -585,7 +584,7 @@ bool flipper_format_update_hex( bool flipper_format_insert_or_update_string( FlipperFormat* flipper_format, const char* key, - string_t data); + FuriString* data); /** * Updates the value of the first matching key to a string value, or adds the key and value if the key did not exist. diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index e4b7b300..ecc68d4e 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -26,8 +26,8 @@ bool flipper_format_stream_write_eol(Stream* stream) { return flipper_format_stream_write(stream, &flipper_format_eoln, 1); } -static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { - string_reset(key); +static bool flipper_format_stream_read_valid_key(Stream* stream, FuriString* key) { + furi_string_reset(key); const size_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -44,7 +44,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { uint8_t data = buffer[i]; if(data == flipper_format_eoln) { // EOL found, clean data, start accumulating data and set the new_line flag - string_reset(key); + furi_string_reset(key); accumulate = true; new_line = true; } else if(data == flipper_format_eolr) { @@ -60,7 +60,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { // this can only be if we have previously found some kind of key, so // clear the data, set the flag that we no longer want to accumulate data // and reset the new_line flag - string_reset(key); + furi_string_reset(key); accumulate = false; new_line = false; } else { @@ -82,7 +82,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { new_line = false; if(accumulate) { // and accumulate data if we want - string_push_back(key, data); + furi_string_push_back(key, data); } } } @@ -95,13 +95,13 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool strict_mode) { bool found = false; - string_t read_key; + FuriString* read_key; - string_init(read_key); + read_key = furi_string_alloc(); while(!stream_eof(stream)) { if(flipper_format_stream_read_valid_key(stream, read_key)) { - if(string_cmp_str(read_key, key) == 0) { + if(furi_string_cmp_str(read_key, key) == 0) { if(!stream_seek(stream, 2, StreamOffsetFromCurrent)) break; found = true; @@ -112,13 +112,13 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str } } } - string_clear(read_key); + furi_string_free(read_key); return found; } -static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) { - string_reset(value); +static bool flipper_format_stream_read_value(Stream* stream, FuriString* value, bool* last) { + furi_string_reset(value); const size_t buffer_size = 32; uint8_t buffer[buffer_size]; bool result = false; @@ -129,7 +129,7 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo if(was_read == 0) { // check EOF - if(stream_eof(stream) && string_size(value) > 0) { + if(stream_eof(stream) && furi_string_size(value) > 0) { result = true; *last = true; break; @@ -139,7 +139,7 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo for(uint16_t i = 0; i < was_read; i++) { uint8_t data = buffer[i]; if(data == flipper_format_eoln) { - if(string_size(value) > 0) { + if(furi_string_size(value) > 0) { if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { error = true; break; @@ -152,7 +152,7 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo error = true; } } else if(data == ' ') { - if(string_size(value) > 0) { + if(furi_string_size(value) > 0) { if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { error = true; break; @@ -166,7 +166,7 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo } else if(data == flipper_format_eolr) { // Ignore } else { - string_push_back(value, data); + furi_string_push_back(value, data); } } @@ -176,8 +176,8 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo return result; } -static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) { - string_reset(str_result); +static bool flipper_format_stream_read_line(Stream* stream, FuriString* str_result) { + furi_string_reset(str_result); const size_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -201,7 +201,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) } else if(data == flipper_format_eolr) { // Ignore } else { - string_push_back(str_result, data); + furi_string_push_back(str_result, data); } } @@ -210,7 +210,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) } } while(true); - return string_size(str_result) != 0; + return furi_string_size(str_result) != 0; } static bool flipper_format_stream_seek_to_next_line(Stream* stream) { @@ -254,8 +254,8 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa if(write_data->type == FlipperStreamValueIgnore) { result = true; } else { - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); do { if(!flipper_format_stream_write_key(stream, write_data->key)) break; @@ -267,45 +267,45 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa switch(write_data->type) { case FlipperStreamValueStr: { const char* data = write_data->data; - string_printf(value, "%s", data); + furi_string_printf(value, "%s", data); }; break; case FlipperStreamValueHex: { const uint8_t* data = write_data->data; - string_printf(value, "%02X", data[i]); + furi_string_printf(value, "%02X", data[i]); }; break; #ifndef FLIPPER_STREAM_LITE case FlipperStreamValueFloat: { const float* data = write_data->data; - string_printf(value, "%f", (double)data[i]); + furi_string_printf(value, "%f", (double)data[i]); }; break; #endif case FlipperStreamValueInt32: { const int32_t* data = write_data->data; - string_printf(value, "%" PRIi32, data[i]); + furi_string_printf(value, "%" PRIi32, data[i]); }; break; case FlipperStreamValueUint32: { const uint32_t* data = write_data->data; - string_printf(value, "%" PRId32, data[i]); + furi_string_printf(value, "%" PRId32, data[i]); }; break; case FlipperStreamValueHexUint64: { const uint64_t* data = write_data->data; - string_printf( + furi_string_printf( value, "%08lX%08lX", (uint32_t)(data[i] >> 32), (uint32_t)data[i]); }; break; case FlipperStreamValueBool: { const bool* data = write_data->data; - string_printf(value, data[i] ? "true" : "false"); + furi_string_printf(value, data[i] ? "true" : "false"); }; break; default: furi_crash("Unknown FF type"); } if((size_t)(i + 1) < write_data->data_size) { - string_cat(value, " "); + furi_string_cat(value, " "); } if(!flipper_format_stream_write( - stream, string_get_cstr(value), string_size(value))) { + stream, furi_string_get_cstr(value), furi_string_size(value))) { cycle_error = true; break; } @@ -316,7 +316,7 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa result = true; } while(false); - string_clear(value); + furi_string_free(value); } return result; @@ -335,15 +335,15 @@ bool flipper_format_stream_read_value_line( if(!flipper_format_stream_seek_to_key(stream, key, strict_mode)) break; if(type == FlipperStreamValueStr) { - string_ptr data = (string_ptr)_data; + FuriString* data = (FuriString*)_data; if(flipper_format_stream_read_line(stream, data)) { result = true; break; } } else { result = true; - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); for(size_t i = 0; i < data_size; i++) { bool last = false; @@ -354,11 +354,11 @@ bool flipper_format_stream_read_value_line( switch(type) { case FlipperStreamValueHex: { uint8_t* data = _data; - if(string_size(value) >= 2) { + if(furi_string_size(value) >= 2) { // sscanf "%02X" does not work here if(hex_char_to_uint8( - string_get_char(value, 0), - string_get_char(value, 1), + furi_string_get_char(value, 0), + furi_string_get_char(value, 1), &data[i])) { scan_values = 1; } @@ -368,9 +368,9 @@ bool flipper_format_stream_read_value_line( case FlipperStreamValueFloat: { float* data = _data; // newlib-nano does not have sscanf for floats - // scan_values = sscanf(string_get_cstr(value), "%f", &data[i]); + // scan_values = sscanf(furi_string_get_cstr(value), "%f", &data[i]); char* end_char; - data[i] = strtof(string_get_cstr(value), &end_char); + data[i] = strtof(furi_string_get_cstr(value), &end_char); if(*end_char == 0) { // most likely ok scan_values = 1; @@ -379,23 +379,23 @@ bool flipper_format_stream_read_value_line( #endif case FlipperStreamValueInt32: { int32_t* data = _data; - scan_values = sscanf(string_get_cstr(value), "%" PRIi32, &data[i]); + scan_values = sscanf(furi_string_get_cstr(value), "%" PRIi32, &data[i]); }; break; case FlipperStreamValueUint32: { uint32_t* data = _data; - scan_values = sscanf(string_get_cstr(value), "%" PRId32, &data[i]); + scan_values = sscanf(furi_string_get_cstr(value), "%" PRId32, &data[i]); }; break; case FlipperStreamValueHexUint64: { uint64_t* data = _data; - if(string_size(value) >= 16) { - if(hex_chars_to_uint64(string_get_cstr(value), &data[i])) { + if(furi_string_size(value) >= 16) { + if(hex_chars_to_uint64(furi_string_get_cstr(value), &data[i])) { scan_values = 1; } } }; break; case FlipperStreamValueBool: { bool* data = _data; - data[i] = !string_cmpi_str(value, "true"); + data[i] = !furi_string_cmpi(value, "true"); scan_values = 1; }; break; default: @@ -416,7 +416,7 @@ bool flipper_format_stream_read_value_line( } } - string_clear(value); + furi_string_free(value); } } while(false); @@ -431,8 +431,8 @@ bool flipper_format_stream_get_value_count( bool result = false; bool last = false; - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); uint32_t position = stream_tell(stream); do { @@ -456,7 +456,7 @@ bool flipper_format_stream_get_value_count( result = false; } - string_clear(value); + furi_string_free(value); return result; } diff --git a/lib/flipper_format/flipper_format_stream.h b/lib/flipper_format/flipper_format_stream.h index 75eaef20..88b096b2 100644 --- a/lib/flipper_format/flipper_format_stream.h +++ b/lib/flipper_format/flipper_format_stream.h @@ -2,7 +2,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/lib/lfrfid/lfrfid_dict_file.c b/lib/lfrfid/lfrfid_dict_file.c index bb6af39a..7ae84f8b 100644 --- a/lib/lfrfid/lfrfid_dict_file.c +++ b/lib/lfrfid/lfrfid_dict_file.c @@ -143,8 +143,8 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { FlipperFormat* file = flipper_format_file_alloc(storage); ProtocolId result = PROTOCOL_NO; uint8_t* data = malloc(protocol_dict_get_max_data_size(dict)); - string_t str_result; - string_init(str_result); + FuriString* str_result; + str_result = furi_string_alloc(); do { if(!flipper_format_file_open_existing(file, filename)) break; @@ -152,16 +152,16 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { // header uint32_t version; if(!flipper_format_read_header(file, str_result, &version)) break; - if(string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break; + if(furi_string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break; if(version != 1) break; // type if(!flipper_format_read_string(file, "Key type", str_result)) break; ProtocolId protocol; - protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(str_result)); + protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(str_result)); if(protocol == PROTOCOL_NO) { - protocol = lfrfid_dict_protocol_fallback(dict, string_get_cstr(str_result), file); + protocol = lfrfid_dict_protocol_fallback(dict, furi_string_get_cstr(str_result), file); if(protocol == PROTOCOL_NO) break; } else { // data @@ -174,7 +174,7 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { } while(false); free(data); - string_clear(str_result); + furi_string_free(str_result); flipper_format_free(file); furi_record_close(RECORD_STORAGE); diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index 4050a8ca..b277bbd3 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -40,7 +40,7 @@ typedef struct { // main worker struct LFRFIDRawWorker { - string_t file_path; + FuriString* file_path; FuriThread* thread; FuriEventFlag* events; @@ -69,14 +69,14 @@ LFRFIDRawWorker* lfrfid_raw_worker_alloc() { worker->events = furi_event_flag_alloc(NULL); - string_init(worker->file_path); + worker->file_path = furi_string_alloc(); return worker; } void lfrfid_raw_worker_free(LFRFIDRawWorker* worker) { furi_thread_free(worker->thread); furi_event_flag_free(worker->events); - string_clear(worker->file_path); + furi_string_free(worker->file_path); free(worker); } @@ -89,7 +89,7 @@ void lfrfid_raw_worker_start_read( void* context) { furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped); - string_set(worker->file_path, file_path); + furi_string_set(worker->file_path, file_path); worker->frequency = freq; worker->duty_cycle = duty_cycle; @@ -107,7 +107,7 @@ void lfrfid_raw_worker_start_emulate( LFRFIDWorkerEmulateRawCallback callback, void* context) { furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped); - string_set(worker->file_path, file_path); + furi_string_set(worker->file_path, file_path); worker->emulate_callback = callback; worker->context = context; furi_thread_set_callback(worker->thread, lfrfid_raw_emulate_worker_thread); @@ -147,7 +147,7 @@ static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { Storage* storage = furi_record_open(RECORD_STORAGE); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); - const char* filename = string_get_cstr(worker->file_path); + const char* filename = furi_string_get_cstr(worker->file_path); bool file_valid = lfrfid_raw_file_open_write(file, filename); LFRFIDRawWorkerReadData* data = malloc(sizeof(LFRFIDRawWorkerReadData)); @@ -256,7 +256,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); do { - file_valid = lfrfid_raw_file_open_read(file, string_get_cstr(worker->file_path)); + file_valid = lfrfid_raw_file_open_read(file, furi_string_get_cstr(worker->file_path)); if(!file_valid) break; file_valid = lfrfid_raw_file_read_header(file, &worker->frequency, &worker->duty_cycle); if(!file_valid) break; diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 16936cca..56447057 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -270,14 +270,14 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( } if(furi_log_get_level() >= FuriLogLevelDebug) { - string_t string_info; - string_init(string_info); + FuriString* string_info; + string_info = furi_string_alloc(); for(uint8_t i = 0; i < protocol_data_size; i++) { if(i != 0) { - string_cat_printf(string_info, " "); + furi_string_cat_printf(string_info, " "); } - string_cat_printf(string_info, "%02X", protocol_data[i]); + furi_string_cat_printf(string_info, "%02X", protocol_data[i]); } FURI_LOG_D( @@ -285,8 +285,8 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( "%s, %d, [%s]", protocol_dict_get_name(worker->protocols, protocol), last_read_count, - string_get_cstr(string_info)); - string_clear(string_info); + furi_string_get_cstr(string_info)); + furi_string_free(string_info); } protocol_dict_decoders_start(worker->protocols); diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 7131d30d..69409b31 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -147,7 +147,7 @@ LevelDuration protocol_awid_encoder_yield(ProtocolAwid* protocol) { return level_duration_make(level, duration); }; -void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { +void protocol_awid_render_data(ProtocolAwid* protocol, FuriString* result) { // Index map // 0 10 20 30 40 50 60 // | | | | | | | @@ -164,7 +164,7 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -172,22 +172,22 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - string_cat_printf(result, "Facility: %d\r\n", facility); - string_cat_printf(result, "Card: %d", card_id); + furi_string_cat_printf(result, "Facility: %d\r\n", facility); + furi_string_cat_printf(result, "Card: %d", card_id); } else { // print 66 bits as hex - string_cat_printf(result, "Data: "); + furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < AWID_DECODED_DATA_SIZE; i++) { - string_cat_printf(result, "%02X", decoded_data[i]); + furi_string_cat_printf(result, "%02X", decoded_data[i]); } } }; -void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) { +void protocol_awid_render_brief_data(ProtocolAwid* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -195,9 +195,9 @@ void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - string_cat_printf(result, "ID: %03u,%05u", facility, card_id); + furi_string_cat_printf(result, "ID: %03u,%05u", facility, card_id); } else { - string_cat_printf(result, "Data: unknown"); + furi_string_cat_printf(result, "Data: unknown"); } }; diff --git a/lib/lfrfid/protocols/protocol_em4100.c b/lib/lfrfid/protocols/protocol_em4100.c index 6959f753..4b720dff 100644 --- a/lib/lfrfid/protocols/protocol_em4100.c +++ b/lib/lfrfid/protocols/protocol_em4100.c @@ -251,10 +251,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { // Correct protocol data by redecoding protocol_em4100_encoder_start(protocol); em4100_decode( - (uint8_t*)&protocol->encoded_data, - sizeof(EM4100DecodedData), - protocol->data, - EM4100_DECODED_DATA_SIZE); + (uint8_t*)&protocol->encoded_data, + sizeof(EM4100DecodedData), + protocol->data, + EM4100_DECODED_DATA_SIZE); protocol_em4100_encoder_start(protocol); @@ -270,9 +270,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { return result; }; -void protocol_em4100_render_data(ProtocolEM4100* protocol, string_t result) { +void protocol_em4100_render_data(ProtocolEM4100* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf(result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); + furi_string_printf( + result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); }; const ProtocolBase protocol_em4100 = { diff --git a/lib/lfrfid/protocols/protocol_fdx_a.c b/lib/lfrfid/protocols/protocol_fdx_a.c index 554b9071..058dc553 100644 --- a/lib/lfrfid/protocols/protocol_fdx_a.c +++ b/lib/lfrfid/protocols/protocol_fdx_a.c @@ -196,7 +196,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) { return result; }; -void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) { +void protocol_fdx_a_render_data(ProtocolFDXA* protocol, FuriString* result) { uint8_t data[FDXA_DECODED_DATA_SIZE]; memcpy(data, protocol->data, FDXA_DECODED_DATA_SIZE); @@ -206,7 +206,7 @@ void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) { data[i] &= 0x7F; } - string_printf( + furi_string_printf( result, "ID: %02X%02X%02X%02X%02X\r\n" "Parity: %s", diff --git a/lib/lfrfid/protocols/protocol_fdx_b.c b/lib/lfrfid/protocols/protocol_fdx_b.c index f42b4ed9..855356f2 100644 --- a/lib/lfrfid/protocols/protocol_fdx_b.c +++ b/lib/lfrfid/protocols/protocol_fdx_b.c @@ -273,7 +273,7 @@ static bool protocol_fdx_b_get_temp(const uint8_t* data, float* temp) { } } -void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { +void protocol_fdx_b_render_data(ProtocolFDXB* protocol, FuriString* result) { // 38 bits of national code uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data); @@ -287,19 +287,19 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { uint8_t replacement_number = bit_lib_get_bits(protocol->data, 60, 3); bool animal_flag = bit_lib_get_bit(protocol->data, 63); - string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); + furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { float temperature_c = (temperature - 32) / 1.8; - string_cat_printf( + furi_string_cat_printf( result, "T: %.2fF, %.2fC\r\n", (double)temperature, (double)temperature_c); } else { - string_cat_printf(result, "T: ---\r\n"); + furi_string_cat_printf(result, "T: ---\r\n"); } - string_cat_printf( + furi_string_cat_printf( result, "Bits: %X-%X-%X-%X-%X", block_status, @@ -309,7 +309,7 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { replacement_number); }; -void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) { +void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, FuriString* result) { // 38 bits of national code uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data); @@ -318,15 +318,15 @@ void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) { bool animal_flag = bit_lib_get_bit(protocol->data, 63); - string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); + furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { float temperature_c = (temperature - 32) / 1.8; - string_cat_printf(result, "T: %.2fC", (double)temperature_c); + furi_string_cat_printf(result, "T: %.2fC", (double)temperature_c); } else { - string_cat_printf(result, "T: ---"); + furi_string_cat_printf(result, "T: ---"); } }; diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 5d824530..460c23a3 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -268,15 +268,15 @@ bool protocol_gallagher_write_data(ProtocolGallagher* protocol, void* data) { return result; }; -void protocol_gallagher_render_data(ProtocolGallagher* protocol, string_t result) { +void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* result) { UNUSED(protocol); uint8_t rc = bit_lib_get_bits(protocol->data, 0, 4); uint8_t il = bit_lib_get_bits(protocol->data, 4, 4); uint32_t fc = bit_lib_get_bits_32(protocol->data, 8, 24); uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32); - string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); - string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id); + furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); + furi_string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id); }; const ProtocolBase protocol_gallagher = { diff --git a/lib/lfrfid/protocols/protocol_h10301.c b/lib/lfrfid/protocols/protocol_h10301.c index 6c50c667..2d7a3e66 100644 --- a/lib/lfrfid/protocols/protocol_h10301.c +++ b/lib/lfrfid/protocols/protocol_h10301.c @@ -340,7 +340,7 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) { // Correct protocol data by redecoding protocol_h10301_encoder_start(protocol); protocol_h10301_decode(protocol->encoded_data, protocol->data); - + protocol_h10301_encoder_start(protocol); if(request->write_type == LFRFIDWriteTypeT5577) { @@ -355,9 +355,9 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) { return result; }; -void protocol_h10301_render_data(ProtocolH10301* protocol, string_t result) { +void protocol_h10301_render_data(ProtocolH10301* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u\r\n" "Card: %u", diff --git a/lib/lfrfid/protocols/protocol_hid_ex_generic.c b/lib/lfrfid/protocols/protocol_hid_ex_generic.c index 17b75528..240128cb 100644 --- a/lib/lfrfid/protocols/protocol_hid_ex_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_ex_generic.c @@ -192,10 +192,10 @@ bool protocol_hid_ex_generic_write_data(ProtocolHIDEx* protocol, void* data) { return result; }; -void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, string_t result) { +void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, FuriString* result) { // TODO: parser and render functions UNUSED(protocol); - string_printf(result, "Generic HID Extended\r\nData: Unknown"); + furi_string_printf(result, "Generic HID Extended\r\nData: Unknown"); }; const ProtocolBase protocol_hid_ex_generic = { diff --git a/lib/lfrfid/protocols/protocol_hid_generic.c b/lib/lfrfid/protocols/protocol_hid_generic.c index da5f5b7c..e0702140 100644 --- a/lib/lfrfid/protocols/protocol_hid_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_generic.c @@ -221,25 +221,29 @@ bool protocol_hid_generic_write_data(ProtocolHID* protocol, void* data) { return result; }; -static void protocol_hid_generic_string_cat_protocol_bits(ProtocolHID* protocol, uint8_t protocol_size, string_t result) { +static void protocol_hid_generic_string_cat_protocol_bits( + ProtocolHID* protocol, + uint8_t protocol_size, + FuriString* result) { // round up to the nearest nibble const uint8_t hex_character_count = (protocol_size + 3) / 4; const uint8_t protocol_bit_index = HID_DECODED_BIT_SIZE - protocol_size; for(size_t i = 0; i < hex_character_count; i++) { - uint8_t nibble = - i == 0 ? bit_lib_get_bits( - protocol->data, protocol_bit_index, protocol_size % 4 == 0 ? 4 : protocol_size % 4) : - bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4); - string_cat_printf(result, "%X", nibble & 0xF); + uint8_t nibble = i == 0 ? bit_lib_get_bits( + protocol->data, + protocol_bit_index, + protocol_size % 4 == 0 ? 4 : protocol_size % 4) : + bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4); + furi_string_cat_printf(result, "%X", nibble & 0xF); } } -void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) { +void protocol_hid_generic_render_data(ProtocolHID* protocol, FuriString* result) { const uint8_t protocol_size = protocol_hid_generic_decode_protocol_size(protocol); if(protocol_size == HID_PROTOCOL_SIZE_UNKNOWN) { - string_printf( + furi_string_printf( result, "Generic HID Proximity\r\n" "Data: %02X%02X%02X%02X%02X%X", @@ -250,7 +254,7 @@ void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) { protocol->data[4], protocol->data[5] >> 4); } else { - string_printf( + furi_string_printf( result, "%hhu-bit HID Proximity\r\n" "Data: ", diff --git a/lib/lfrfid/protocols/protocol_indala26.c b/lib/lfrfid/protocols/protocol_indala26.c index 136ececf..cafc5848 100644 --- a/lib/lfrfid/protocols/protocol_indala26.c +++ b/lib/lfrfid/protocols/protocol_indala26.c @@ -236,7 +236,10 @@ static uint16_t get_cn(const uint8_t* data) { return cn; } -void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t result, bool brief) { +void protocol_indala26_render_data_internal( + ProtocolIndala* protocol, + FuriString* result, + bool brief) { bool wiegand_correct = true; bool checksum_correct = true; @@ -284,7 +287,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r if(odd_parity_sum % 2 != odd_parity) wiegand_correct = false; if(brief) { - string_printf( + furi_string_printf( result, "FC: %u\r\nCard: %u, Parity:%s%s", fc, @@ -292,7 +295,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r (checksum_correct ? "+" : "-"), (wiegand_correct ? "+" : "-")); } else { - string_printf( + furi_string_printf( result, "FC: %u\r\n" "Card: %u\r\n" @@ -304,10 +307,10 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r (wiegand_correct ? "+" : "-")); } } -void protocol_indala26_render_data(ProtocolIndala* protocol, string_t result) { +void protocol_indala26_render_data(ProtocolIndala* protocol, FuriString* result) { protocol_indala26_render_data_internal(protocol, result, false); } -void protocol_indala26_render_brief_data(ProtocolIndala* protocol, string_t result) { +void protocol_indala26_render_brief_data(ProtocolIndala* protocol, FuriString* result) { protocol_indala26_render_data_internal(protocol, result, true); } diff --git a/lib/lfrfid/protocols/protocol_io_prox_xsf.c b/lib/lfrfid/protocols/protocol_io_prox_xsf.c index f53eac68..71314856 100644 --- a/lib/lfrfid/protocols/protocol_io_prox_xsf.c +++ b/lib/lfrfid/protocols/protocol_io_prox_xsf.c @@ -232,9 +232,9 @@ LevelDuration protocol_io_prox_xsf_encoder_yield(ProtocolIOProxXSF* protocol) { return level_duration_make(level, duration); }; -void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t result) { +void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u\r\n" "VС: %u\r\n" @@ -244,9 +244,9 @@ void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t resu (uint16_t)((data[2] << 8) | (data[3]))); } -void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, string_t result) { +void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u, VС: %u\r\n" "Card: %u", diff --git a/lib/lfrfid/protocols/protocol_jablotron.c b/lib/lfrfid/protocols/protocol_jablotron.c index 89a59a2d..d2c7ea79 100644 --- a/lib/lfrfid/protocols/protocol_jablotron.c +++ b/lib/lfrfid/protocols/protocol_jablotron.c @@ -160,9 +160,9 @@ LevelDuration protocol_jablotron_encoder_yield(ProtocolJablotron* protocol) { return level_duration_make(protocol->last_level, duration); }; -void protocol_jablotron_render_data(ProtocolJablotron* protocol, string_t result) { +void protocol_jablotron_render_data(ProtocolJablotron* protocol, FuriString* result) { uint64_t id = protocol_jablotron_card_id(protocol->data); - string_printf(result, "ID: %llX\r\n", id); + furi_string_printf(result, "ID: %llX\r\n", id); }; bool protocol_jablotron_write_data(ProtocolJablotron* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index 7e662554..20e44a70 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -211,13 +211,13 @@ LevelDuration protocol_keri_encoder_yield(ProtocolKeri* protocol) { return level_duration; }; -void protocol_keri_render_data(ProtocolKeri* protocol, string_t result) { +void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { uint32_t data = bit_lib_get_bits_32(protocol->data, 0, 32); uint32_t internal_id = data & 0x7FFFFFFF; uint32_t fc = 0; uint32_t cn = 0; protocol_keri_descramble(&fc, &cn, &data); - string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn); + furi_string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn); } bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_pac_stanley.c b/lib/lfrfid/protocols/protocol_pac_stanley.c index b5e1ebdd..59aaf1e6 100644 --- a/lib/lfrfid/protocols/protocol_pac_stanley.c +++ b/lib/lfrfid/protocols/protocol_pac_stanley.c @@ -57,31 +57,31 @@ static void protocol_pac_stanley_decode(ProtocolPACStanley* protocol) { } static bool protocol_pac_stanley_can_be_decoded(ProtocolPACStanley* protocol) { - // Check preamble - if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false; - if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false; - if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false; - if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false; - if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false; + // Check preamble + if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false; + if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false; + if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false; + if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false; + if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false; - // Check next preamble - if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false; + // Check next preamble + if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false; - // Checksum - uint8_t checksum = 0; - uint8_t stripped_byte; - for(size_t idx = 0; idx < 9; idx++) { - uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits( - protocol->encoded_data, - PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx), - 8)); - stripped_byte = byte & 0x7F; // discard the parity bit - if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) { - return false; - } - if(idx < 8) checksum ^= stripped_byte; + // Checksum + uint8_t checksum = 0; + uint8_t stripped_byte; + for(size_t idx = 0; idx < 9; idx++) { + uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits( + protocol->encoded_data, + PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx), + 8)); + stripped_byte = byte & 0x7F; // discard the parity bit + if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) { + return false; } - if(stripped_byte != checksum) return false; + if(idx < 8) checksum ^= stripped_byte; + } + if(stripped_byte != checksum) return false; return true; } @@ -201,9 +201,9 @@ bool protocol_pac_stanley_write_data(ProtocolPACStanley* protocol, void* data) { return result; } -void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, string_t result) { +void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + furi_string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]); } const ProtocolBase protocol_pac_stanley = { diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index b0b3e71d..6a8e33ba 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -136,26 +136,26 @@ LevelDuration protocol_paradox_encoder_yield(ProtocolParadox* protocol) { return level_duration_make(level, duration); }; -void protocol_paradox_render_data(ProtocolParadox* protocol, string_t result) { +void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8); uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); - string_cat_printf(result, "Facility: %u\r\n", fc); - string_cat_printf(result, "Card: %lu\r\n", card_id); - string_cat_printf(result, "Data: "); + furi_string_cat_printf(result, "Facility: %u\r\n", fc); + furi_string_cat_printf(result, "Card: %lu\r\n", card_id); + furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) { - string_cat_printf(result, "%02X", decoded_data[i]); + furi_string_cat_printf(result, "%02X", decoded_data[i]); } }; -void protocol_paradox_render_brief_data(ProtocolParadox* protocol, string_t result) { +void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8); uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); - string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id); + furi_string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id); }; bool protocol_paradox_write_data(ProtocolParadox* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index 1bba9871..2e1b57ed 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -238,11 +238,11 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) { return result; }; -void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) { +void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: 26\r\n", format_length); + furi_string_cat_printf(result, "Format: 26\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8); @@ -250,9 +250,9 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 16); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 24); - string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id); + furi_string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id); } else { - string_cat_printf(result, "Data: unknown"); + furi_string_cat_printf(result, "Data: unknown"); } }; diff --git a/lib/lfrfid/protocols/protocol_viking.c b/lib/lfrfid/protocols/protocol_viking.c index f252cc2c..8083f6d9 100644 --- a/lib/lfrfid/protocols/protocol_viking.c +++ b/lib/lfrfid/protocols/protocol_viking.c @@ -175,9 +175,9 @@ bool protocol_viking_write_data(ProtocolViking* protocol, void* data) { return result; }; -void protocol_viking_render_data(ProtocolViking* protocol, string_t result) { +void protocol_viking_render_data(ProtocolViking* protocol, FuriString* result) { uint32_t id = bit_lib_get_bits_32(protocol->data, 0, 32); - string_printf(result, "ID: %08lX\r\n", id); + furi_string_printf(result, "ID: %08lX\r\n", id); }; const ProtocolBase protocol_viking = { diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c index 5bb67145..57841afc 100644 --- a/lib/nfc/helpers/mf_classic_dict.c +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -66,15 +66,15 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { } // Read total amount of keys - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); while(true) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; dict->total_keys++; } - string_clear(next_line); + furi_string_free(next_line); stream_rewind(dict->stream); dict_loaded = true; @@ -99,20 +99,20 @@ void mf_classic_dict_free(MfClassicDict* dict) { free(dict); } -static void mf_classic_dict_int_to_str(uint8_t* key_int, string_t key_str) { - string_reset(key_str); +static void mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) { + furi_string_reset(key_str); for(size_t i = 0; i < 6; i++) { - string_cat_printf(key_str, "%02X", key_int[i]); + furi_string_cat_printf(key_str, "%02X", key_int[i]); } } -static void mf_classic_dict_str_to_int(string_t key_str, uint64_t* key_int) { +static void mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) { uint8_t key_byte_tmp; *key_int = 0ULL; for(uint8_t i = 0; i < 12; i += 2) { args_char_to_hex( - string_get_char(key_str, i), string_get_char(key_str, i + 1), &key_byte_tmp); + furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp); *key_int |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2); } } @@ -130,17 +130,17 @@ bool mf_classic_dict_rewind(MfClassicDict* dict) { return stream_rewind(dict->stream); } -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); bool key_read = false; - string_reset(key); + furi_string_reset(key); while(!key_read) { if(!stream_read_line(dict->stream, key)) break; - if(string_get_char(key, 0) == '#') continue; - if(string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(key, 12); + if(furi_string_get_char(key, 0) == '#') continue; + if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(key, 12); key_read = true; } @@ -151,53 +151,53 @@ bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) { furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); bool key_read = mf_classic_dict_get_next_key_str(dict, temp_key); if(key_read) { mf_classic_dict_str_to_int(temp_key, key); } - string_clear(temp_key); + furi_string_free(temp_key); return key_read; } -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); bool key_found = false; stream_rewind(dict->stream); while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(next_line, 12); - if(!string_equal_p(key, next_line)) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(next_line, 12); + if(!furi_string_equal(key, next_line)) continue; key_found = true; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) { - string_t temp_key; + FuriString* temp_key; - string_init(temp_key); + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_found = mf_classic_dict_is_key_present_str(dict, temp_key); - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } -bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); - string_cat_printf(key, "\n"); + furi_string_cat_printf(key, "\n"); bool key_added = false; do { @@ -207,7 +207,7 @@ bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) { key_added = true; } while(false); - string_left(key, 12); + furi_string_left(key, 12); return key_added; } @@ -215,35 +215,35 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) { furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_added = mf_classic_dict_add_key_str(dict, temp_key); - string_clear(temp_key); + furi_string_free(temp_key); return key_added; } -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target) { +bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; + FuriString* next_line; uint32_t index = 0; - string_init(next_line); - string_reset(key); + next_line = furi_string_alloc(); + furi_string_reset(key); bool key_found = false; while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; if(index++ != target) continue; - string_set_n(key, next_line, 0, 12); + furi_string_set_n(key, next_line, 0, 12); key_found = true; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } @@ -251,37 +251,37 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32 furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); bool key_found = mf_classic_dict_get_key_at_index_str(dict, temp_key, target); if(key_found) { mf_classic_dict_str_to_int(temp_key, key); } - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } -bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target) { +bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); bool key_found = false; uint32_t index = 0; stream_rewind(dict->stream); while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(next_line, 12); - if(!string_equal_p(key, next_line)) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(next_line, 12); + if(!furi_string_equal(key, next_line)) continue; key_found = true; *target = index; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } @@ -289,12 +289,12 @@ bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* tar furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_found = mf_classic_dict_find_index_str(dict, temp_key, target); - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } @@ -302,15 +302,15 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); uint32_t index = 0; bool key_removed = false; while(!key_removed) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; if(index++ != target) continue; stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent); if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break; @@ -318,6 +318,6 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) { key_removed = true; } - string_clear(next_line); + furi_string_free(next_line); return key_removed; } diff --git a/lib/nfc/helpers/mf_classic_dict.h b/lib/nfc/helpers/mf_classic_dict.h index 9241a37b..5b0ee312 100644 --- a/lib/nfc/helpers/mf_classic_dict.h +++ b/lib/nfc/helpers/mf_classic_dict.h @@ -48,11 +48,11 @@ bool mf_classic_dict_rewind(MfClassicDict* dict); bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key); -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key); bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key); -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key); /** Get key at target offset as uint64_t * @@ -72,7 +72,7 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32 * * @return true on success */ -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target); +bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target); bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); @@ -83,11 +83,11 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); * * @return true on success */ -bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key); bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target); -bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target); +bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target); /** Delete key at target offset * diff --git a/lib/nfc/helpers/mfkey32.c b/lib/nfc/helpers/mfkey32.c index 64b06e25..8eb417eb 100644 --- a/lib/nfc/helpers/mfkey32.c +++ b/lib/nfc/helpers/mfkey32.c @@ -91,9 +91,7 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, } static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { - string_t str; - string_init_printf( - str, + FuriString* str = furi_string_alloc_printf( "Sector %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", params->sector, params->key == MfClassicKeyA ? 'A' : 'B', @@ -105,7 +103,7 @@ static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { params->nr1, params->ar1); bool write_success = stream_write_string(instance->file_stream, str); - string_clear(str); + furi_string_free(str); return write_success; } @@ -199,14 +197,14 @@ void mfkey32_process_data( } } -uint16_t mfkey32_get_auth_sectors(string_t data_str) { +uint16_t mfkey32_get_auth_sectors(FuriString* data_str) { furi_assert(data_str); uint16_t nonces_num = 0; Storage* storage = furi_record_open(RECORD_STORAGE); Stream* file_stream = buffered_file_stream_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!buffered_file_stream_open( @@ -214,17 +212,17 @@ uint16_t mfkey32_get_auth_sectors(string_t data_str) { break; while(true) { if(!stream_read_line(file_stream, temp_str)) break; - size_t uid_pos = string_search_str(temp_str, "cuid"); - string_left(temp_str, uid_pos); - string_push_back(temp_str, '\n'); - string_cat(data_str, temp_str); + size_t uid_pos = furi_string_search(temp_str, "cuid"); + furi_string_left(temp_str, uid_pos); + furi_string_push_back(temp_str, '\n'); + furi_string_cat(data_str, temp_str); nonces_num++; } } while(false); buffered_file_stream_close(file_stream); stream_free(file_stream); - string_clear(temp_str); + furi_string_free(temp_str); return nonces_num; } diff --git a/lib/nfc/helpers/mfkey32.h b/lib/nfc/helpers/mfkey32.h index c4f13cc2..e1f472e5 100644 --- a/lib/nfc/helpers/mfkey32.h +++ b/lib/nfc/helpers/mfkey32.h @@ -1,7 +1,6 @@ #pragma once #include -#include typedef struct Mfkey32 Mfkey32; @@ -24,4 +23,4 @@ void mfkey32_process_data( void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context); -uint16_t mfkey32_get_auth_sectors(string_t string); +uint16_t mfkey32_get_auth_sectors(FuriString* string); diff --git a/lib/nfc/helpers/nfc_debug_log.c b/lib/nfc/helpers/nfc_debug_log.c index 1cbc5224..0bfbc2c6 100644 --- a/lib/nfc/helpers/nfc_debug_log.c +++ b/lib/nfc/helpers/nfc_debug_log.c @@ -1,6 +1,5 @@ #include "nfc_debug_log.h" -#include #include #include @@ -10,7 +9,7 @@ struct NfcDebugLog { Stream* file_stream; - string_t data_str; + FuriString* data_str; }; NfcDebugLog* nfc_debug_log_alloc() { @@ -30,7 +29,7 @@ NfcDebugLog* nfc_debug_log_alloc() { free(instance); instance = NULL; } else { - string_init(instance->data_str); + instance->data_str = furi_string_alloc(); } furi_record_close(RECORD_STORAGE); @@ -44,7 +43,7 @@ void nfc_debug_log_free(NfcDebugLog* instance) { buffered_file_stream_close(instance->file_stream); stream_free(instance->file_stream); - string_clear(instance->data_str); + furi_string_free(instance->data_str); free(instance); } @@ -61,12 +60,12 @@ void nfc_debug_log_process_data( furi_assert(data); UNUSED(crc_dropped); - string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); + furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); uint16_t data_len = len; for(size_t i = 0; i < data_len; i++) { - string_cat_printf(instance->data_str, " %02x", data[i]); + furi_string_cat_printf(instance->data_str, " %02x", data[i]); } - string_push_back(instance->data_str, '\n'); + furi_string_push_back(instance->data_str, '\n'); stream_write_string(instance->file_stream, instance->data_str); } diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index dd78e2da..f28d4d5b 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -1,6 +1,5 @@ #include "nfc_device.h" #include "assets_icons.h" -#include "m-string.h" #include "nfc_types.h" #include @@ -25,8 +24,8 @@ NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); nfc_dev->storage = furi_record_open(RECORD_STORAGE); nfc_dev->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(nfc_dev->load_path); - string_init(nfc_dev->dev_data.parsed_data); + nfc_dev->load_path = furi_string_alloc(); + nfc_dev->dev_data.parsed_data = furi_string_alloc(); return nfc_dev; } @@ -35,53 +34,53 @@ void nfc_device_free(NfcDevice* nfc_dev) { nfc_device_clear(nfc_dev); furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_DIALOGS); - string_clear(nfc_dev->load_path); - string_clear(nfc_dev->dev_data.parsed_data); + furi_string_free(nfc_dev->load_path); + furi_string_free(nfc_dev->dev_data.parsed_data); free(nfc_dev); } -static void nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string) { +static void nfc_device_prepare_format_string(NfcDevice* dev, FuriString* format_string) { if(dev->format == NfcDeviceSaveFormatUid) { - string_set_str(format_string, "UID"); + furi_string_set(format_string, "UID"); } else if(dev->format == NfcDeviceSaveFormatBankCard) { - string_set_str(format_string, "Bank card"); + furi_string_set(format_string, "Bank card"); } else if(dev->format == NfcDeviceSaveFormatMifareUl) { - string_set_str(format_string, nfc_mf_ul_type(dev->dev_data.mf_ul_data.type, true)); + furi_string_set(format_string, nfc_mf_ul_type(dev->dev_data.mf_ul_data.type, true)); } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { - string_set_str(format_string, "Mifare Classic"); + furi_string_set(format_string, "Mifare Classic"); } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { - string_set_str(format_string, "Mifare DESFire"); + furi_string_set(format_string, "Mifare DESFire"); } else { - string_set_str(format_string, "Unknown"); + furi_string_set(format_string, "Unknown"); } } -static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) { - if(string_start_with_str_p(format_string, "UID")) { +static bool nfc_device_parse_format_string(NfcDevice* dev, FuriString* format_string) { + if(furi_string_start_with_str(format_string, "UID")) { dev->format = NfcDeviceSaveFormatUid; dev->dev_data.protocol = NfcDeviceProtocolUnknown; return true; } - if(string_start_with_str_p(format_string, "Bank card")) { + if(furi_string_start_with_str(format_string, "Bank card")) { dev->format = NfcDeviceSaveFormatBankCard; dev->dev_data.protocol = NfcDeviceProtocolEMV; return true; } // Check Mifare Ultralight types for(MfUltralightType type = MfUltralightTypeUnknown; type < MfUltralightTypeNum; type++) { - if(string_equal_str_p(format_string, nfc_mf_ul_type(type, true))) { + if(furi_string_equal(format_string, nfc_mf_ul_type(type, true))) { dev->format = NfcDeviceSaveFormatMifareUl; dev->dev_data.protocol = NfcDeviceProtocolMifareUl; dev->dev_data.mf_ul_data.type = type; return true; } } - if(string_start_with_str_p(format_string, "Mifare Classic")) { + if(furi_string_start_with_str(format_string, "Mifare Classic")) { dev->format = NfcDeviceSaveFormatMifareClassic; dev->dev_data.protocol = NfcDeviceProtocolMifareClassic; return true; } - if(string_start_with_str_p(format_string, "Mifare DESFire")) { + if(furi_string_start_with_str(format_string, "Mifare DESFire")) { dev->format = NfcDeviceSaveFormatMifareDesfire; dev->dev_data.protocol = NfcDeviceProtocolMifareDesfire; return true; @@ -92,8 +91,8 @@ static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_strin static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; MfUltralightData* data = &dev->dev_data.mf_ul_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); // Save Mifare Ultralight specific data do { @@ -109,14 +108,15 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) // Write conters and tearing flags data bool counters_saved = true; for(uint8_t i = 0; i < 3; i++) { - string_printf(temp_str, "Counter %d", i); + furi_string_printf(temp_str, "Counter %d", i); if(!flipper_format_write_uint32( - file, string_get_cstr(temp_str), &data->counter[i], 1)) { + file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { counters_saved = false; break; } - string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_write_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + furi_string_printf(temp_str, "Tearing %d", i); + if(!flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { counters_saved = false; break; } @@ -129,8 +129,8 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) if(!flipper_format_write_uint32(file, "Pages read", &pages_read, 1)) break; bool pages_saved = true; for(uint16_t i = 0; i < data->data_size; i += 4) { - string_printf(temp_str, "Page %d", i / 4); - if(!flipper_format_write_hex(file, string_get_cstr(temp_str), &data->data[i], 4)) { + furi_string_printf(temp_str, "Page %d", i / 4); + if(!flipper_format_write_hex(file, furi_string_get_cstr(temp_str), &data->data[i], 4)) { pages_saved = false; break; } @@ -145,15 +145,15 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) saved = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return saved; } bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; MfUltralightData* data = &dev->dev_data.mf_ul_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t data_format_version = 0; do { @@ -172,13 +172,15 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { // Read counters and tearing flags bool counters_parsed = true; for(uint8_t i = 0; i < 3; i++) { - string_printf(temp_str, "Counter %d", i); - if(!flipper_format_read_uint32(file, string_get_cstr(temp_str), &data->counter[i], 1)) { + furi_string_printf(temp_str, "Counter %d", i); + if(!flipper_format_read_uint32( + file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { counters_parsed = false; break; } - string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_read_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + furi_string_printf(temp_str, "Tearing %d", i); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { counters_parsed = false; break; } @@ -198,8 +200,9 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { if(data->data_size > MF_UL_MAX_DUMP_SIZE || data->data_read > MF_UL_MAX_DUMP_SIZE) break; bool pages_parsed = true; for(uint16_t i = 0; i < pages_total; i++) { - string_printf(temp_str, "Page %d", i); - if(!flipper_format_read_hex(file, string_get_cstr(temp_str), &data->data[i * 4], 4)) { + furi_string_printf(temp_str, "Page %d", i); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), &data->data[i * 4], 4)) { pages_parsed = false; break; } @@ -214,7 +217,7 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } @@ -223,38 +226,40 @@ static bool nfc_device_save_mifare_df_key_settings( MifareDesfireKeySettings* ks, const char* prefix) { bool saved = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); do { - string_printf(key, "%s Change Key ID", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Config Changeable", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->config_changeable, 1)) + furi_string_printf(key, "%s Change Key ID", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Free Create Delete", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->free_create_delete, 1)) + furi_string_printf(key, "%s Config Changeable", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Directory List", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->free_directory_list, 1)) + furi_string_printf(key, "%s Free Create Delete", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->free_create_delete, 1)) break; - string_printf(key, "%s Key Changeable", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->master_key_changeable, 1)) + furi_string_printf(key, "%s Free Directory List", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->free_directory_list, 1)) + break; + furi_string_printf(key, "%s Key Changeable", prefix); + if(!flipper_format_write_bool( + file, furi_string_get_cstr(key), &ks->master_key_changeable, 1)) break; if(ks->flags) { - string_printf(key, "%s Flags", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->flags, 1)) break; + furi_string_printf(key, "%s Flags", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->flags, 1)) break; } - string_printf(key, "%s Max Keys", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->max_keys, 1)) break; + furi_string_printf(key, "%s Max Keys", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->max_keys, 1)) break; for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) { - string_printf(key, "%s Key %d Version", prefix, kv->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &kv->version, 1)) break; + furi_string_printf(key, "%s Key %d Version", prefix, kv->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &kv->version, 1)) break; } saved = true; } while(false); - string_clear(key); + furi_string_free(key); return saved; } @@ -263,36 +268,38 @@ bool nfc_device_load_mifare_df_key_settings( MifareDesfireKeySettings* ks, const char* prefix) { bool parsed = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); do { - string_printf(key, "%s Change Key ID", prefix); - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Config Changeable", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Create Delete", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->free_create_delete, 1)) + furi_string_printf(key, "%s Change Key ID", prefix); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->change_key_id, 1)) break; + furi_string_printf(key, "%s Config Changeable", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Directory List", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->free_directory_list, 1)) + furi_string_printf(key, "%s Free Create Delete", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->free_create_delete, 1)) break; - string_printf(key, "%s Key Changeable", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->master_key_changeable, 1)) + furi_string_printf(key, "%s Free Directory List", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->free_directory_list, 1)) break; - string_printf(key, "%s Flags", prefix); - if(flipper_format_key_exist(file, string_get_cstr(key))) { - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->flags, 1)) break; + furi_string_printf(key, "%s Key Changeable", prefix); + if(!flipper_format_read_bool( + file, furi_string_get_cstr(key), &ks->master_key_changeable, 1)) + break; + furi_string_printf(key, "%s Flags", prefix); + if(flipper_format_key_exist(file, furi_string_get_cstr(key))) { + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->flags, 1)) break; } - string_printf(key, "%s Max Keys", prefix); - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->max_keys, 1)) break; + furi_string_printf(key, "%s Max Keys", prefix); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->max_keys, 1)) break; ks->flags |= ks->max_keys >> 4; ks->max_keys &= 0xF; MifareDesfireKeyVersion** kv_head = &ks->key_version_head; for(int key_id = 0; key_id < ks->max_keys; key_id++) { - string_printf(key, "%s Key %d Version", prefix, key_id); + furi_string_printf(key, "%s Key %d Version", prefix, key_id); uint8_t version; - if(flipper_format_read_hex(file, string_get_cstr(key), &version, 1)) { + if(flipper_format_read_hex(file, furi_string_get_cstr(key), &version, 1)) { MifareDesfireKeyVersion* kv = malloc(sizeof(MifareDesfireKeyVersion)); memset(kv, 0, sizeof(MifareDesfireKeyVersion)); kv->id = key_id; @@ -304,21 +311,22 @@ bool nfc_device_load_mifare_df_key_settings( parsed = true; } while(false); - string_clear(key); + furi_string_free(key); return parsed; } static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireApplication* app) { bool saved = false; - string_t prefix, key; - string_init_printf(prefix, "Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); - string_init(key); + FuriString *prefix, *key; + prefix = + furi_string_alloc_printf("Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); + key = furi_string_alloc(); uint8_t* tmp = NULL; do { if(app->key_settings) { if(!nfc_device_save_mifare_df_key_settings( - file, app->key_settings, string_get_cstr(prefix))) + file, app->key_settings, furi_string_get_cstr(prefix))) break; } if(!app->file_head) break; @@ -331,68 +339,75 @@ static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireAppl for(MifareDesfireFile* f = app->file_head; f; f = f->next) { tmp[i++] = f->id; } - string_printf(key, "%s File IDs", string_get_cstr(prefix)); - if(!flipper_format_write_hex(file, string_get_cstr(key), tmp, n_files)) break; + furi_string_printf(key, "%s File IDs", furi_string_get_cstr(prefix)); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), tmp, n_files)) break; bool saved_files = true; for(MifareDesfireFile* f = app->file_head; f; f = f->next) { saved_files = false; - string_printf(key, "%s File %d Type", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &f->type, 1)) break; - string_printf( - key, "%s File %d Communication Settings", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &f->comm, 1)) break; - string_printf(key, "%s File %d Access Rights", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Type", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &f->type, 1)) break; + furi_string_printf( + key, "%s File %d Communication Settings", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &f->comm, 1)) break; + furi_string_printf( + key, "%s File %d Access Rights", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_hex( - file, string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) + file, furi_string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) break; uint16_t size = 0; if(f->type == MifareDesfireFileTypeStandard || f->type == MifareDesfireFileTypeBackup) { size = f->settings.data.size; - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.data.size, 1)) + file, furi_string_get_cstr(key), &f->settings.data.size, 1)) break; } else if(f->type == MifareDesfireFileTypeValue) { - string_printf(key, "%s File %d Hi Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Hi Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.hi_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.hi_limit, 1)) break; - string_printf(key, "%s File %d Lo Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Lo Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.lo_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.lo_limit, 1)) break; - string_printf( - key, "%s File %d Limited Credit Value", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Value", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) + file, furi_string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) break; - string_printf( - key, "%s File %d Limited Credit Enabled", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Enabled", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_bool( - file, string_get_cstr(key), &f->settings.value.limited_credit_enabled, 1)) + file, + furi_string_get_cstr(key), + &f->settings.value.limited_credit_enabled, + 1)) break; size = 4; } else if( f->type == MifareDesfireFileTypeLinearRecord || f->type == MifareDesfireFileTypeCyclicRecord) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.size, 1)) + file, furi_string_get_cstr(key), &f->settings.record.size, 1)) break; - string_printf(key, "%s File %d Max", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Max", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.max, 1)) + file, furi_string_get_cstr(key), &f->settings.record.max, 1)) break; - string_printf(key, "%s File %d Cur", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Cur", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.cur, 1)) + file, furi_string_get_cstr(key), &f->settings.record.cur, 1)) break; size = f->settings.record.size * f->settings.record.cur; } if(f->contents) { - string_printf(key, "%s File %d", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), f->contents, size)) break; + furi_string_printf(key, "%s File %d", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), f->contents, size)) + break; } saved_files = true; } @@ -403,16 +418,17 @@ static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireAppl } while(false); free(tmp); - string_clear(prefix); - string_clear(key); + furi_string_free(prefix); + furi_string_free(key); return saved; } bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication* app) { bool parsed = false; - string_t prefix, key; - string_init_printf(prefix, "Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); - string_init(key); + FuriString *prefix, *key; + prefix = + furi_string_alloc_printf("Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); + key = furi_string_alloc(); uint8_t* tmp = NULL; MifareDesfireFile* f = NULL; @@ -420,16 +436,16 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication app->key_settings = malloc(sizeof(MifareDesfireKeySettings)); memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings)); if(!nfc_device_load_mifare_df_key_settings( - file, app->key_settings, string_get_cstr(prefix))) { + file, app->key_settings, furi_string_get_cstr(prefix))) { free(app->key_settings); app->key_settings = NULL; break; } - string_printf(key, "%s File IDs", string_get_cstr(prefix)); + furi_string_printf(key, "%s File IDs", furi_string_get_cstr(prefix)); uint32_t n_files; - if(!flipper_format_get_value_count(file, string_get_cstr(key), &n_files)) break; + if(!flipper_format_get_value_count(file, furi_string_get_cstr(key), &n_files)) break; tmp = malloc(n_files); - if(!flipper_format_read_hex(file, string_get_cstr(key), tmp, n_files)) break; + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), tmp, n_files)) break; MifareDesfireFile** file_head = &app->file_head; bool parsed_files = true; for(uint32_t i = 0; i < n_files; i++) { @@ -437,61 +453,69 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication f = malloc(sizeof(MifareDesfireFile)); memset(f, 0, sizeof(MifareDesfireFile)); f->id = tmp[i]; - string_printf(key, "%s File %d Type", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), &f->type, 1)) break; - string_printf( - key, "%s File %d Communication Settings", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), &f->comm, 1)) break; - string_printf(key, "%s File %d Access Rights", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) + furi_string_printf(key, "%s File %d Type", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &f->type, 1)) break; + furi_string_printf( + key, "%s File %d Communication Settings", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &f->comm, 1)) break; + furi_string_printf( + key, "%s File %d Access Rights", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) break; if(f->type == MifareDesfireFileTypeStandard || f->type == MifareDesfireFileTypeBackup) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.data.size, 1)) + file, furi_string_get_cstr(key), &f->settings.data.size, 1)) break; } else if(f->type == MifareDesfireFileTypeValue) { - string_printf(key, "%s File %d Hi Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Hi Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.hi_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.hi_limit, 1)) break; - string_printf(key, "%s File %d Lo Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Lo Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.lo_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.lo_limit, 1)) break; - string_printf( - key, "%s File %d Limited Credit Value", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Value", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) + file, furi_string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) break; - string_printf( - key, "%s File %d Limited Credit Enabled", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Enabled", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_bool( - file, string_get_cstr(key), &f->settings.value.limited_credit_enabled, 1)) + file, + furi_string_get_cstr(key), + &f->settings.value.limited_credit_enabled, + 1)) break; } else if( f->type == MifareDesfireFileTypeLinearRecord || f->type == MifareDesfireFileTypeCyclicRecord) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.size, 1)) + file, furi_string_get_cstr(key), &f->settings.record.size, 1)) break; - string_printf(key, "%s File %d Max", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Max", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.max, 1)) + file, furi_string_get_cstr(key), &f->settings.record.max, 1)) break; - string_printf(key, "%s File %d Cur", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Cur", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.cur, 1)) + file, furi_string_get_cstr(key), &f->settings.record.cur, 1)) break; } - string_printf(key, "%s File %d", string_get_cstr(prefix), f->id); - if(flipper_format_key_exist(file, string_get_cstr(key))) { + furi_string_printf(key, "%s File %d", furi_string_get_cstr(prefix), f->id); + if(flipper_format_key_exist(file, furi_string_get_cstr(key))) { uint32_t size; - if(!flipper_format_get_value_count(file, string_get_cstr(key), &size)) break; + if(!flipper_format_get_value_count(file, furi_string_get_cstr(key), &size)) break; f->contents = malloc(size); - if(!flipper_format_read_hex(file, string_get_cstr(key), f->contents, size)) break; + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), f->contents, size)) + break; } *file_head = f; file_head = &f->next; @@ -509,8 +533,8 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication free(f); } free(tmp); - string_clear(prefix); - string_clear(key); + furi_string_free(prefix); + furi_string_free(key); return parsed; } @@ -646,8 +670,8 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { EmvData* data = &dev->dev_data.emv_data; memset(data, 0, sizeof(EmvData)); uint32_t data_cnt = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { // Load essential data @@ -655,7 +679,7 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { data->aid_len = data_cnt; if(!flipper_format_read_hex(file, "AID", data->aid, data->aid_len)) break; if(!flipper_format_read_string(file, "Name", temp_str)) break; - strlcpy(data->name, string_get_cstr(temp_str), sizeof(data->name)); + strlcpy(data->name, furi_string_get_cstr(temp_str), sizeof(data->name)); if(!flipper_format_get_value_count(file, "Number", &data_cnt)) break; data->number_len = data_cnt; if(!flipper_format_read_hex(file, "Number", data->number, data->number_len)) break; @@ -674,15 +698,15 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { } } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } static void nfc_device_write_mifare_classic_block( - string_t block_str, + FuriString* block_str, MfClassicData* data, uint8_t block_num) { - string_reset(block_str); + furi_string_reset(block_str); bool is_sec_trailer = mf_classic_is_sector_trailer(block_num); if(is_sec_trailer) { uint8_t sector_num = mf_classic_get_sector_by_block(block_num); @@ -690,45 +714,45 @@ static void nfc_device_write_mifare_classic_block( // Write key A for(size_t i = 0; i < sizeof(sec_tr->key_a); i++) { if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) { - string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } // Write Access bytes for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i++) { if(mf_classic_is_block_read(data, block_num)) { - string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } // Write key B for(size_t i = 0; i < sizeof(sec_tr->key_b); i++) { if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) { - string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } } else { // Write data block for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { if(mf_classic_is_block_read(data, block_num)) { - string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); + furi_string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } } - string_strim(block_str); + furi_string_trim(block_str); } static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint16_t blocks = 0; // Save Mifare Classic specific data @@ -749,39 +773,39 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* file, "Mifare Classic blocks, \'??\' means unknown data")) break; bool block_saved = true; - string_t block_str; - string_init(block_str); + FuriString* block_str; + block_str = furi_string_alloc(); for(size_t i = 0; i < blocks; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); nfc_device_write_mifare_classic_block(block_str, data, i); - if(!flipper_format_write_string(file, string_get_cstr(temp_str), block_str)) { + if(!flipper_format_write_string(file, furi_string_get_cstr(temp_str), block_str)) { block_saved = false; break; } } - string_clear(block_str); + furi_string_free(block_str); if(!block_saved) break; saved = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return saved; } static void nfc_device_load_mifare_classic_block( - string_t block_str, + FuriString* block_str, MfClassicData* data, uint8_t block_num) { - string_strim(block_str); + furi_string_trim(block_str); MfClassicBlock block_tmp = {}; bool is_sector_trailer = mf_classic_is_sector_trailer(block_num); uint8_t sector_num = mf_classic_get_sector_by_block(block_num); uint16_t block_unknown_bytes_mask = 0; - string_strim(block_str); + furi_string_trim(block_str); for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { - char hi = string_get_char(block_str, 3 * i); - char low = string_get_char(block_str, 3 * i + 1); + char hi = furi_string_get_char(block_str, 3 * i); + char low = furi_string_get_char(block_str, 3 * i + 1); uint8_t byte = 0; if(hex_char_to_uint8(hi, low, &byte)) { block_tmp.value[i] = byte; @@ -824,19 +848,19 @@ static void nfc_device_load_mifare_classic_block( static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; + FuriString* temp_str; uint32_t data_format_version = 0; - string_init(temp_str); + temp_str = furi_string_alloc(); uint16_t data_blocks = 0; memset(data, 0, sizeof(MfClassicData)); do { // Read Mifare Classic type if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!string_cmp_str(temp_str, "1K")) { + if(!furi_string_cmp(temp_str, "1K")) { data->type = MfClassicType1k; data_blocks = 64; - } else if(!string_cmp_str(temp_str, "4K")) { + } else if(!furi_string_cmp(temp_str, "4K")) { data->type = MfClassicType4k; data_blocks = 256; } else { @@ -857,17 +881,17 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* // Read Mifare Classic blocks bool block_read = true; - string_t block_str; - string_init(block_str); + FuriString* block_str; + block_str = furi_string_alloc(); for(size_t i = 0; i < data_blocks; i++) { - string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_string(file, string_get_cstr(temp_str), block_str)) { + furi_string_printf(temp_str, "Block %d", i); + if(!flipper_format_read_string(file, furi_string_get_cstr(temp_str), block_str)) { block_read = false; break; } nfc_device_load_mifare_classic_block(block_str, data, i); } - string_clear(block_str); + furi_string_free(block_str); if(!block_read) break; // Set keys and blocks as unknown for backward compatibility @@ -880,32 +904,32 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } -static void nfc_device_get_key_cache_file_path(NfcDevice* dev, string_t file_path) { +static void nfc_device_get_key_cache_file_path(NfcDevice* dev, FuriString* file_path) { uint8_t* uid = dev->dev_data.nfc_data.uid; uint8_t uid_len = dev->dev_data.nfc_data.uid_len; - string_set_str(file_path, NFC_DEVICE_KEYS_FOLDER "/"); + furi_string_set(file_path, NFC_DEVICE_KEYS_FOLDER "/"); for(size_t i = 0; i < uid_len; i++) { - string_cat_printf(file_path, "%02X", uid[i]); + furi_string_cat_printf(file_path, "%02X", uid[i]); } - string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); + furi_string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); } static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { FlipperFormat* file = flipper_format_file_alloc(dev->storage); MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); nfc_device_get_key_cache_file_path(dev, temp_str); bool save_success = false; do { if(!storage_simply_mkdir(dev->storage, NFC_DEVICE_KEYS_FOLDER)) break; - if(!storage_simply_remove(dev->storage, string_get_cstr(temp_str))) break; - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version)) break; if(data->type == MfClassicType1k) { @@ -920,29 +944,29 @@ static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { for(size_t i = 0; (i < sector_num) && (key_save_success); i++) { MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key A sector %d", i); - key_save_success = - flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + furi_string_printf(temp_str, "Key A sector %d", i); + key_save_success = flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); } if(!key_save_success) break; if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key B sector %d", i); - key_save_success = - flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + furi_string_printf(temp_str, "Key B sector %d", i); + key_save_success = flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); } } save_success = key_save_success; } while(false); flipper_format_free(file); - string_clear(temp_str); + furi_string_free(temp_str); return save_success; } bool nfc_device_load_key_cache(NfcDevice* dev) { furi_assert(dev); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); MfClassicData* data = &dev->dev_data.mf_classic_data; nfc_device_get_key_cache_file_path(dev, temp_str); @@ -950,16 +974,17 @@ bool nfc_device_load_key_cache(NfcDevice* dev) { bool load_success = false; do { - if(storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) != FSE_OK) break; - if(!flipper_format_file_open_existing(file, string_get_cstr(temp_str))) break; + if(storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) != FSE_OK) + break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break; uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_keys_file_header)) break; + if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break; if(version != nfc_keys_file_version) break; if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!string_cmp_str(temp_str, "1K")) { + if(!furi_string_cmp(temp_str, "1K")) { data->type = MfClassicType1k; - } else if(!string_cmp_str(temp_str, "4K")) { + } else if(!furi_string_cmp(temp_str, "4K")) { data->type = MfClassicType4k; } else { break; @@ -971,21 +996,21 @@ bool nfc_device_load_key_cache(NfcDevice* dev) { for(size_t i = 0; (i < sectors) && (key_read_success); i++) { MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key A sector %d", i); - key_read_success = - flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + furi_string_printf(temp_str, "Key A sector %d", i); + key_read_success = flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); } if(!key_read_success) break; if(FURI_BIT(data->key_b_mask, i)) { - string_printf(temp_str, "Key B sector %d", i); - key_read_success = - flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + furi_string_printf(temp_str, "Key B sector %d", i); + key_read_success = flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); } } load_success = key_read_success; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return load_success; @@ -997,16 +1022,16 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) { strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN); } -static void nfc_device_get_path_without_ext(string_t orig_path, string_t shadow_path) { +static void nfc_device_get_path_without_ext(FuriString* orig_path, FuriString* shadow_path) { // TODO: this won't work if there is ".nfc" anywhere in the path other than // at the end - size_t ext_start = string_search_str(orig_path, NFC_APP_EXTENSION); - string_set_n(shadow_path, orig_path, 0, ext_start); + size_t ext_start = furi_string_search(orig_path, NFC_APP_EXTENSION); + furi_string_set_n(shadow_path, orig_path, 0, ext_start); } -static void nfc_device_get_shadow_path(string_t orig_path, string_t shadow_path) { +static void nfc_device_get_shadow_path(FuriString* orig_path, FuriString* shadow_path) { nfc_device_get_path_without_ext(orig_path, shadow_path); - string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION); + furi_string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION); } static bool nfc_device_save_file( @@ -1020,25 +1045,25 @@ static bool nfc_device_save_file( bool saved = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); FuriHalNfcDevData* data = &dev->dev_data.nfc_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { // Get directory name - path_extract_dirname(string_get_cstr(dev->load_path), temp_str); + path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); // Create nfc directory if necessary - if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break; + if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(temp_str))) break; // Make path to file to save - string_cat_printf(temp_str, "/%s%s", dev_name, extension); + furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); } else { // Create nfc directory if necessary if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break; // First remove nfc device file if it was saved - string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); + furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); } // Open file - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; // Write header if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break; // Write nfc device type @@ -1072,7 +1097,7 @@ static bool nfc_device_save_file( if(!saved) { dialog_message_show_storage_error(dev->dialogs, "Can not save\nkey file"); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return saved; } @@ -1086,13 +1111,13 @@ bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_SHADOW_EXTENSION, true); } -static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog) { +static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dialog) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); FuriHalNfcDevData* data = &dev->dev_data.nfc_data; uint32_t data_cnt = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool deprecated_version = false; if(dev->loading_cb) { @@ -1103,17 +1128,17 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog // Check existance of shadow file nfc_device_get_shadow_path(path, temp_str); dev->shadow_file_exist = - storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; + storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) == FSE_OK; // Open shadow file if it exists. If not - open original if(dev->shadow_file_exist) { - if(!flipper_format_file_open_existing(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break; } else { - if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; } // Read and verify file header uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { + if(furi_string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { deprecated_version = true; break; } @@ -1152,7 +1177,7 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog } } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; } @@ -1162,15 +1187,15 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) { furi_assert(file_path); // Load device data - string_set_str(dev->load_path, file_path); + furi_string_set(dev->load_path, file_path); bool dev_load = nfc_device_load_data(dev, dev->load_path, show_dialog); if(dev_load) { // Set device name - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename_no_ext(file_path, filename); - nfc_device_set_name(dev, string_get_cstr(filename)); - string_clear(filename); + nfc_device_set_name(dev, furi_string_get_cstr(filename)); + furi_string_free(filename); } return dev_load; @@ -1180,8 +1205,8 @@ bool nfc_file_select(NfcDevice* dev) { furi_assert(dev); // Input events and views are managed by file_browser - string_t nfc_app_folder; - string_init_set_str(nfc_app_folder, NFC_APP_FOLDER); + FuriString* nfc_app_folder; + nfc_app_folder = furi_string_alloc_set(NFC_APP_FOLDER); const DialogsFileBrowserOptions browser_options = { .extension = NFC_APP_EXTENSION, @@ -1195,17 +1220,17 @@ bool nfc_file_select(NfcDevice* dev) { bool res = dialog_file_browser_show(dev->dialogs, dev->load_path, nfc_app_folder, &browser_options); - string_clear(nfc_app_folder); + furi_string_free(nfc_app_folder); if(res) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, string_get_cstr(filename), NFC_DEV_NAME_MAX_LEN); + strncpy(dev->dev_name, furi_string_get_cstr(filename), NFC_DEV_NAME_MAX_LEN); res = nfc_device_load_data(dev, dev->load_path, true); if(res) { nfc_device_set_name(dev, dev->dev_name); } - string_clear(filename); + furi_string_free(filename); } return res; @@ -1223,7 +1248,7 @@ void nfc_device_data_clear(NfcDeviceData* dev_data) { } memset(&dev_data->nfc_data, 0, sizeof(FuriHalNfcDevData)); dev_data->protocol = NfcDeviceProtocolUnknown; - string_reset(dev_data->parsed_data); + furi_string_reset(dev_data->parsed_data); } void nfc_device_clear(NfcDevice* dev) { @@ -1232,33 +1257,34 @@ void nfc_device_clear(NfcDevice* dev) { nfc_device_set_name(dev, ""); nfc_device_data_clear(&dev->dev_data); dev->format = NfcDeviceSaveFormatUid; - string_reset(dev->load_path); + furi_string_reset(dev->load_path); } bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { furi_assert(dev); bool deleted = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { // Delete original file - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(file_path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(file_path, dev->load_path); } else { - string_printf(file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); + furi_string_printf( + file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; // Delete shadow file if it exists if(dev->shadow_file_exist) { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { nfc_device_get_shadow_path(dev->load_path, file_path); } else { - string_printf( + furi_string_printf( file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; } deleted = true; } while(0); @@ -1267,7 +1293,7 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); } - string_clear(file_path); + furi_string_free(file_path); return deleted; } @@ -1276,29 +1302,29 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { furi_assert(dev->shadow_file_exist); bool restored = false; - string_t path; + FuriString* path; - string_init(path); + path = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { nfc_device_get_shadow_path(dev->load_path, path); } else { - string_printf( + furi_string_printf( path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(path))) break; dev->shadow_file_exist = false; - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(path, dev->load_path); } else { - string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); + furi_string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); } if(!nfc_device_load_data(dev, path, true)) break; restored = true; } while(0); - string_clear(path); + furi_string_free(path); return restored; } diff --git a/lib/nfc/nfc_device.h b/lib/nfc/nfc_device.h index f9a0b24b..6cac72c6 100644 --- a/lib/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -60,7 +60,7 @@ typedef struct { MfClassicData mf_classic_data; MifareDesfireData mf_df_data; }; - string_t parsed_data; + FuriString* parsed_data; } NfcDeviceData; typedef struct { @@ -68,7 +68,7 @@ typedef struct { DialogsApp* dialogs; NfcDeviceData dev_data; char dev_name[NFC_DEV_NAME_MAX_LEN + 1]; - string_t load_path; + FuriString* load_path; NfcDeviceSaveFormat format; bool shadow_file_exist; diff --git a/lib/nfc/parsers/all_in_one.c b/lib/nfc/parsers/all_in_one.c index b49a32f7..f63fb7e6 100644 --- a/lib/nfc/parsers/all_in_one.c +++ b/lib/nfc/parsers/all_in_one.c @@ -107,7 +107,7 @@ bool all_in_one_parser_parse(NfcDeviceData* dev_data) { dev_data->mf_ul_data.data[4 * 4 + 5] << 4 | (dev_data->mf_ul_data.data[4 * 4 + 6] >> 4); // Format string for rides count - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#All-In-One\nNumber: %u\nRides left: %u", serial, ride_count); return true; } \ No newline at end of file diff --git a/lib/nfc/parsers/nfc_supported_card.h b/lib/nfc/parsers/nfc_supported_card.h index d34b5794..4af59ade 100644 --- a/lib/nfc/parsers/nfc_supported_card.h +++ b/lib/nfc/parsers/nfc_supported_card.h @@ -4,8 +4,6 @@ #include "../nfc_worker.h" #include "../nfc_device.h" -#include - typedef enum { NfcSupportedCardTypePlantain, NfcSupportedCardTypeTroika, diff --git a/lib/nfc/parsers/plantain_4k_parser.c b/lib/nfc/parsers/plantain_4k_parser.c index 77387707..c970d74e 100644 --- a/lib/nfc/parsers/plantain_4k_parser.c +++ b/lib/nfc/parsers/plantain_4k_parser.c @@ -118,36 +118,36 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead string_push_uint64(card_number, card_number_str); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); // The number to calculate the checksum on doesn't fit into uint64_t, idk //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); + // FuriString* luhn_checksum_str; + // luhn_checksum_str = furi_string_alloc(); // string_push_uint64(luhn_checksum, luhn_checksum_str); - string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_suffix, "-"); // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); + // furi_string_free(luhn_checksum_str); - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#Plantain\nN:%s\nBalance:%d\n", - string_get_cstr(card_number_str), + furi_string_get_cstr(card_number_str), balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/parsers/plantain_parser.c b/lib/nfc/parsers/plantain_parser.c index ff81b8e9..8ef8ee14 100644 --- a/lib/nfc/parsers/plantain_parser.c +++ b/lib/nfc/parsers/plantain_parser.c @@ -55,7 +55,7 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16; } -void string_push_uint64(uint64_t input, string_t output) { +void string_push_uint64(uint64_t input, FuriString* output) { const uint8_t base = 10; do { @@ -66,14 +66,15 @@ void string_push_uint64(uint64_t input, string_t output) { c += '0'; else c += 'A' - 10; - string_push_back(output, c); + furi_string_push_back(output, c); } while(input); // reverse string - for(uint8_t i = 0; i < string_size(output) / 2; i++) { - char c = string_get_char(output, i); - string_set_char(output, i, string_get_char(output, string_size(output) - i - 1)); - string_set_char(output, string_size(output) - i - 1, c); + for(uint8_t i = 0; i < furi_string_size(output) / 2; i++) { + char c = furi_string_get_char(output, i); + furi_string_set_char( + output, i, furi_string_get_char(output, furi_string_size(output) - i - 1)); + furi_string_set_char(output, furi_string_size(output) - i - 1, c); } } @@ -112,36 +113,36 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead string_push_uint64(card_number, card_number_str); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); // The number to calculate the checksum on doesn't fit into uint64_t, idk //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); + // FuriString* luhn_checksum_str; + // luhn_checksum_str = furi_string_alloc(); // string_push_uint64(luhn_checksum, luhn_checksum_str); - string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_suffix, "-"); // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); + // furi_string_free(luhn_checksum_str); - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#Plantain\nN:%s\nBalance:%d\n", - string_get_cstr(card_number_str), + furi_string_get_cstr(card_number_str), balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/parsers/plantain_parser.h b/lib/nfc/parsers/plantain_parser.h index d37f0dd4..65f396f1 100644 --- a/lib/nfc/parsers/plantain_parser.h +++ b/lib/nfc/parsers/plantain_parser.h @@ -8,6 +8,6 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); bool plantain_parser_parse(NfcDeviceData* dev_data); -void string_push_uint64(uint64_t input, string_t output); +void string_push_uint64(uint64_t input, FuriString* output); uint8_t plantain_calculate_luhn(uint64_t number); diff --git a/lib/nfc/parsers/troika_4k_parser.c b/lib/nfc/parsers/troika_4k_parser.c index 8c32381f..d87b4eba 100644 --- a/lib/nfc/parsers/troika_4k_parser.c +++ b/lib/nfc/parsers/troika_4k_parser.c @@ -98,7 +98,8 @@ bool troika_4k_parser_parse(NfcDeviceData* dev_data) { } number >>= 4; - string_printf(dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); + furi_string_printf( + dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); return true; } diff --git a/lib/nfc/parsers/troika_parser.c b/lib/nfc/parsers/troika_parser.c index f396b168..9c16296f 100644 --- a/lib/nfc/parsers/troika_parser.c +++ b/lib/nfc/parsers/troika_parser.c @@ -78,7 +78,7 @@ bool troika_parser_parse(NfcDeviceData* dev_data) { } number >>= 4; - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); troika_parsed = true; } while(false); diff --git a/lib/nfc/parsers/two_cities.c b/lib/nfc/parsers/two_cities.c index d052dff1..3dc97586 100644 --- a/lib/nfc/parsers/two_cities.c +++ b/lib/nfc/parsers/two_cities.c @@ -118,29 +118,29 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead string_push_uint64(card_number, card_number_str); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); // The number to calculate the checksum on doesn't fit into uint64_t, idk //uint8_t luhn_checksum = two_cities_calculate_luhn(card_number); // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); + // FuriString* luhn_checksum_str; + // luhn_checksum_str = furi_string_alloc(); // string_push_uint64(luhn_checksum, luhn_checksum_str); - string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_suffix, "-"); // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); + // furi_string_free(luhn_checksum_str); // ===== // --PLANTAIN-- @@ -158,14 +158,14 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { } troika_number >>= 4; - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#Troika+Plantain\nPN: %s\nPB: %d rur.\nTN: %d\nTB: %d rur.\n", - string_get_cstr(card_number_str), + furi_string_get_cstr(card_number_str), balance, troika_number, troika_balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index f969cdde..9dd37f1e 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -42,14 +42,14 @@ void mf_df_clear(MifareDesfireData* data) { data->app_head = NULL; } -void mf_df_cat_data(MifareDesfireData* data, string_t out) { +void mf_df_cat_data(MifareDesfireData* data, FuriString* out) { mf_df_cat_card_info(data, out); for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { mf_df_cat_application(app, out); } } -void mf_df_cat_card_info(MifareDesfireData* data, string_t out) { +void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out) { mf_df_cat_version(&data->version, out); if(data->free_memory) { mf_df_cat_free_mem(data->free_memory, out); @@ -59,8 +59,8 @@ void mf_df_cat_card_info(MifareDesfireData* data, string_t out) { } } -void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { - string_cat_printf( +void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out) { + furi_string_cat_printf( out, "%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", version->uid[0], @@ -70,7 +70,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->uid[4], version->uid[5], version->uid[6]); - string_cat_printf( + furi_string_cat_printf( out, "hw %02x type %02x sub %02x\n" " maj %02x min %02x\n" @@ -82,7 +82,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->hw_minor, version->hw_storage, version->hw_proto); - string_cat_printf( + furi_string_cat_printf( out, "sw %02x type %02x sub %02x\n" " maj %02x min %02x\n" @@ -94,7 +94,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->sw_minor, version->sw_storage, version->sw_proto); - string_cat_printf( + furi_string_cat_printf( out, "batch %02x:%02x:%02x:%02x:%02x\n" "week %d year %d\n", @@ -107,40 +107,40 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->prod_year); } -void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out) { - string_cat_printf(out, "freeMem %d\n", free_mem->bytes); +void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out) { + furi_string_cat_printf(out, "freeMem %d\n", free_mem->bytes); } -void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out) { - string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id); - string_cat_printf(out, "configChangeable %d\n", ks->config_changeable); - string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete); - string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list); - string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable); +void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out) { + furi_string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id); + furi_string_cat_printf(out, "configChangeable %d\n", ks->config_changeable); + furi_string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete); + furi_string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list); + furi_string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable); if(ks->flags) { - string_cat_printf(out, "flags %d\n", ks->flags); + furi_string_cat_printf(out, "flags %d\n", ks->flags); } - string_cat_printf(out, "maxKeys %d\n", ks->max_keys); + furi_string_cat_printf(out, "maxKeys %d\n", ks->max_keys); for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) { - string_cat_printf(out, "key %d version %d\n", kv->id, kv->version); + furi_string_cat_printf(out, "key %d version %d\n", kv->id, kv->version); } } -void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out) { - string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]); +void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out) { + furi_string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]); if(app->key_settings) { mf_df_cat_key_settings(app->key_settings, out); } } -void mf_df_cat_application(MifareDesfireApplication* app, string_t out) { +void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out) { mf_df_cat_application_info(app, out); for(MifareDesfireFile* file = app->file_head; file; file = file->next) { mf_df_cat_file(file, out); } } -void mf_df_cat_file(MifareDesfireFile* file, string_t out) { +void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { char* type = "unknown"; switch(file->type) { case MifareDesfireFileTypeStandard: @@ -171,9 +171,9 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { comm = "enciphered"; break; } - string_cat_printf(out, "File %d\n", file->id); - string_cat_printf(out, "%s %s\n", type, comm); - string_cat_printf( + furi_string_cat_printf(out, "File %d\n", file->id); + furi_string_cat_printf(out, "%s %s\n", type, comm); + furi_string_cat_printf( out, "r %d w %d rw %d c %d\n", file->access_rights >> 12 & 0xF, @@ -186,13 +186,13 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { case MifareDesfireFileTypeStandard: case MifareDesfireFileTypeBackup: size = file->settings.data.size; - string_cat_printf(out, "size %d\n", size); + furi_string_cat_printf(out, "size %d\n", size); break; case MifareDesfireFileTypeValue: size = 4; - string_cat_printf( + furi_string_cat_printf( out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit); - string_cat_printf( + furi_string_cat_printf( out, "limit %d enabled %d\n", file->settings.value.limited_credit_value, @@ -202,33 +202,33 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { case MifareDesfireFileTypeCyclicRecord: size = file->settings.record.size; num = file->settings.record.cur; - string_cat_printf(out, "size %d\n", size); - string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max); + furi_string_cat_printf(out, "size %d\n", size); + furi_string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max); break; } uint8_t* data = file->contents; if(data) { for(int rec = 0; rec < num; rec++) { - string_cat_printf(out, "record %d\n", rec); + furi_string_cat_printf(out, "record %d\n", rec); for(int ch = 0; ch < size; ch += 4) { - string_cat_printf(out, "%03x|", ch); + furi_string_cat_printf(out, "%03x|", ch); for(int i = 0; i < 4; i++) { if(ch + i < size) { - string_cat_printf(out, "%02x ", data[rec * size + ch + i]); + furi_string_cat_printf(out, "%02x ", data[rec * size + ch + i]); } else { - string_cat_printf(out, " "); + furi_string_cat_printf(out, " "); } } for(int i = 0; i < 4 && ch + i < size; i++) { if(isprint(data[rec * size + ch + i])) { - string_cat_printf(out, "%c", data[rec * size + ch + i]); + furi_string_cat_printf(out, "%c", data[rec * size + ch + i]); } else { - string_cat_printf(out, "."); + furi_string_cat_printf(out, "."); } } - string_cat_printf(out, "\n"); + furi_string_cat_printf(out, "\n"); } - string_cat_printf(out, " \n"); + furi_string_cat_printf(out, " \n"); } } } diff --git a/lib/nfc/protocols/mifare_desfire.h b/lib/nfc/protocols/mifare_desfire.h index e59743a2..963a18f5 100644 --- a/lib/nfc/protocols/mifare_desfire.h +++ b/lib/nfc/protocols/mifare_desfire.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -120,14 +119,14 @@ typedef struct { void mf_df_clear(MifareDesfireData* data); -void mf_df_cat_data(MifareDesfireData* data, string_t out); -void mf_df_cat_card_info(MifareDesfireData* data, string_t out); -void mf_df_cat_version(MifareDesfireVersion* version, string_t out); -void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out); -void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out); -void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out); -void mf_df_cat_application(MifareDesfireApplication* app, string_t out); -void mf_df_cat_file(MifareDesfireFile* file, string_t out); +void mf_df_cat_data(MifareDesfireData* data, FuriString* out); +void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out); +void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out); +void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out); +void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out); +void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out); +void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out); +void mf_df_cat_file(MifareDesfireFile* file, FuriString* out); bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); diff --git a/lib/nfc/protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c index b3d80deb..ffabe88a 100644 --- a/lib/nfc/protocols/mifare_ultralight.c +++ b/lib/nfc/protocols/mifare_ultralight.c @@ -4,7 +4,6 @@ #include "nfc_util.h" #include #include "furi_hal_nfc.h" -#include #define TAG "MfUltralight" @@ -1005,7 +1004,7 @@ static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page) return (dynamic_lock_bytes & (1 << shift)) == 0; } -static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str) { +static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* str) { // Locals to improve readability uint8_t mirror_page = emulator->config->mirror_page; uint8_t mirror_byte = emulator->config->mirror.mirror_byte; @@ -1020,14 +1019,14 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str if(mirror_conf == MfUltralightMirrorUid) return; // NTAG21x has the peculiar behavior when UID+counter selected, if UID does not fit but // counter will fit, it will actually mirror the counter - string_cat_str(str, " "); + furi_string_cat(str, " "); } else { for(int i = 0; i < 3; ++i) { - string_cat_printf(str, "%02X", emulator->data.data[i]); + furi_string_cat_printf(str, "%02X", emulator->data.data[i]); } // Skip BCC0 for(int i = 4; i < 8; ++i) { - string_cat_printf(str, "%02X", emulator->data.data[i]); + furi_string_cat_printf(str, "%02X", emulator->data.data[i]); } uid_printed = true; } @@ -1049,9 +1048,9 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str if(mirror_page == last_user_page_index - 1 && mirror_byte > 2) return; if(mirror_conf == MfUltralightMirrorUidCounter) - string_cat_str(str, uid_printed ? "x" : " "); + furi_string_cat(str, uid_printed ? "x" : " "); - string_cat_printf(str, "%06X", emulator->data.counter[2]); + furi_string_cat_printf(str, "%06X", emulator->data.counter[2]); } } } @@ -1267,14 +1266,14 @@ bool mf_ul_prepare_emulation_response( bool reset_idle = false; #ifdef FURI_DEBUG - string_t debug_buf; - string_init(debug_buf); + FuriString* debug_buf; + debug_buf = furi_string_alloc(); for(int i = 0; i < (buff_rx_len + 7) / 8; ++i) { - string_cat_printf(debug_buf, "%02x ", buff_rx[i]); + furi_string_cat_printf(debug_buf, "%02x ", buff_rx[i]); } - string_strim(debug_buf); - FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, string_get_cstr(debug_buf)); - string_reset(debug_buf); + furi_string_trim(debug_buf); + FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, furi_string_get_cstr(debug_buf)); + furi_string_reset(debug_buf); #endif // Check composite commands @@ -1328,7 +1327,7 @@ bool mf_ul_prepare_emulation_response( uint8_t src_page = start_page; uint8_t last_page_plus_one = start_page + 4; uint8_t pwd_page = emulator->page_num - 2; - string_t ascii_mirror; + FuriString* ascii_mirror = NULL; size_t ascii_mirror_len = 0; const char* ascii_mirror_cptr = NULL; uint8_t ascii_mirror_curr_page = 0; @@ -1353,10 +1352,10 @@ bool mf_ul_prepare_emulation_response( if(last_page_plus_one > ascii_mirror_curr_page && start_page + 3 >= ascii_mirror_curr_page && start_page <= ascii_mirror_curr_page + 6) { - string_init(ascii_mirror); + ascii_mirror = furi_string_alloc(); mf_ul_make_ascii_mirror(emulator, ascii_mirror); - ascii_mirror_len = string_length_u(ascii_mirror); - ascii_mirror_cptr = string_get_cstr(ascii_mirror); + ascii_mirror_len = furi_string_utf8_length(ascii_mirror); + ascii_mirror_cptr = furi_string_get_cstr(ascii_mirror); // Move pointer to where it should be to start copying if(ascii_mirror_len > 0 && ascii_mirror_curr_page < start_page && @@ -1414,8 +1413,8 @@ bool mf_ul_prepare_emulation_response( ++src_page; if(src_page >= last_page_plus_one) src_page = 0; } - if(ascii_mirror_cptr != NULL) { - string_clear(ascii_mirror); + if(ascii_mirror != NULL) { + furi_string_free(ascii_mirror); } *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; @@ -1512,12 +1511,13 @@ bool mf_ul_prepare_emulation_response( // Copy ASCII mirror // Less stringent check here, because expecting FAST_READ to // only be issued once rather than repeatedly - string_t ascii_mirror; - string_init(ascii_mirror); + FuriString* ascii_mirror; + ascii_mirror = furi_string_alloc(); mf_ul_make_ascii_mirror(emulator, ascii_mirror); - size_t ascii_mirror_len = string_length_u(ascii_mirror); + size_t ascii_mirror_len = + furi_string_utf8_length(ascii_mirror); const char* ascii_mirror_cptr = - string_get_cstr(ascii_mirror); + furi_string_get_cstr(ascii_mirror); int16_t mirror_start_offset = (emulator->config->mirror_page - start_page) * 4 + emulator->config->mirror.mirror_byte; @@ -1547,7 +1547,7 @@ bool mf_ul_prepare_emulation_response( ++ascii_mirror_cptr; } } - string_clear(ascii_mirror); + furi_string_free(ascii_mirror); } if(emulator->supported_features & MfUltralightSupportAuth) { @@ -1851,11 +1851,11 @@ bool mf_ul_prepare_emulation_response( } else if(*buff_tx_len > 0) { int count = (*buff_tx_len + 7) / 8; for(int i = 0; i < count; ++i) { - string_cat_printf(debug_buf, "%02x ", buff_tx[i]); + furi_string_cat_printf(debug_buf, "%02x ", buff_tx[i]); } - string_strim(debug_buf); - FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, string_get_cstr(debug_buf)); - string_clear(debug_buf); + furi_string_trim(debug_buf); + FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, furi_string_get_cstr(debug_buf)); + furi_string_free(debug_buf); } else { FURI_LOG_T(TAG, "Emu TX: HALT"); } diff --git a/lib/subghz/blocks/generic.c b/lib/subghz/blocks/generic.c index 353ff18b..7496aea3 100644 --- a/lib/subghz/blocks/generic.c +++ b/lib/subghz/blocks/generic.c @@ -4,7 +4,7 @@ #define TAG "SubGhzBlockGeneric" -void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str) { +void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { const char* preset_name_temp; if(!strcmp(preset_name, "AM270")) { preset_name_temp = "FuriHalSubGhzPresetOok270Async"; @@ -17,7 +17,7 @@ void subghz_block_generic_get_preset_name(const char* preset_name, string_t pres } else { preset_name_temp = "FuriHalSubGhzPresetCustom"; } - string_set(preset_str, preset_name_temp); + furi_string_set(preset_str, preset_name_temp); } bool subghz_block_generic_serialize( @@ -26,8 +26,8 @@ bool subghz_block_generic_serialize( SubGhzPresetDefinition* preset) { furi_assert(instance); bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { stream_clean(flipper_format_get_raw_stream(flipper_format)); if(!flipper_format_write_header_cstr( @@ -41,12 +41,13 @@ bool subghz_block_generic_serialize( break; } - subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr(flipper_format, "Preset", string_get_cstr(temp_str))) { + subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); + if(!flipper_format_write_string_cstr( + flipper_format, "Preset", furi_string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { if(!flipper_format_write_string_cstr( flipper_format, "Custom_preset_module", "CC1101")) { FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); @@ -79,15 +80,15 @@ bool subghz_block_generic_serialize( } res = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return res; } bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) { furi_assert(instance); bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data = 0; do { @@ -113,7 +114,7 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma res = true; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); return res; } diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 56a7fc2d..300807da 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,7 +25,7 @@ struct SubGhzBlockGeneric { * @param preset_name name preset * @param preset_str Output name preset */ -void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str); +void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str); /** * Serialize data SubGhzBlockGeneric. diff --git a/lib/subghz/protocols/base.c b/lib/subghz/protocols/base.c index 06542f5e..4ee7a3f8 100644 --- a/lib/subghz/protocols/base.c +++ b/lib/subghz/protocols/base.c @@ -11,7 +11,7 @@ void subghz_protocol_decoder_base_set_decoder_callback( bool subghz_protocol_decoder_base_get_string( SubGhzProtocolDecoderBase* decoder_base, - string_t output) { + FuriString* output) { bool status = false; if(decoder_base->protocol && decoder_base->protocol->decoder && diff --git a/lib/subghz/protocols/base.h b/lib/subghz/protocols/base.h index fdd13567..47b4e482 100644 --- a/lib/subghz/protocols/base.h +++ b/lib/subghz/protocols/base.h @@ -11,8 +11,9 @@ typedef struct SubGhzProtocolDecoderBase SubGhzProtocolDecoderBase; typedef void ( *SubGhzProtocolDecoderBaseRxCallback)(SubGhzProtocolDecoderBase* instance, void* context); -typedef void ( - *SubGhzProtocolDecoderBaseSerialize)(SubGhzProtocolDecoderBase* decoder_base, string_t output); +typedef void (*SubGhzProtocolDecoderBaseSerialize)( + SubGhzProtocolDecoderBase* decoder_base, + FuriString* output); struct SubGhzProtocolDecoderBase { // Decoder general section @@ -41,7 +42,7 @@ void subghz_protocol_decoder_base_set_decoder_callback( */ bool subghz_protocol_decoder_base_get_string( SubGhzProtocolDecoderBase* decoder_base, - string_t output); + FuriString* output); /** * Serialize data SubGhzProtocolDecoderBase. diff --git a/lib/subghz/protocols/bett.c b/lib/subghz/protocols/bett.c index c8070257..605a922c 100644 --- a/lib/subghz/protocols/bett.c +++ b/lib/subghz/protocols/bett.c @@ -323,11 +323,11 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip return ret; } -void subghz_protocol_decoder_bett_get_string(void* context, string_t output) { +void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderBETT* instance = context; uint32_t data = (uint32_t)(instance->generic.data & 0x3FFFF); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%05lX\r\n" diff --git a/lib/subghz/protocols/bett.h b/lib/subghz/protocols/bett.h index 48f32b3e..04bf46b5 100644 --- a/lib/subghz/protocols/bett.h +++ b/lib/subghz/protocols/bett.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip * @param context Pointer to a SubGhzProtocolDecoderBETT instance * @param output Resulting text */ -void subghz_protocol_decoder_bett_get_string(void* context, string_t output); +void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 53d3d078..7c037bd1 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -322,7 +322,7 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip return ret; } -void subghz_protocol_decoder_came_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCame* instance = context; @@ -333,7 +333,7 @@ void subghz_protocol_decoder_came_get_string(void* context, string_t output) { uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/came.h b/lib/subghz/protocols/came.h index c2648c05..d1ac7628 100644 --- a/lib/subghz/protocols/came.h +++ b/lib/subghz/protocols/came.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip * @param context Pointer to a SubGhzProtocolDecoderCame instance * @param output Resulting text */ -void subghz_protocol_decoder_came_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 0c3cdd8a..1349d976 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -325,7 +325,7 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCameAtomo* instance = context; subghz_protocol_came_atomo_remote_controller( @@ -333,7 +333,7 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t outpu uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/came_atomo.h b/lib/subghz/protocols/came_atomo.h index 70a79eca..aa1cffd0 100644 --- a/lib/subghz/protocols/came_atomo.h +++ b/lib/subghz/protocols/came_atomo.h @@ -69,4 +69,4 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance * @param output Resulting text */ -void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index b5b409c5..65667be2 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -446,14 +446,14 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCameTwee* instance = context; subghz_protocol_came_twee_remote_controller(&instance->generic); uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/came_twee.h b/lib/subghz/protocols/came_twee.h index 42e6ddaf..aa1f0e0d 100644 --- a/lib/subghz/protocols/came_twee.h +++ b/lib/subghz/protocols/came_twee.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance * @param output Resulting text */ -void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index 66d230d1..d2d19af2 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -451,7 +451,7 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output) { +void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderChamb_Code* instance = context; @@ -462,7 +462,7 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%03lX\r\n" @@ -474,19 +474,19 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu switch(instance->generic.data_count_bit) { case 7: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_7_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_7_CODE_DATA_TO_DIP(code_found_lo)); break; case 8: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_8_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_8_CODE_DATA_TO_DIP(code_found_lo)); break; case 9: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_9_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_9_CODE_DATA_TO_DIP(code_found_lo)); diff --git a/lib/subghz/protocols/chamberlain_code.h b/lib/subghz/protocols/chamberlain_code.h index 1ac2f9f9..923a3151 100644 --- a/lib/subghz/protocols/chamberlain_code.h +++ b/lib/subghz/protocols/chamberlain_code.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance * @param output Resulting text */ -void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output); +void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/clemsa.c b/lib/subghz/protocols/clemsa.c index 33734693..dbee0ac9 100644 --- a/lib/subghz/protocols/clemsa.c +++ b/lib/subghz/protocols/clemsa.c @@ -343,12 +343,12 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output) { +void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderClemsa* instance = context; subghz_protocol_clemsa_check_remote_controller(&instance->generic); //uint32_t data = (uint32_t)(instance->generic.data & 0xFFFFFF); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%05lX Btn %X\r\n" diff --git a/lib/subghz/protocols/clemsa.h b/lib/subghz/protocols/clemsa.h index a8398312..8287af23 100644 --- a/lib/subghz/protocols/clemsa.h +++ b/lib/subghz/protocols/clemsa.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderClemsa instance * @param output Resulting text */ -void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output); +void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c index 9122c193..eeab2576 100644 --- a/lib/subghz/protocols/doitrand.c +++ b/lib/subghz/protocols/doitrand.c @@ -337,11 +337,11 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output) { +void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderDoitrand* instance = context; subghz_protocol_doitrand_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" diff --git a/lib/subghz/protocols/doitrand.h b/lib/subghz/protocols/doitrand.h index f94d7389..c96946a1 100644 --- a/lib/subghz/protocols/doitrand.h +++ b/lib/subghz/protocols/doitrand.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance * @param output Resulting text */ -void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output); +void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 8b90f471..75f8d4e9 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -207,7 +207,7 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) { +void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; subghz_protocol_faac_slh_check_remote_controller(&instance->generic); @@ -216,7 +216,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%lX%08lX\r\n" diff --git a/lib/subghz/protocols/faac_slh.h b/lib/subghz/protocols/faac_slh.h index fe7a7926..9b18f5ea 100644 --- a/lib/subghz/protocols/faac_slh.h +++ b/lib/subghz/protocols/faac_slh.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance * @param output Resulting text */ -void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output); +void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 56c224ae..73a50926 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -317,11 +317,11 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f return ret; } -void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output) { +void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderGateTx* instance = context; subghz_protocol_gate_tx_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%06lX\r\n" diff --git a/lib/subghz/protocols/gate_tx.h b/lib/subghz/protocols/gate_tx.h index 17157681..36eeb9a9 100644 --- a/lib/subghz/protocols/gate_tx.h +++ b/lib/subghz/protocols/gate_tx.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f * @param context Pointer to a SubGhzProtocolDecoderGateTx instance * @param output Resulting text */ -void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output); +void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index 5cd16063..230f4cfe 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -350,12 +350,12 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { +void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHoltek* instance = context; subghz_protocol_holtek_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" @@ -368,8 +368,8 @@ void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { instance->generic.btn >> 4); if((instance->generic.btn & 0xF) == 0xE) { - string_cat_printf(output, "ON\r\n"); + furi_string_cat_printf(output, "ON\r\n"); } else if(((instance->generic.btn & 0xF) == 0xB)) { - string_cat_printf(output, "OFF\r\n"); + furi_string_cat_printf(output, "OFF\r\n"); } } diff --git a/lib/subghz/protocols/holtek.h b/lib/subghz/protocols/holtek.h index df7dd644..1dac783b 100644 --- a/lib/subghz/protocols/holtek.h +++ b/lib/subghz/protocols/holtek.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderHoltek instance * @param output Resulting text */ -void subghz_protocol_decoder_holtek_get_string(void* context, string_t output); +void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 451a13f5..326e79f8 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -374,12 +374,12 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize( return ret; } -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output) { +void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHoneywell_WDB* instance = context; subghz_protocol_honeywell_wdb_check_remote_controller(instance); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/honeywell_wdb.h b/lib/subghz/protocols/honeywell_wdb.h index 012b3699..c61aa822 100644 --- a/lib/subghz/protocols/honeywell_wdb.h +++ b/lib/subghz/protocols/honeywell_wdb.h @@ -108,4 +108,4 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize( * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance * @param output Resulting text */ -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output); +void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index d78bc927..d8438604 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -338,12 +338,12 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f return ret; } -void subghz_protocol_decoder_hormann_get_string(void* context, string_t output) { +void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHormann* instance = context; subghz_protocol_hormann_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s\r\n" "%dbit\r\n" diff --git a/lib/subghz/protocols/hormann.h b/lib/subghz/protocols/hormann.h index 45d6eb22..743ad0b3 100644 --- a/lib/subghz/protocols/hormann.h +++ b/lib/subghz/protocols/hormann.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f * @param context Pointer to a SubGhzProtocolDecoderHormann instance * @param output Resulting text */ -void subghz_protocol_decoder_hormann_get_string(void* context, string_t output); +void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index 91446844..a0332f9e 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -205,7 +205,7 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp return ret; } -void subghz_protocol_decoder_ido_get_string(void* context, string_t output) { +void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderIDo* instance = context; @@ -215,7 +215,7 @@ void subghz_protocol_decoder_ido_get_string(void* context, string_t output) { uint32_t code_fix = code_found_reverse & 0xFFFFFF; uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/ido.h b/lib/subghz/protocols/ido.h index 4fe4e740..67d2b4d8 100644 --- a/lib/subghz/protocols/ido.h +++ b/lib/subghz/protocols/ido.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderIDo instance * @param output Resulting text */ -void subghz_protocol_decoder_ido_get_string(void* context, string_t output); +void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index ffe52e87..14e137ca 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -434,13 +434,13 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize( return ret; } -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output) { +void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderIntertechno_V3* instance = context; subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%.11s %db\r\n" "Key:0x%08llX\r\n" @@ -453,17 +453,17 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t o if(instance->generic.data_count_bit == subghz_protocol_intertechno_v3_const.min_count_bit_for_found) { if(instance->generic.cnt >> 5) { - string_cat_printf( + furi_string_cat_printf( output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off")); } else { - string_cat_printf( + furi_string_cat_printf( output, "Ch:" CH_PATTERN " Btn:%s\r\n", CNT_TO_CH(instance->generic.cnt), (instance->generic.btn ? "On" : "Off")); } } else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) { - string_cat_printf( + furi_string_cat_printf( output, "Ch:" CH_PATTERN " Dimm:%d%%\r\n", CNT_TO_CH(instance->generic.cnt), diff --git a/lib/subghz/protocols/intertechno_v3.h b/lib/subghz/protocols/intertechno_v3.h index 65d6f61d..078d0397 100644 --- a/lib/subghz/protocols/intertechno_v3.h +++ b/lib/subghz/protocols/intertechno_v3.h @@ -108,4 +108,4 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize( * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance * @param output Resulting text */ -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output); +void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index cfb92fe8..2865309e 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -2,7 +2,6 @@ #include "keeloq_common.h" #include "../subghz_keystore.h" -#include #include #include "../blocks/const.h" @@ -131,7 +130,7 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); + res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); if(res == 0) { switch(manufacture_code->type) { case KEELOQ_LEARNING_SIMPLE: @@ -489,7 +488,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -499,7 +498,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -508,7 +507,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, seed, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -517,7 +516,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -526,7 +525,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -534,7 +533,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -548,7 +547,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -558,7 +557,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -566,7 +565,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -575,7 +574,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, seed, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -583,7 +582,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_secure_learning(fix, seed, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -592,7 +591,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -600,7 +599,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -683,7 +682,7 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl return res; } -void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) { +void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; subghz_protocol_keeloq_check_remote_controller( @@ -697,7 +696,7 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) { uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index e1485e5e..c0575bd9 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -124,4 +124,4 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance * @param output Resulting text */ -void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output); +void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index 4c0c1d4e..6c9bc461 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -2,7 +2,6 @@ #include -#include #include #define bit(x, n) (((x) >> (n)) & 1) diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 6fc10617..aad26f16 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -256,7 +256,7 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp return ret; } -void subghz_protocol_decoder_kia_get_string(void* context, string_t output) { +void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderKIA* instance = context; @@ -264,7 +264,7 @@ void subghz_protocol_decoder_kia_get_string(void* context, string_t output) { uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" diff --git a/lib/subghz/protocols/kia.h b/lib/subghz/protocols/kia.h index 743ab7cb..cf186921 100644 --- a/lib/subghz/protocols/kia.h +++ b/lib/subghz/protocols/kia.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderKIA instance * @param output Resulting text */ -void subghz_protocol_decoder_kia_get_string(void* context, string_t output); +void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c index 8f7aed79..582c4aaf 100644 --- a/lib/subghz/protocols/linear.c +++ b/lib/subghz/protocols/linear.c @@ -327,7 +327,7 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_linear_get_string(void* context, string_t output) { +void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderLinear* instance = context; @@ -338,7 +338,7 @@ void subghz_protocol_decoder_linear_get_string(void* context, string_t output) { uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/linear.h b/lib/subghz/protocols/linear.h index 035b130c..6111ad85 100644 --- a/lib/subghz/protocols/linear.h +++ b/lib/subghz/protocols/linear.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderLinear instance * @param output Resulting text */ -void subghz_protocol_decoder_linear_get_string(void* context, string_t output); +void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/magellen.c b/lib/subghz/protocols/magellen.c index 6dcc83e5..0c801c08 100644 --- a/lib/subghz/protocols/magellen.c +++ b/lib/subghz/protocols/magellen.c @@ -375,8 +375,8 @@ static void subghz_protocol_magellen_check_remote_controller(SubGhzBlockGeneric* instance->btn = (data_rev >> 16) & 0xFF; } -static void subghz_protocol_magellen_get_event_serialize(uint8_t event, string_t output) { - string_cat_printf( +static void subghz_protocol_magellen_get_event_serialize(uint8_t event, FuriString* output) { + furi_string_cat_printf( output, "%s%s%s%s%s%s%s%s", ((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") : @@ -424,11 +424,11 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_magellen_get_string(void* context, string_t output) { +void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMagellen* instance = context; subghz_protocol_magellen_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/magellen.h b/lib/subghz/protocols/magellen.h index 224f7901..226919c8 100644 --- a/lib/subghz/protocols/magellen.h +++ b/lib/subghz/protocols/magellen.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMagellen instance * @param output Resulting text */ -void subghz_protocol_decoder_magellen_get_string(void* context, string_t output); +void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index bdce6593..1c3997b9 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -373,12 +373,12 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_marantec_get_string(void* context, string_t output) { +void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMarantec* instance = context; subghz_protocol_marantec_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/marantec.h b/lib/subghz/protocols/marantec.h index 2da3c88a..5fc042e7 100644 --- a/lib/subghz/protocols/marantec.h +++ b/lib/subghz/protocols/marantec.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMarantec instance * @param output Resulting text */ -void subghz_protocol_decoder_marantec_get_string(void* context, string_t output); +void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 1501580d..40f22cfd 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -408,12 +408,12 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_megacode_get_string(void* context, string_t output) { +void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMegaCode* instance = context; subghz_protocol_megacode_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%06lX\r\n" diff --git a/lib/subghz/protocols/megacode.h b/lib/subghz/protocols/megacode.h index c8010665..0fafddb6 100644 --- a/lib/subghz/protocols/megacode.h +++ b/lib/subghz/protocols/megacode.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance * @param output Resulting text */ -void subghz_protocol_decoder_megacode_get_string(void* context, string_t output); +void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index b5a7e8c0..d6925d48 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -370,7 +370,7 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNeroRadio* instance = context; @@ -383,7 +383,7 @@ void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t outpu uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/nero_radio.h b/lib/subghz/protocols/nero_radio.h index f04dc2b3..ef270342 100644 --- a/lib/subghz/protocols/nero_radio.h +++ b/lib/subghz/protocols/nero_radio.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance * @param output Resulting text */ -void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output); +void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 66ee569c..8080bf9e 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -355,7 +355,7 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNeroSketch* instance = context; @@ -368,7 +368,7 @@ void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t outp uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/nero_sketch.h b/lib/subghz/protocols/nero_sketch.h index ab592b48..4536e704 100644 --- a/lib/subghz/protocols/nero_sketch.h +++ b/lib/subghz/protocols/nero_sketch.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance * @param output Resulting text */ -void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output); +void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index f07e9efc..06538db1 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -309,7 +309,7 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNiceFlo* instance = context; @@ -318,7 +318,7 @@ void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) instance->generic.data, instance->generic.data_count_bit); uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/nice_flo.h b/lib/subghz/protocols/nice_flo.h index 0873e81b..dd374006 100644 --- a/lib/subghz/protocols/nice_flo.h +++ b/lib/subghz/protocols/nice_flo.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance * @param output Resulting text */ -void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output); +void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 1d370e85..ffd94811 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -354,7 +354,7 @@ bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNiceFlorS* instance = context; @@ -363,7 +363,7 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t outp uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index 7d98876f..286d03d4 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance * @param output Resulting text */ -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t output); +void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/oregon2.c b/lib/subghz/protocols/oregon2.c index 84bb38be..48435502 100644 --- a/lib/subghz/protocols/oregon2.c +++ b/lib/subghz/protocols/oregon2.c @@ -5,7 +5,6 @@ #include "../blocks/math.h" #include #include -#include #define TAG "SubGhzProtocolOregon2" @@ -247,12 +246,12 @@ bool subghz_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* f // append string of the variable data static void - oregon2_var_data_append_string(uint16_t sensor_id, uint32_t var_data, string_t output) { + oregon2_var_data_append_string(uint16_t sensor_id, uint32_t var_data, FuriString* output) { uint32_t val; if(sensor_id == 0xEC40) { val = ((var_data >> 4) & 0xF) * 10 + ((var_data >> 8) & 0xF); - string_cat_printf( + furi_string_cat_printf( output, "Temp: %s%d.%d C\r\n", (var_data & 0xF) ? "-" : "+", @@ -261,7 +260,7 @@ static void } } -static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, string_t output) { +static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, FuriString* output) { uint8_t sum = fix_data & 0xF; uint8_t ref_sum = var_data & 0xFF; var_data >>= 8; @@ -275,16 +274,16 @@ static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, strin // swap calculated sum nibbles sum = (((sum >> 4) & 0xF) | (sum << 4)) & 0xFF; if(sum == ref_sum) - string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); + furi_string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); else - string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); + furi_string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); } -void subghz_protocol_decoder_oregon2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_oregon2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderOregon2* instance = context; uint16_t sensor_id = OREGON2_SENSOR_ID(instance->generic.data); - string_cat_printf( + furi_string_cat_printf( output, "%s\r\n" "ID: 0x%04lX, ch: %d%s, rc: 0x%02lX\r\n", diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index d680b2e6..e97df9b6 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -320,11 +320,11 @@ bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPhoenix_V2* instance = context; subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" diff --git a/lib/subghz/protocols/phoenix_v2.h b/lib/subghz/protocols/phoenix_v2.h index 38cadc1a..b2f18279 100644 --- a/lib/subghz/protocols/phoenix_v2.h +++ b/lib/subghz/protocols/phoenix_v2.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance * @param output Resulting text */ -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, string_t output); +void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index bd009d88..3ec35c74 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -373,12 +373,12 @@ bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_power_smart_get_string(void* context, string_t output) { +void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPowerSmart* instance = context; subghz_protocol_power_smart_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/power_smart.h b/lib/subghz/protocols/power_smart.h index f6e9571b..21e5dcf4 100644 --- a/lib/subghz/protocols/power_smart.h +++ b/lib/subghz/protocols/power_smart.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance * @param output Resulting text */ -void subghz_protocol_decoder_power_smart_get_string(void* context, string_t output); +void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index a5b8134d..c981de1b 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -351,14 +351,14 @@ bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* return res; } -void subghz_protocol_decoder_princeton_get_string(void* context, string_t output) { +void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPrinceton* instance = context; subghz_protocol_princeton_check_remote_controller(&instance->generic); uint32_t data_rev = subghz_protocol_blocks_reverse_key( instance->generic.data, instance->generic.data_count_bit); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/princeton.h b/lib/subghz/protocols/princeton.h index 9c296c4a..4e482f74 100644 --- a/lib/subghz/protocols/princeton.h +++ b/lib/subghz/protocols/princeton.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance * @param output Resulting text */ -void subghz_protocol_decoder_princeton_get_string(void* context, string_t output); +void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 0419a39a..48c3ff4d 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -29,7 +29,7 @@ struct SubGhzProtocolDecoderRAW { Storage* storage; FlipperFormat* flipper_file; uint32_t file_is_open; - string_t file_name; + FuriString* file_name; size_t sample_write; bool last_level; }; @@ -38,7 +38,7 @@ struct SubGhzProtocolEncoderRAW { SubGhzProtocolEncoderBase base; bool is_running; - string_t file_name; + FuriString* file_name; SubGhzFileEncoderWorker* file_worker_encoder; }; @@ -90,8 +90,8 @@ bool subghz_protocol_raw_save_to_file_init( instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_file = flipper_format_file_alloc(instance->storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool init = false; do { @@ -104,16 +104,17 @@ bool subghz_protocol_raw_save_to_file_init( break; } - string_set(instance->file_name, dev_name); + furi_string_set(instance->file_name, dev_name); // First remove subghz device file if it was saved - string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + furi_string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); - if(!storage_simply_remove(instance->storage, string_get_cstr(temp_str))) { + if(!storage_simply_remove(instance->storage, furi_string_get_cstr(temp_str))) { break; } // Open file - if(!flipper_format_file_open_always(instance->flipper_file, string_get_cstr(temp_str))) { + if(!flipper_format_file_open_always( + instance->flipper_file, furi_string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to open file for write: %s", temp_str); break; } @@ -130,13 +131,13 @@ bool subghz_protocol_raw_save_to_file_init( break; } - subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); + subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); if(!flipper_format_write_string_cstr( - instance->flipper_file, "Preset", string_get_cstr(temp_str))) { + instance->flipper_file, "Preset", furi_string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { if(!flipper_format_write_string_cstr( instance->flipper_file, "Custom_preset_module", "CC1101")) { FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); @@ -160,7 +161,7 @@ bool subghz_protocol_raw_save_to_file_init( init = true; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); return init; } @@ -210,7 +211,7 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { instance->ind_write = 0; instance->last_level = false; instance->file_is_open = RAWFileIsOpenClose; - string_init(instance->file_name); + instance->file_name = furi_string_alloc(); return instance; } @@ -218,7 +219,7 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_raw_free(void* context) { furi_assert(context); SubGhzProtocolDecoderRAW* instance = context; - string_clear(instance->file_name); + furi_string_free(instance->file_name); free(instance); } @@ -255,12 +256,12 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp return true; } -void subghz_protocol_decoder_raw_get_string(void* context, string_t output) { +void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { furi_assert(context); //SubGhzProtocolDecoderRAW* instance = context; UNUSED(context); //ToDo no use - string_cat_printf(output, "RAW Date"); + furi_string_cat_printf(output, "RAW Date"); } void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { @@ -268,7 +269,7 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { SubGhzProtocolEncoderRAW* instance = malloc(sizeof(SubGhzProtocolEncoderRAW)); instance->base.protocol = &subghz_protocol_raw; - string_init(instance->file_name); + instance->file_name = furi_string_alloc(); instance->is_running = false; return instance; } @@ -286,7 +287,7 @@ void subghz_protocol_encoder_raw_free(void* context) { furi_assert(context); SubGhzProtocolEncoderRAW* instance = context; subghz_protocol_encoder_raw_stop(instance); - string_clear(instance->file_name); + furi_string_free(instance->file_name); free(instance); } @@ -305,7 +306,7 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in instance->file_worker_encoder = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start( - instance->file_worker_encoder, string_get_cstr(instance->file_name))) { + instance->file_worker_encoder, furi_string_get_cstr(instance->file_name))) { //the worker needs a file in order to open and read part of the file furi_delay_ms(100); instance->is_running = true; @@ -334,8 +335,8 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp furi_assert(context); SubGhzProtocolEncoderRAW* instance = context; bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -346,11 +347,11 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp FURI_LOG_E(TAG, "Missing File_name"); break; } - string_set(instance->file_name, temp_str); + furi_string_set(instance->file_name, temp_str); res = subghz_protocol_encoder_raw_worker_init(instance); } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return res; } diff --git a/lib/subghz/protocols/raw.h b/lib/subghz/protocols/raw.h index b52a7d84..be03dea2 100644 --- a/lib/subghz/protocols/raw.h +++ b/lib/subghz/protocols/raw.h @@ -82,7 +82,7 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderRAW instance * @param output Resulting text */ -void subghz_protocol_decoder_raw_get_string(void* context, string_t output); +void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output); /** * Allocate SubGhzProtocolEncoderRAW. diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 1c044e9d..617efbba 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -263,14 +263,14 @@ bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat return subghz_block_generic_deserialize(&instance->generic, flipper_format); } -void subghz_protocol_decoder_scher_khan_get_string(void* context, string_t output) { +void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderScherKhan* instance = context; subghz_protocol_scher_khan_check_remote_controller( &instance->generic, &instance->protocol_name); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/scher_khan.h b/lib/subghz/protocols/scher_khan.h index 391ccc41..f0fe595b 100644 --- a/lib/subghz/protocols/scher_khan.h +++ b/lib/subghz/protocols/scher_khan.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance * @param output Resulting text */ -void subghz_protocol_decoder_scher_khan_get_string(void* context, string_t output); +void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 77a0c62a..885615b6 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -555,7 +555,7 @@ bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed) { return true; } -void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output) { +void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v1* instance = context; @@ -567,7 +567,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu uint8_t id1 = (fixed / 9) % 3; uint16_t pin = 0; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" @@ -587,9 +587,9 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu pin = (fixed / 59049) % 19683; if(pin <= 9999) { - string_cat_printf(output, " pin:%d", pin); + furi_string_cat_printf(output, " pin:%d", pin); } else if(10000 <= pin && pin <= 11029) { - string_cat_printf(output, " pin:enter"); + furi_string_cat_printf(output, " pin:enter"); } int pin_suffix = 0; @@ -597,13 +597,13 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu pin_suffix = (fixed / 1162261467) % 3; if(pin_suffix == 1) { - string_cat_printf(output, " #\r\n"); + furi_string_cat_printf(output, " #\r\n"); } else if(pin_suffix == 2) { - string_cat_printf(output, " *\r\n"); + furi_string_cat_printf(output, " *\r\n"); } else { - string_cat_printf(output, "\r\n"); + furi_string_cat_printf(output, "\r\n"); } - string_cat_printf( + furi_string_cat_printf( output, "Sn:0x%08lX\r\n" "Cnt:0x%03X\r\n" @@ -615,14 +615,14 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu //id = fixed / 27; instance->generic.serial = fixed / 27; if(instance->generic.btn == 1) { - string_cat_printf(output, " Btn:left\r\n"); + furi_string_cat_printf(output, " Btn:left\r\n"); } else if(instance->generic.btn == 0) { - string_cat_printf(output, " Btn:middle\r\n"); + furi_string_cat_printf(output, " Btn:middle\r\n"); } else if(instance->generic.btn == 2) { - string_cat_printf(output, " Btn:right\r\n"); + furi_string_cat_printf(output, " Btn:right\r\n"); } - string_cat_printf( + furi_string_cat_printf( output, "Sn:0x%08lX\r\n" "Cnt:0x%03X\r\n" diff --git a/lib/subghz/protocols/secplus_v1.h b/lib/subghz/protocols/secplus_v1.h index 8ae1c0cb..ba1762f5 100644 --- a/lib/subghz/protocols/secplus_v1.h +++ b/lib/subghz/protocols/secplus_v1.h @@ -110,4 +110,4 @@ bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed); * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance * @param output Resulting text */ -void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output); +void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index c242d0b4..3c9b966a 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -810,12 +810,12 @@ bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat return res; } -void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v2* instance = context; subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Pk1:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/secplus_v2.h b/lib/subghz/protocols/secplus_v2.h index 9e9ae2a7..007609fc 100644 --- a/lib/subghz/protocols/secplus_v2.h +++ b/lib/subghz/protocols/secplus_v2.h @@ -122,4 +122,4 @@ bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance * @param output Resulting text */ -void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output); +void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 7a3b2186..e1b75074 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -426,13 +426,13 @@ bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperForm return res; } -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, string_t output) { +void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSomfyKeytis* instance = context; subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "%lX%08lX%06lX\r\n" diff --git a/lib/subghz/protocols/somfy_keytis.h b/lib/subghz/protocols/somfy_keytis.h index 29f96cd6..af1df91d 100644 --- a/lib/subghz/protocols/somfy_keytis.h +++ b/lib/subghz/protocols/somfy_keytis.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperForm * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance * @param output Resulting text */ -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, string_t output); +void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index b9aac577..1dfdf0c4 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -363,13 +363,13 @@ bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_somfy_telis_get_string(void* context, string_t output) { +void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSomfyTelis* instance = context; subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/somfy_telis.h b/lib/subghz/protocols/somfy_telis.h index ff5b45e2..b6e58e34 100644 --- a/lib/subghz/protocols/somfy_telis.h +++ b/lib/subghz/protocols/somfy_telis.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance * @param output Resulting text */ -void subghz_protocol_decoder_somfy_telis_get_string(void* context, string_t output); +void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 757b5662..a8b0dad7 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -2,7 +2,6 @@ #include "keeloq_common.h" #include "../subghz_keystore.h" -#include #include #include "../blocks/const.h" @@ -229,7 +228,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( //Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -240,7 +239,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -248,7 +247,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } // Check for mirrored man @@ -260,7 +259,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( } decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } //########################### @@ -270,13 +269,13 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -355,7 +354,7 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* return res; } -void subghz_protocol_decoder_star_line_get_string(void* context, string_t output) { +void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; @@ -370,7 +369,7 @@ void subghz_protocol_decoder_star_line_get_string(void* context, string_t output uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" diff --git a/lib/subghz/protocols/star_line.h b/lib/subghz/protocols/star_line.h index e240954b..74c99410 100644 --- a/lib/subghz/protocols/star_line.h +++ b/lib/subghz/protocols/star_line.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderStarLine instance * @param output Resulting text */ -void subghz_protocol_decoder_star_line_get_string(void* context, string_t output); +void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output); diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 8f65ea00..1b8e99f1 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -19,8 +19,8 @@ struct SubGhzFileEncoderWorker { volatile bool worker_running; volatile bool worker_stoping; bool level; - string_t str_data; - string_t file_path; + FuriString* str_data; + FuriString* file_path; SubGhzFileEncoderWorkerCallbackEnd callback_end; void* context_end; @@ -117,9 +117,11 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); do { if(!flipper_format_file_open_existing( - instance->flipper_format, string_get_cstr(instance->file_path))) { + instance->flipper_format, furi_string_get_cstr(instance->file_path))) { FURI_LOG_E( - TAG, "Unable to open file for read: %s", string_get_cstr(instance->file_path)); + TAG, + "Unable to open file for read: %s", + furi_string_get_cstr(instance->file_path)); break; } if(!flipper_format_read_string(instance->flipper_format, "Protocol", instance->str_data)) { @@ -138,9 +140,9 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { size_t stream_free_byte = xStreamBufferSpacesAvailable(instance->stream); if((stream_free_byte / sizeof(int32_t)) >= SUBGHZ_FILE_ENCODER_LOAD) { if(stream_read_line(stream, instance->str_data)) { - string_strim(instance->str_data); + furi_string_trim(instance->str_data); if(!subghz_file_encoder_worker_data_parse( - instance, string_get_cstr(instance->str_data))) { + instance, furi_string_get_cstr(instance->str_data))) { //to stop DMA correctly subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); @@ -186,8 +188,8 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_format = flipper_format_file_alloc(instance->storage); - string_init(instance->str_data); - string_init(instance->file_path); + instance->str_data = furi_string_alloc(); + instance->file_path = furi_string_alloc(); instance->level = false; instance->worker_stoping = true; @@ -200,8 +202,8 @@ void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { vStreamBufferDelete(instance->stream); furi_thread_free(instance->thread); - string_clear(instance->str_data); - string_clear(instance->file_path); + furi_string_free(instance->str_data); + furi_string_free(instance->file_path); flipper_format_free(instance->flipper_format); furi_record_close(RECORD_STORAGE); @@ -214,7 +216,7 @@ bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const c furi_assert(!instance->worker_running); xStreamBufferReset(instance->stream); - string_set(instance->file_path, file_path); + furi_string_set(instance->file_path, file_path); instance->worker_running = true; furi_thread_start(instance->thread); diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index 4d2eb0e5..1b4b3b71 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -43,7 +43,7 @@ void subghz_keystore_free(SubGhzKeystore* instance) { for M_EACH(manufacture_code, instance->data, SubGhzKeyArray_t) { - string_clear(manufacture_code->name); + furi_string_free(manufacture_code->name); manufacture_code->key = 0; } SubGhzKeyArray_clear(instance->data); @@ -57,7 +57,7 @@ static void subghz_keystore_add_key( uint64_t key, uint16_t type) { SubGhzKey* manufacture_code = SubGhzKeyArray_push_raw(instance->data); - string_init_set_str(manufacture_code->name, name); + manufacture_code->name = furi_string_alloc_set(name); manufacture_code->key = key; manufacture_code->type = type; } @@ -191,8 +191,8 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { uint32_t version; SubGhzKeystoreEncryption encryption; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); FURI_LOG_I(TAG, "Loading keystore %s", file_name); @@ -213,7 +213,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { break; } - if(strcmp(string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -238,7 +238,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); return result; } @@ -294,7 +294,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 (uint32_t)(key->key >> 32), (uint32_t)key->key, key->type, - string_get_cstr(key->name)); + furi_string_get_cstr(key->name)); // Verify length and align furi_assert(len > 0); if(len % 16 != 0) { @@ -349,8 +349,8 @@ bool subghz_keystore_raw_encrypted_save( uint8_t* iv) { bool encrypted = false; uint32_t version; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); SubGhzKeystoreEncryption encryption; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -373,7 +373,7 @@ bool subghz_keystore_raw_encrypted_save( break; } - if(strcmp(string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -392,7 +392,9 @@ bool subghz_keystore_raw_encrypted_save( break; } if(!flipper_format_write_header_cstr( - output_flipper_format, string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_VERSION)) { + output_flipper_format, + furi_string_get_cstr(filetype), + SUBGHZ_KEYSTORE_FILE_VERSION)) { FURI_LOG_E(TAG, "Unable to add header"); break; } @@ -488,8 +490,8 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* uint32_t version; SubGhzKeystoreEncryption encryption; - string_t str_temp; - string_init(str_temp); + FuriString* str_temp; + str_temp = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); @@ -509,7 +511,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* break; } - if(strcmp(string_get_cstr(str_temp), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(str_temp), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -605,7 +607,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* free(decrypted_line); - string_clear(str_temp); + furi_string_free(str_temp); return result; } diff --git a/lib/subghz/subghz_keystore.h b/lib/subghz/subghz_keystore.h index 2b7880f0..06ae8ada 100644 --- a/lib/subghz/subghz_keystore.h +++ b/lib/subghz/subghz_keystore.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ extern "C" { #endif typedef struct { - string_t name; + FuriString* name; uint64_t key; uint16_t type; } SubGhzKey; diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 32b70b65..dd9cefb8 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -41,7 +41,7 @@ typedef bool (*SubGhzDeserialize)(void* context, FlipperFormat* flipper_format); typedef void (*SubGhzDecoderFeed)(void* decoder, bool level, uint32_t duration); typedef void (*SubGhzDecoderReset)(void* decoder); typedef uint8_t (*SubGhzGetHashData)(void* decoder); -typedef void (*SubGhzGetString)(void* decoder, string_t output); +typedef void (*SubGhzGetString)(void* decoder, FuriString* output); // Encoder specific typedef void (*SubGhzEncoderStop)(void* encoder); diff --git a/lib/toolbox/args.c b/lib/toolbox/args.c index 287ca7ef..aa790ad6 100644 --- a/lib/toolbox/args.c +++ b/lib/toolbox/args.c @@ -1,60 +1,60 @@ #include "args.h" #include "hex.h" -size_t args_get_first_word_length(string_t args) { - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { - ws = string_size(args); +size_t args_get_first_word_length(FuriString* args) { + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { + ws = furi_string_size(args); } return ws; } -size_t args_length(string_t args) { - return string_size(args); +size_t args_length(FuriString* args) { + return furi_string_size(args); } -bool args_read_int_and_trim(string_t args, int* value) { +bool args_read_int_and_trim(FuriString* args, int* value) { size_t cmd_length = args_get_first_word_length(args); if(cmd_length == 0) { return false; } - if(sscanf(string_get_cstr(args), "%d", value) == 1) { - string_right(args, cmd_length); - string_strim(args); + if(sscanf(furi_string_get_cstr(args), "%d", value) == 1) { + furi_string_right(args, cmd_length); + furi_string_trim(args); return true; } return false; } -bool args_read_string_and_trim(string_t args, string_t word) { +bool args_read_string_and_trim(FuriString* args, FuriString* word) { size_t cmd_length = args_get_first_word_length(args); if(cmd_length == 0) { return false; } - string_set_n(word, args, 0, cmd_length); - string_right(args, cmd_length); - string_strim(args); + furi_string_set_n(word, args, 0, cmd_length); + furi_string_right(args, cmd_length); + furi_string_trim(args); return true; } -bool args_read_probably_quoted_string_and_trim(string_t args, string_t word) { - if(string_size(args) > 1 && string_get_char(args, 0) == '\"') { - size_t second_quote_pos = string_search_char(args, '\"', 1); +bool args_read_probably_quoted_string_and_trim(FuriString* args, FuriString* word) { + if(furi_string_size(args) > 1 && furi_string_get_char(args, 0) == '\"') { + size_t second_quote_pos = furi_string_search_char(args, '\"', 1); if(second_quote_pos == 0) { return false; } - string_set_n(word, args, 1, second_quote_pos - 1); - string_right(args, second_quote_pos + 1); - string_strim(args); + furi_string_set_n(word, args, 1, second_quote_pos - 1); + furi_string_right(args, second_quote_pos + 1); + furi_string_trim(args); return true; } else { return args_read_string_and_trim(args, word); @@ -76,9 +76,9 @@ bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte) { return result; } -bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count) { +bool args_read_hex_bytes(FuriString* args, uint8_t* bytes, size_t bytes_count) { bool result = true; - const char* str_pointer = string_get_cstr(args); + const char* str_pointer = furi_string_get_cstr(args); if(args_get_first_word_length(args) == (bytes_count * 2)) { for(size_t i = 0; i < bytes_count; i++) { diff --git a/lib/toolbox/args.h b/lib/toolbox/args.h index dc72bdaf..556fd4a7 100644 --- a/lib/toolbox/args.h +++ b/lib/toolbox/args.h @@ -2,7 +2,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ extern "C" { * @return true - success * @return false - arguments string does not contain int */ -bool args_read_int_and_trim(string_t args, int* value); +bool args_read_int_and_trim(FuriString* args, int* value); /** * @brief Extract first argument from arguments string and trim arguments string @@ -25,7 +25,7 @@ bool args_read_int_and_trim(string_t args, int* value); * @return true - success * @return false - arguments string does not contain anything */ -bool args_read_string_and_trim(string_t args, string_t word); +bool args_read_string_and_trim(FuriString* args, FuriString* word); /** * @brief Extract the first quoted argument from the argument string and trim the argument string. If the argument is not quoted, calls args_read_string_and_trim. @@ -35,7 +35,7 @@ bool args_read_string_and_trim(string_t args, string_t word); * @return true - success * @return false - arguments string does not contain anything */ -bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); +bool args_read_probably_quoted_string_and_trim(FuriString* args, FuriString* word); /** * @brief Convert hex ASCII values to byte array @@ -46,7 +46,7 @@ bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); * @return true - success * @return false - arguments string does not contain enough values, or contain non-hex ASCII values */ -bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count); +bool args_read_hex_bytes(FuriString* args, uint8_t* bytes, size_t bytes_count); /************************************ HELPERS ***************************************/ @@ -56,7 +56,7 @@ bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count); * @param args arguments string * @return size_t length of first word */ -size_t args_get_first_word_length(string_t args); +size_t args_get_first_word_length(FuriString* args); /** * @brief Get length of arguments string @@ -64,7 +64,7 @@ size_t args_get_first_word_length(string_t args); * @param args arguments string * @return size_t length of arguments string */ -size_t args_length(string_t args); +size_t args_length(FuriString* args); /** * @brief Convert ASCII hex values to byte diff --git a/lib/toolbox/dir_walk.c b/lib/toolbox/dir_walk.c index 348bd544..b5e2cb52 100644 --- a/lib/toolbox/dir_walk.c +++ b/lib/toolbox/dir_walk.c @@ -5,7 +5,7 @@ LIST_DEF(DirIndexList, uint32_t); struct DirWalk { File* file; - string_t path; + FuriString* path; DirIndexList_t index_list; uint32_t current_index; bool recursive; @@ -15,7 +15,7 @@ struct DirWalk { DirWalk* dir_walk_alloc(Storage* storage) { DirWalk* dir_walk = malloc(sizeof(DirWalk)); - string_init(dir_walk->path); + dir_walk->path = furi_string_alloc(); dir_walk->file = storage_file_alloc(storage); DirIndexList_init(dir_walk->index_list); dir_walk->recursive = true; @@ -25,7 +25,7 @@ DirWalk* dir_walk_alloc(Storage* storage) { void dir_walk_free(DirWalk* dir_walk) { storage_file_free(dir_walk->file); - string_clear(dir_walk->path); + furi_string_free(dir_walk->path); DirIndexList_clear(dir_walk->index_list); free(dir_walk); } @@ -40,7 +40,7 @@ void dir_walk_set_filter_cb(DirWalk* dir_walk, DirWalkFilterCb cb, void* context } bool dir_walk_open(DirWalk* dir_walk, const char* path) { - string_set(dir_walk->path, path); + furi_string_set(dir_walk->path, path); dir_walk->current_index = 0; return storage_dir_open(dir_walk->file, path); } @@ -53,7 +53,8 @@ static bool dir_walk_filter(DirWalk* dir_walk, const char* name, FileInfo* filei } } -static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { +static DirWalkResult + dir_walk_iter(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo) { DirWalkResult result = DirWalkError; char* name = malloc(256); // FIXME: remove magic number FileInfo info; @@ -68,7 +69,8 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File if(dir_walk_filter(dir_walk, name, &info)) { if(return_path != NULL) { - string_printf(return_path, "%s/%s", string_get_cstr(dir_walk->path), name); + furi_string_printf( + return_path, "%s/%s", furi_string_get_cstr(dir_walk->path), name); } if(fileinfo != NULL) { @@ -84,8 +86,8 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File dir_walk->current_index = 0; storage_dir_close(dir_walk->file); - string_cat_printf(dir_walk->path, "/%s", name); - storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + furi_string_cat_printf(dir_walk->path, "/%s", name); + storage_dir_open(dir_walk->file, furi_string_get_cstr(dir_walk->path)); } } else if(storage_file_get_error(dir_walk->file) == FSE_NOT_EXIST) { if(DirIndexList_size(dir_walk->index_list) == 0) { @@ -100,12 +102,12 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File storage_dir_close(dir_walk->file); - size_t last_char = string_search_rchar(dir_walk->path, '/'); - if(last_char != STRING_FAILURE) { - string_left(dir_walk->path, last_char); + size_t last_char = furi_string_search_rchar(dir_walk->path, '/'); + if(last_char != FURI_STRING_FAILURE) { + furi_string_left(dir_walk->path, last_char); } - storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + storage_dir_open(dir_walk->file, furi_string_get_cstr(dir_walk->path)); // rewind while(true) { @@ -137,7 +139,7 @@ FS_Error dir_walk_get_error(DirWalk* dir_walk) { return storage_file_get_error(dir_walk->file); } -DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { +DirWalkResult dir_walk_read(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo) { return dir_walk_iter(dir_walk, return_path, fileinfo); } @@ -147,6 +149,6 @@ void dir_walk_close(DirWalk* dir_walk) { } DirIndexList_reset(dir_walk->index_list); - string_reset(dir_walk->path); + furi_string_reset(dir_walk->path); dir_walk->current_index = 0; } diff --git a/lib/toolbox/dir_walk.h b/lib/toolbox/dir_walk.h index fc651042..535237fc 100644 --- a/lib/toolbox/dir_walk.h +++ b/lib/toolbox/dir_walk.h @@ -66,7 +66,7 @@ FS_Error dir_walk_get_error(DirWalk* dir_walk); * @param fileinfo * @return DirWalkResult */ -DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo); +DirWalkResult dir_walk_read(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo); /** * Close directory diff --git a/lib/toolbox/m_cstr_dup.h b/lib/toolbox/m_cstr_dup.h index 2bc35c87..0555f72c 100644 --- a/lib/toolbox/m_cstr_dup.h +++ b/lib/toolbox/m_cstr_dup.h @@ -13,5 +13,4 @@ HASH(m_core_cstr_hash), \ EQUAL(M_CSTR_EQUAL), \ CMP(strcmp), \ - TYPE(const char*), \ - OUT_STR(M_CSTR_OUT_STR)) + TYPE(const char*)) diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 1262362e..53e9fc09 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -1,86 +1,85 @@ #include "path.h" -#include "m-string.h" #include -void path_extract_filename_no_ext(const char* path, string_t filename) { - string_set(filename, path); +void path_extract_filename_no_ext(const char* path, FuriString* filename) { + furi_string_set(filename, path); - size_t start_position = string_search_rchar(filename, '/'); - size_t end_position = string_search_rchar(filename, '.'); + size_t start_position = furi_string_search_rchar(filename, '/'); + size_t end_position = furi_string_search_rchar(filename, '.'); - if(start_position == STRING_FAILURE) { + if(start_position == FURI_STRING_FAILURE) { start_position = 0; } else { start_position += 1; } - if(end_position == STRING_FAILURE) { - end_position = string_size(filename); + if(end_position == FURI_STRING_FAILURE) { + end_position = furi_string_size(filename); } - string_mid(filename, start_position, end_position - start_position); + furi_string_mid(filename, start_position, end_position - start_position); } -void path_extract_filename(string_t path, string_t name, bool trim_ext) { - size_t filename_start = string_search_rchar(path, '/'); +void path_extract_filename(FuriString* path, FuriString* name, bool trim_ext) { + size_t filename_start = furi_string_search_rchar(path, '/'); if(filename_start > 0) { filename_start++; - string_set_n(name, path, filename_start, string_size(path) - filename_start); + furi_string_set_n(name, path, filename_start, furi_string_size(path) - filename_start); } if(trim_ext) { - size_t dot = string_search_rchar(name, '.'); + size_t dot = furi_string_search_rchar(name, '.'); if(dot > 0) { - string_left(name, dot); + furi_string_left(name, dot); } } } -void path_extract_extension(string_t path, char* ext, size_t ext_len_max) { - size_t dot = string_search_rchar(path, '.'); - size_t filename_start = string_search_rchar(path, '/'); +void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max) { + size_t dot = furi_string_search_rchar(path, '.'); + size_t filename_start = furi_string_search_rchar(path, '/'); if((dot > 0) && (filename_start < dot)) { - strlcpy(ext, &(string_get_cstr(path))[dot], ext_len_max); + strlcpy(ext, &(furi_string_get_cstr(path))[dot], ext_len_max); } } -static inline void path_cleanup(string_t path) { - string_strim(path); - while(string_end_with_str_p(path, "/")) { - string_left(path, string_size(path) - 1); +static inline void path_cleanup(FuriString* path) { + furi_string_trim(path); + while(furi_string_end_with(path, "/")) { + furi_string_left(path, furi_string_size(path) - 1); } } -void path_extract_basename(const char* path, string_t basename) { - string_set(basename, path); +void path_extract_basename(const char* path, FuriString* basename) { + furi_string_set(basename, path); path_cleanup(basename); - size_t pos = string_search_rchar(basename, '/'); - if(pos != STRING_FAILURE) { - string_right(basename, pos + 1); + size_t pos = furi_string_search_rchar(basename, '/'); + if(pos != FURI_STRING_FAILURE) { + furi_string_right(basename, pos + 1); } } -void path_extract_dirname(const char* path, string_t dirname) { - string_set(dirname, path); +void path_extract_dirname(const char* path, FuriString* dirname) { + furi_string_set(dirname, path); path_cleanup(dirname); - size_t pos = string_search_rchar(dirname, '/'); - if(pos != STRING_FAILURE) { - string_left(dirname, pos); + size_t pos = furi_string_search_rchar(dirname, '/'); + if(pos != FURI_STRING_FAILURE) { + furi_string_left(dirname, pos); } } -void path_append(string_t path, const char* suffix) { +void path_append(FuriString* path, const char* suffix) { path_cleanup(path); - string_t suffix_str; - string_init_set(suffix_str, suffix); - string_strim(suffix_str); - string_strim(suffix_str, "/"); - string_cat_printf(path, "/%s", string_get_cstr(suffix_str)); - string_clear(suffix_str); + FuriString* suffix_str; + suffix_str = furi_string_alloc_set(suffix); + furi_string_trim(suffix_str); + furi_string_trim(suffix_str, "/"); + furi_string_cat_printf(path, "/%s", furi_string_get_cstr(suffix_str)); + furi_string_free(suffix_str); } -void path_concat(const char* path, const char* suffix, string_t out_path) { - string_set(out_path, path); +void path_concat(const char* path, const char* suffix, FuriString* out_path) { + furi_string_set(out_path, path); path_append(out_path, suffix); } diff --git a/lib/toolbox/path.h b/lib/toolbox/path.h index d46b210f..e6145b71 100644 --- a/lib/toolbox/path.h +++ b/lib/toolbox/path.h @@ -1,6 +1,5 @@ #pragma once - -#include +#include #ifdef __cplusplus extern "C" { @@ -12,7 +11,7 @@ extern "C" { * @param path path string * @param filename output filename string. Must be initialized before. */ -void path_extract_filename_no_ext(const char* path, string_t filename); +void path_extract_filename_no_ext(const char* path, FuriString* filename); /** * @brief Extract filename string from path. @@ -21,7 +20,7 @@ void path_extract_filename_no_ext(const char* path, string_t filename); * @param filename output filename string. Must be initialized before. * @param trim_ext true - get filename without extension */ -void path_extract_filename(string_t path, string_t filename, bool trim_ext); +void path_extract_filename(FuriString* path, FuriString* filename, bool trim_ext); /** * @brief Extract file extension from path. @@ -30,7 +29,7 @@ void path_extract_filename(string_t path, string_t filename, bool trim_ext); * @param ext output extension string * @param ext_len_max maximum extension string length */ -void path_extract_extension(string_t path, char* ext, size_t ext_len_max); +void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max); /** * @brief Extract last path component @@ -38,7 +37,7 @@ void path_extract_extension(string_t path, char* ext, size_t ext_len_max); * @param path path string * @param filename output string. Must be initialized before. */ -void path_extract_basename(const char* path, string_t basename); +void path_extract_basename(const char* path, FuriString* basename); /** * @brief Extract path, except for last component @@ -46,7 +45,7 @@ void path_extract_basename(const char* path, string_t basename); * @param path path string * @param filename output string. Must be initialized before. */ -void path_extract_dirname(const char* path, string_t dirname); +void path_extract_dirname(const char* path, FuriString* dirname); /** * @brief Appends new component to path, adding path delimiter @@ -54,7 +53,7 @@ void path_extract_dirname(const char* path, string_t dirname); * @param path path string * @param suffix path part to apply */ -void path_append(string_t path, const char* suffix); +void path_append(FuriString* path, const char* suffix); /** * @brief Appends new component to path, adding path delimiter @@ -63,7 +62,7 @@ void path_append(string_t path, const char* suffix); * @param suffix second path part * @param out_path output string to combine parts into. Must be initialized */ -void path_concat(const char* path, const char* suffix, string_t out_path); +void path_concat(const char* path, const char* suffix, FuriString* out_path); /** * @brief Check that path contains only ascii characters diff --git a/lib/toolbox/protocols/protocol.h b/lib/toolbox/protocols/protocol.h index 56bb1b74..5a8015b1 100644 --- a/lib/toolbox/protocols/protocol.h +++ b/lib/toolbox/protocols/protocol.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include typedef void* (*ProtocolAlloc)(void); typedef void (*ProtocolFree)(void* protocol); @@ -15,7 +15,7 @@ typedef bool (*ProtocolDecoderFeed)(void* protocol, bool level, uint32_t duratio typedef bool (*ProtocolEncoderStart)(void* protocol); typedef LevelDuration (*ProtocolEncoderYield)(void* protocol); -typedef void (*ProtocolRenderData)(void* protocol, string_t result); +typedef void (*ProtocolRenderData)(void* protocol, FuriString* result); typedef bool (*ProtocolWriteData)(void* protocol, void* data); typedef struct { diff --git a/lib/toolbox/protocols/protocol_dict.c b/lib/toolbox/protocols/protocol_dict.c index 2a022cc4..136dc137 100644 --- a/lib/toolbox/protocols/protocol_dict.c +++ b/lib/toolbox/protocols/protocol_dict.c @@ -185,7 +185,7 @@ LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_in } } -void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t protocol_index) { +void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) { furi_assert(protocol_index < dict->count); ProtocolRenderData fn = dict->base[protocol_index]->render_data; @@ -194,7 +194,7 @@ void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t proto } } -void protocol_dict_render_brief_data(ProtocolDict* dict, string_t result, size_t protocol_index) { +void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) { furi_assert(protocol_index < dict->count); ProtocolRenderData fn = dict->base[protocol_index]->render_brief_data; diff --git a/lib/toolbox/protocols/protocol_dict.h b/lib/toolbox/protocols/protocol_dict.h index 3037ddd5..cd850395 100644 --- a/lib/toolbox/protocols/protocol_dict.h +++ b/lib/toolbox/protocols/protocol_dict.h @@ -58,9 +58,9 @@ bool protocol_dict_encoder_start(ProtocolDict* dict, size_t protocol_index); LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_index); -void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t protocol_index); +void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); -void protocol_dict_render_brief_data(ProtocolDict* dict, string_t result, size_t protocol_index); +void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); uint32_t protocol_dict_get_validate_count(ProtocolDict* dict, size_t protocol_index); diff --git a/lib/toolbox/stream/file_stream.c b/lib/toolbox/stream/file_stream.c index f7363c6b..06491216 100644 --- a/lib/toolbox/stream/file_stream.c +++ b/lib/toolbox/stream/file_stream.c @@ -173,17 +173,20 @@ static bool file_stream_delete_and_insert( Stream* scratch_stream = file_stream_alloc(_stream->storage); // TODO: we need something like "storage_open_tmpfile and storage_close_tmpfile" - string_t scratch_name; - string_t tmp_name; - string_init(tmp_name); + FuriString* scratch_name; + FuriString* tmp_name; + tmp_name = furi_string_alloc(); storage_get_next_filename( _stream->storage, STORAGE_ANY_PATH_PREFIX, ".scratch", ".pad", tmp_name, 255); - string_init_printf(scratch_name, ANY_PATH("%s.pad"), string_get_cstr(tmp_name)); - string_clear(tmp_name); + scratch_name = furi_string_alloc_printf(ANY_PATH("%s.pad"), furi_string_get_cstr(tmp_name)); + furi_string_free(tmp_name); do { if(!file_stream_open( - scratch_stream, string_get_cstr(scratch_name), FSAM_READ_WRITE, FSOM_CREATE_NEW)) + scratch_stream, + furi_string_get_cstr(scratch_name), + FSAM_READ_WRITE, + FSOM_CREATE_NEW)) break; size_t current_position = stream_tell(stream); @@ -225,8 +228,8 @@ static bool file_stream_delete_and_insert( } while(false); stream_free(scratch_stream); - storage_common_remove(_stream->storage, string_get_cstr(scratch_name)); - string_clear(scratch_name); + storage_common_remove(_stream->storage, furi_string_get_cstr(scratch_name)); + furi_string_free(scratch_name); return result; } diff --git a/lib/toolbox/stream/stream.c b/lib/toolbox/stream/stream.c index 088996f0..86d35c95 100644 --- a/lib/toolbox/stream/stream.c +++ b/lib/toolbox/stream/stream.c @@ -67,8 +67,8 @@ static bool stream_write_struct(Stream* stream, const void* context) { return (stream_write(stream, write_data->data, write_data->size) == write_data->size); } -bool stream_read_line(Stream* stream, string_t str_result) { - string_reset(str_result); +bool stream_read_line(Stream* stream, FuriString* str_result) { + furi_string_reset(str_result); const uint8_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -84,13 +84,13 @@ bool stream_read_line(Stream* stream, string_t str_result) { error = true; break; } - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); result = true; break; } else if(buffer[i] == '\r') { // Ignore } else { - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); } } @@ -99,7 +99,7 @@ bool stream_read_line(Stream* stream, string_t str_result) { } } while(true); - return string_size(str_result) != 0; + return furi_string_size(str_result) != 0; } bool stream_rewind(Stream* stream) { @@ -112,9 +112,10 @@ size_t stream_write_char(Stream* stream, char c) { return stream_write(stream, (const uint8_t*)&c, 1); } -size_t stream_write_string(Stream* stream, string_t string) { +size_t stream_write_string(Stream* stream, FuriString* string) { furi_assert(stream); - return stream_write(stream, (const uint8_t*)string_get_cstr(string), string_size(string)); + return stream_write( + stream, (const uint8_t*)furi_string_get_cstr(string), furi_string_size(string)); } size_t stream_write_cstring(Stream* stream, const char* string) { @@ -134,10 +135,10 @@ size_t stream_write_format(Stream* stream, const char* format, ...) { size_t stream_write_vaformat(Stream* stream, const char* format, va_list args) { furi_assert(stream); - string_t data; - string_init_vprintf(data, format, args); + FuriString* data; + data = furi_string_alloc_vprintf(format, args); size_t size = stream_write_string(stream, data); - string_clear(data); + furi_string_free(data); return size; } @@ -153,7 +154,7 @@ bool stream_insert_char(Stream* stream, char c) { return stream_delete_and_insert_char(stream, 0, c); } -bool stream_insert_string(Stream* stream, string_t string) { +bool stream_insert_string(Stream* stream, FuriString* string) { furi_assert(stream); return stream_delete_and_insert_string(stream, 0, string); } @@ -184,10 +185,10 @@ bool stream_delete_and_insert_char(Stream* stream, size_t delete_size, char c) { return stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); } -bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, string_t string) { +bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, FuriString* string) { furi_assert(stream); StreamWriteData write_data = { - .data = (uint8_t*)string_get_cstr(string), .size = string_size(string)}; + .data = (uint8_t*)furi_string_get_cstr(string), .size = furi_string_size(string)}; return stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); } @@ -213,12 +214,12 @@ bool stream_delete_and_insert_vaformat( const char* format, va_list args) { furi_assert(stream); - string_t data; - string_init_vprintf(data, format, args); + FuriString* data; + data = furi_string_alloc_vprintf(format, args); StreamWriteData write_data = { - .data = (uint8_t*)string_get_cstr(data), .size = string_size(data)}; + .data = (uint8_t*)furi_string_get_cstr(data), .size = furi_string_size(data)}; bool result = stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); - string_clear(data); + furi_string_free(data); return result; } diff --git a/lib/toolbox/stream/stream.h b/lib/toolbox/stream/stream.h index c10e9f5e..1ffb4044 100644 --- a/lib/toolbox/stream/stream.h +++ b/lib/toolbox/stream/stream.h @@ -2,7 +2,6 @@ #include #include #include -#include #include #ifdef __cplusplus @@ -105,7 +104,7 @@ bool stream_delete_and_insert( * @return true if line lenght is not zero * @return false otherwise */ -bool stream_read_line(Stream* stream, string_t str_result); +bool stream_read_line(Stream* stream, FuriString* str_result); /** * Moves the rw pointer to the start @@ -127,7 +126,7 @@ size_t stream_write_char(Stream* stream, char c); * @param string string value * @return size_t how many bytes was written */ -size_t stream_write_string(Stream* stream, string_t string); +size_t stream_write_string(Stream* stream, FuriString* string); /** * Write const char* to the stream @@ -182,7 +181,7 @@ bool stream_insert_char(Stream* stream, char c); * @return true if the operation was successful * @return false on error */ -bool stream_insert_string(Stream* stream, string_t string); +bool stream_insert_string(Stream* stream, FuriString* string); /** * Insert const char* to the stream @@ -231,7 +230,7 @@ bool stream_delete_and_insert_char(Stream* stream, size_t delete_size, char c); * @return true if the operation was successful * @return false on error */ -bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, string_t string); +bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, FuriString* string); /** * Delete N chars from the stream and insert const char* to the stream diff --git a/lib/toolbox/stream/string_stream.c b/lib/toolbox/stream/string_stream.c index f3e1364d..075f0b26 100644 --- a/lib/toolbox/stream/string_stream.c +++ b/lib/toolbox/stream/string_stream.c @@ -5,7 +5,7 @@ typedef struct { Stream stream_base; - string_t string; + FuriString* string; size_t index; } StringStream; @@ -39,14 +39,14 @@ const StreamVTable string_stream_vtable = { Stream* string_stream_alloc() { StringStream* stream = malloc(sizeof(StringStream)); - string_init(stream->string); + stream->string = furi_string_alloc(); stream->index = 0; stream->stream_base.vtable = &string_stream_vtable; return (Stream*)stream; } static void string_stream_free(StringStream* stream) { - string_clear(stream->string); + furi_string_free(stream->string); free(stream); } @@ -56,7 +56,7 @@ static bool string_stream_eof(StringStream* stream) { static void string_stream_clean(StringStream* stream) { stream->index = 0; - string_reset(stream->string); + furi_string_reset(stream->string); } static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffset offset_type) { @@ -79,8 +79,8 @@ static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffse } break; case StreamOffsetFromEnd: - if(((int32_t)string_size(stream->string) + offset) >= 0) { - stream->index = string_size(stream->string) + offset; + if(((int32_t)furi_string_size(stream->string) + offset) >= 0) { + stream->index = furi_string_size(stream->string) + offset; } else { result = false; stream->index = 0; @@ -88,7 +88,7 @@ static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffse break; } - int32_t diff = (stream->index - string_size(stream->string)); + int32_t diff = (stream->index - furi_string_size(stream->string)); if(diff > 0) { stream->index -= diff; result = false; @@ -102,7 +102,7 @@ static size_t string_stream_tell(StringStream* stream) { } static size_t string_stream_size(StringStream* stream) { - return string_size(stream->string); + return furi_string_size(stream->string); } static size_t string_stream_write(StringStream* stream, const char* data, size_t size) { @@ -117,7 +117,7 @@ static size_t string_stream_write(StringStream* stream, const char* data, size_t static size_t string_stream_read(StringStream* stream, char* data, size_t size) { size_t write_index = 0; - const char* cstr = string_get_cstr(stream->string); + const char* cstr = furi_string_get_cstr(stream->string); if(!string_stream_eof(stream)) { while(true) { @@ -145,17 +145,17 @@ static bool string_stream_delete_and_insert( remain_size = MIN(delete_size, remain_size); if(remain_size != 0) { - string_replace_at(stream->string, stream->index, remain_size, ""); + furi_string_replace_at(stream->string, stream->index, remain_size, ""); } } if(write_callback) { - string_t right; - string_init_set(right, &string_get_cstr(stream->string)[stream->index]); - string_left(stream->string, string_stream_tell(stream)); + FuriString* right; + right = furi_string_alloc_set(&furi_string_get_cstr(stream->string)[stream->index]); + furi_string_left(stream->string, string_stream_tell(stream)); result &= write_callback((Stream*)stream, ctx); - string_cat(stream->string, right); - string_clear(right); + furi_string_cat(stream->string, right); + furi_string_free(right); } return result; @@ -169,9 +169,9 @@ static bool string_stream_delete_and_insert( */ static size_t string_stream_write_char(StringStream* stream, char c) { if(string_stream_eof(stream)) { - string_push_back(stream->string, c); + furi_string_push_back(stream->string, c); } else { - string_set_char(stream->string, stream->index, c); + furi_string_set_char(stream->string, stream->index, c); } stream->index++; diff --git a/lib/toolbox/stream/string_stream.h b/lib/toolbox/stream/string_stream.h index 6cccfa6c..f882a246 100644 --- a/lib/toolbox/stream/string_stream.h +++ b/lib/toolbox/stream/string_stream.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "stream.h" #ifdef __cplusplus diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index 1a542b2e..e8b44729 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -220,14 +220,14 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } - string_t full_extracted_fname; + FuriString* full_extracted_fname; if(header->type == MTAR_TDIR) { - string_init(full_extracted_fname); + full_extracted_fname = furi_string_alloc(); path_concat(op_params->work_dir, header->name, full_extracted_fname); bool create_res = - storage_simply_mkdir(archive->storage, string_get_cstr(full_extracted_fname)); - string_clear(full_extracted_fname); + storage_simply_mkdir(archive->storage, furi_string_get_cstr(full_extracted_fname)); + furi_string_free(full_extracted_fname); return create_res ? 0 : -1; } @@ -238,19 +238,19 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, FURI_LOG_D(TAG, "Extracting %d bytes to '%s'", header->size, header->name); - string_t converted_fname; - string_init_set(converted_fname, header->name); + FuriString* converted_fname = furi_string_alloc_set(header->name); if(op_params->converter) { op_params->converter(converted_fname); } - string_init(full_extracted_fname); - path_concat(op_params->work_dir, string_get_cstr(converted_fname), full_extracted_fname); + full_extracted_fname = furi_string_alloc(); + path_concat(op_params->work_dir, furi_string_get_cstr(converted_fname), full_extracted_fname); - bool success = archive_extract_current_file(archive, string_get_cstr(full_extracted_fname)); + bool success = + archive_extract_current_file(archive, furi_string_get_cstr(full_extracted_fname)); - string_clear(converted_fname); - string_clear(full_extracted_fname); + furi_string_free(converted_fname); + furi_string_free(full_extracted_fname); return success ? 0 : -1; } @@ -333,32 +333,32 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch break; } - string_t element_name, element_fs_abs_path; - string_init(element_name); - string_init(element_fs_abs_path); + FuriString* element_name = furi_string_alloc(); + FuriString* element_fs_abs_path = furi_string_alloc(); path_concat(fs_full_path, name, element_fs_abs_path); if(strlen(path_prefix)) { path_concat(path_prefix, name, element_name); } else { - string_init_set(element_name, name); + furi_string_set(element_name, name); } if(file_info.flags & FSF_DIRECTORY) { - success = tar_archive_dir_add_element(archive, string_get_cstr(element_name)) && - tar_archive_add_dir( - archive, - string_get_cstr(element_fs_abs_path), - string_get_cstr(element_name)); + success = + tar_archive_dir_add_element(archive, furi_string_get_cstr(element_name)) && + tar_archive_add_dir( + archive, + furi_string_get_cstr(element_fs_abs_path), + furi_string_get_cstr(element_name)); } else { success = tar_archive_add_file( archive, - string_get_cstr(element_fs_abs_path), - string_get_cstr(element_name), + furi_string_get_cstr(element_fs_abs_path), + furi_string_get_cstr(element_name), file_info.size); } - string_clear(element_name); - string_clear(element_fs_abs_path); + furi_string_free(element_name); + furi_string_free(element_fs_abs_path); if(!success) { break; diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h index ceaf82ee..ba2f7749 100644 --- a/lib/toolbox/tar/tar_archive.h +++ b/lib/toolbox/tar/tar_archive.h @@ -2,7 +2,6 @@ #include #include -#include #include #ifdef __cplusplus diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/lfs_backup.c index 089f032d..7786524e 100644 --- a/lib/update_util/lfs_backup.c +++ b/lib/update_util/lfs_backup.c @@ -11,8 +11,8 @@ #define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME) -static void backup_name_converter(string_t filename) { - if(string_empty_p(filename) || (string_get_char(filename, 0) == '.')) { +static void backup_name_converter(FuriString* filename) { + if(furi_string_empty(filename) || (furi_string_get_char(filename, 0) == '.')) { return; } @@ -27,8 +27,8 @@ static void backup_name_converter(string_t filename) { }; for(size_t i = 0; i < COUNT_OF(names); i++) { - if(string_equal_str_p(filename, &names[i][1])) { - string_set_str(filename, names[i]); + if(furi_string_equal(filename, &names[i][1])) { + furi_string_set(filename, names[i]); return; } } diff --git a/lib/update_util/resources/manifest.c b/lib/update_util/resources/manifest.c index 4f8a7d1a..8b6a1b33 100644 --- a/lib/update_util/resources/manifest.c +++ b/lib/update_util/resources/manifest.c @@ -6,7 +6,7 @@ struct ResourceManifestReader { Storage* storage; Stream* stream; - string_t linebuf; + FuriString* linebuf; ResourceManifestEntry entry; }; @@ -16,16 +16,16 @@ ResourceManifestReader* resource_manifest_reader_alloc(Storage* storage) { resource_manifest->storage = storage; resource_manifest->stream = buffered_file_stream_alloc(resource_manifest->storage); memset(&resource_manifest->entry, 0, sizeof(ResourceManifestEntry)); - string_init(resource_manifest->entry.name); - string_init(resource_manifest->linebuf); + resource_manifest->entry.name = furi_string_alloc(); + resource_manifest->linebuf = furi_string_alloc(); return resource_manifest; } void resource_manifest_reader_free(ResourceManifestReader* resource_manifest) { furi_assert(resource_manifest); - string_clear(resource_manifest->linebuf); - string_clear(resource_manifest->entry.name); + furi_string_free(resource_manifest->linebuf); + furi_string_free(resource_manifest->entry.name); buffered_file_stream_close(resource_manifest->stream); stream_free(resource_manifest->stream); free(resource_manifest); @@ -45,7 +45,7 @@ bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, co ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest) { furi_assert(resource_manifest); - string_reset(resource_manifest->entry.name); + furi_string_reset(resource_manifest->entry.name); resource_manifest->entry.type = ResourceManifestEntryTypeUnknown; resource_manifest->entry.size = 0; memset(resource_manifest->entry.hash, 0, sizeof(resource_manifest->entry.hash)); @@ -56,9 +56,9 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res } /* Trim end of line */ - string_strim(resource_manifest->linebuf); + furi_string_trim(resource_manifest->linebuf); - char type_code = string_get_char(resource_manifest->linebuf, 0); + char type_code = furi_string_get_char(resource_manifest->linebuf, 0); switch(type_code) { case 'F': resource_manifest->entry.type = ResourceManifestEntryTypeFile; @@ -75,9 +75,9 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res F::: */ /* Remove entry type code */ - string_right(resource_manifest->linebuf, 2); + furi_string_right(resource_manifest->linebuf, 2); - if(string_search_char(resource_manifest->linebuf, ':') != + if(furi_string_search_char(resource_manifest->linebuf, ':') != sizeof(resource_manifest->entry.hash) * 2) { /* Invalid hash */ continue; @@ -85,27 +85,27 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res /* Read hash */ hex_chars_to_uint8( - string_get_cstr(resource_manifest->linebuf), resource_manifest->entry.hash); + furi_string_get_cstr(resource_manifest->linebuf), resource_manifest->entry.hash); /* Remove hash */ - string_right( + furi_string_right( resource_manifest->linebuf, sizeof(resource_manifest->entry.hash) * 2 + 1); - resource_manifest->entry.size = atoi(string_get_cstr(resource_manifest->linebuf)); + resource_manifest->entry.size = atoi(furi_string_get_cstr(resource_manifest->linebuf)); /* Remove size */ - size_t offs = string_search_char(resource_manifest->linebuf, ':'); - string_right(resource_manifest->linebuf, offs + 1); + size_t offs = furi_string_search_char(resource_manifest->linebuf, ':'); + furi_string_right(resource_manifest->linebuf, offs + 1); - string_set(resource_manifest->entry.name, resource_manifest->linebuf); + furi_string_set(resource_manifest->entry.name, resource_manifest->linebuf); } else if(resource_manifest->entry.type == ResourceManifestEntryTypeDirectory) { /* Parse directory entry D: */ /* Remove entry type code */ - string_right(resource_manifest->linebuf, 2); + furi_string_right(resource_manifest->linebuf, 2); - string_set(resource_manifest->entry.name, resource_manifest->linebuf); + furi_string_set(resource_manifest->entry.name, resource_manifest->linebuf); } return &resource_manifest->entry; diff --git a/lib/update_util/resources/manifest.h b/lib/update_util/resources/manifest.h index 092b7bad..8baa1613 100644 --- a/lib/update_util/resources/manifest.h +++ b/lib/update_util/resources/manifest.h @@ -2,7 +2,6 @@ #include -#include #include #include @@ -18,7 +17,7 @@ typedef enum { typedef struct { ResourceManifestEntryType type; - string_t name; + FuriString* name; uint32_t size; uint8_t hash[16]; } ResourceManifestEntry; diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 1b205d9c..795fdd5e 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -21,12 +21,12 @@ UpdateManifest* update_manifest_alloc() { UpdateManifest* update_manifest = malloc(sizeof(UpdateManifest)); - string_init(update_manifest->version); - string_init(update_manifest->firmware_dfu_image); - string_init(update_manifest->radio_image); - string_init(update_manifest->staged_loader_file); - string_init(update_manifest->resource_bundle); - string_init(update_manifest->splash_file); + update_manifest->version = furi_string_alloc(); + update_manifest->firmware_dfu_image = furi_string_alloc(); + update_manifest->radio_image = furi_string_alloc(); + update_manifest->staged_loader_file = furi_string_alloc(); + update_manifest->resource_bundle = furi_string_alloc(); + update_manifest->splash_file = furi_string_alloc(); update_manifest->target = 0; update_manifest->manifest_version = 0; memset(update_manifest->ob_reference.bytes, 0, FURI_HAL_FLASH_OB_RAW_SIZE_BYTES); @@ -38,12 +38,12 @@ UpdateManifest* update_manifest_alloc() { void update_manifest_free(UpdateManifest* update_manifest) { furi_assert(update_manifest); - string_clear(update_manifest->version); - string_clear(update_manifest->firmware_dfu_image); - string_clear(update_manifest->radio_image); - string_clear(update_manifest->staged_loader_file); - string_clear(update_manifest->resource_bundle); - string_clear(update_manifest->splash_file); + furi_string_free(update_manifest->version); + furi_string_free(update_manifest->firmware_dfu_image); + furi_string_free(update_manifest->radio_image); + furi_string_free(update_manifest->staged_loader_file); + furi_string_free(update_manifest->resource_bundle); + furi_string_free(update_manifest->splash_file); free(update_manifest); } @@ -52,10 +52,10 @@ static bool furi_assert(update_manifest); furi_assert(flipper_file); - string_t filetype; + FuriString* filetype; // TODO: compare filetype? - string_init(filetype); + filetype = furi_string_alloc(); update_manifest->valid = flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && flipper_format_read_string(flipper_file, MANIFEST_KEY_INFO, update_manifest->version) && @@ -68,7 +68,7 @@ static bool MANIFEST_KEY_LOADER_CRC, (uint8_t*)&update_manifest->staged_loader_crc, sizeof(uint32_t)); - string_clear(filetype); + furi_string_free(filetype); if(update_manifest->valid) { /* Optional fields - we can have dfu, radio, resources, or any combination */ @@ -114,9 +114,9 @@ static bool flipper_file, MANIFEST_KEY_SPLASH_FILE, update_manifest->splash_file); update_manifest->valid = - (!string_empty_p(update_manifest->firmware_dfu_image) || - !string_empty_p(update_manifest->radio_image) || - !string_empty_p(update_manifest->resource_bundle)); + (!furi_string_empty(update_manifest->firmware_dfu_image) || + !furi_string_empty(update_manifest->radio_image) || + !furi_string_empty(update_manifest->resource_bundle)); } return update_manifest->valid; diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index 8f385947..c26e4f87 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -6,7 +6,7 @@ extern "C" { #include #include -#include +#include #include /* Paths don't include /ext -- because at startup SD card is mounted as FS root */ @@ -28,20 +28,20 @@ _Static_assert(sizeof(UpdateManifestRadioVersion) == 6, "UpdateManifestRadioVers typedef struct { uint32_t manifest_version; - string_t version; + FuriString* version; uint32_t target; - string_t staged_loader_file; + FuriString* staged_loader_file; uint32_t staged_loader_crc; - string_t firmware_dfu_image; - string_t radio_image; + FuriString* firmware_dfu_image; + FuriString* radio_image; uint32_t radio_address; UpdateManifestRadioVersion radio_version; uint32_t radio_crc; - string_t resource_bundle; + FuriString* resource_bundle; FuriHalFlashRawOptionByteData ob_reference; FuriHalFlashRawOptionByteData ob_compare_mask; FuriHalFlashRawOptionByteData ob_write_mask; - string_t splash_file; + FuriString* splash_file; bool valid; } UpdateManifest; diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index 56f412a9..3a44605e 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -34,9 +33,9 @@ const char* update_operation_describe_preparation_result(const UpdatePrepareResu } } -static bool update_operation_get_current_package_path_rtc(Storage* storage, string_t out_path) { +static bool update_operation_get_current_package_path_rtc(Storage* storage, FuriString* out_path) { const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); - string_set_str(out_path, UPDATE_ROOT_DIR); + furi_string_set(out_path, UPDATE_ROOT_DIR); if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { return true; } @@ -63,7 +62,7 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri free(name_buffer); storage_file_free(dir); if(!found) { - string_reset(out_path); + furi_string_reset(out_path); } return found; @@ -72,8 +71,8 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri #define UPDATE_FILE_POINTER_FN EXT_PATH(UPDATE_MANIFEST_POINTER_FILE_NAME) #define UPDATE_MANIFEST_MAX_PATH_LEN 256u -bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path) { - string_reset(out_path); +bool update_operation_get_current_package_manifest_path(Storage* storage, FuriString* out_path) { + furi_string_reset(out_path); if(storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK) { char* manifest_name_buffer = malloc(UPDATE_MANIFEST_MAX_PATH_LEN); File* upd_file = NULL; @@ -91,23 +90,23 @@ bool update_operation_get_current_package_manifest_path(Storage* storage, string if(storage_common_stat(storage, manifest_name_buffer, NULL) != FSE_OK) { break; } - string_set_str(out_path, manifest_name_buffer); + furi_string_set(out_path, manifest_name_buffer); } while(0); free(manifest_name_buffer); storage_file_free(upd_file); } else { /* legacy, will be deprecated */ - string_t rtcpath; - string_init(rtcpath); + FuriString* rtcpath; + rtcpath = furi_string_alloc(); do { if(!update_operation_get_current_package_path_rtc(storage, rtcpath)) { break; } - path_concat(string_get_cstr(rtcpath), UPDATE_MANIFEST_DEFAULT_NAME, out_path); + path_concat(furi_string_get_cstr(rtcpath), UPDATE_MANIFEST_DEFAULT_NAME, out_path); } while(0); - string_clear(rtcpath); + furi_string_free(rtcpath); } - return !string_empty_p(out_path); + return !furi_string_empty(out_path); } static bool update_operation_persist_manifest_path(Storage* storage, const char* manifest_path) { @@ -141,8 +140,8 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { File* file = storage_file_alloc(storage); uint64_t free_int_space; - string_t stage_path; - string_init(stage_path); + FuriString* stage_path; + stage_path = furi_string_alloc(); do { if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) != FSE_OK) || @@ -171,9 +170,10 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { } path_extract_dirname(manifest_file_path, stage_path); - path_append(stage_path, string_get_cstr(manifest->staged_loader_file)); + path_append(stage_path, furi_string_get_cstr(manifest->staged_loader_file)); - if(!storage_file_open(file, string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(!storage_file_open( + file, furi_string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { result = UpdatePrepareResultStageMissing; break; } @@ -193,7 +193,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); } while(false); - string_clear(stage_path); + furi_string_free(stage_path); storage_file_free(file); update_manifest_free(manifest); diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h index 056520e1..65abf8e1 100644 --- a/lib/update_util/update_operation.h +++ b/lib/update_util/update_operation.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #ifdef __cplusplus @@ -19,7 +18,7 @@ extern "C" { * May be empty if update is in root update directory * @return bool if supplied path is valid and out_manifest_dir contains dir to apply */ -bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir); +bool update_operation_get_package_dir_name(const char* full_path, FuriString* out_manifest_dir); /* When updating this enum, also update assets/protobuf/system.proto */ typedef enum { @@ -51,7 +50,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path); * @param out_path Path to manifest. Must be initialized * @return true if path was restored successfully */ -bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path); +bool update_operation_get_current_package_manifest_path(Storage* storage, FuriString* out_path); /* * Checks if an update operation step is pending after reset From f16cdd1477451f4d8af6f2864f49003a6516f70e Mon Sep 17 00:00:00 2001 From: Matvey Gerasimov <48400794+spherebread@users.noreply.github.com> Date: Thu, 6 Oct 2022 15:18:40 +0400 Subject: [PATCH 02/49] fix: typo badusb demo windows (#1824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a typo in the badusb demo script for Windows. Co-authored-by: あく --- assets/resources/badusb/demo_windows.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/resources/badusb/demo_windows.txt b/assets/resources/badusb/demo_windows.txt index df435351..f304f5e8 100644 --- a/assets/resources/badusb/demo_windows.txt +++ b/assets/resources/badusb/demo_windows.txt @@ -78,7 +78,7 @@ ENTER STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format ENTER -STRING More information about script synax can be found here: +STRING More information about script syntax can be found here: ENTER STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript ENTER From a69e150e2f493bbe89a739bc944aa604d2520987 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 6 Oct 2022 14:36:21 +0300 Subject: [PATCH 03/49] [FL-2812] RFID: write fix for some protocols #1828 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/lfrfid/protocols/protocol_awid.c | 7 +++++++ lib/lfrfid/protocols/protocol_fdx_a.c | 9 +++++++++ lib/lfrfid/protocols/protocol_keri.c | 3 +++ lib/lfrfid/protocols/protocol_pyramid.c | 1 + 4 files changed, 20 insertions(+) diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 69409b31..88093900 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -205,8 +205,15 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) { LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data; bool result = false; + // Fix incorrect length byte + if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 && + protocol->data[0] != 34) { + protocol->data[0] = 26; + } + // Correct protocol data by redecoding protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data); + bit_lib_remove_bit_every_nth((uint8_t*)protocol->encoded_data, 8, 88, 4); protocol_awid_decode(protocol->encoded_data, protocol->data); protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data); diff --git a/lib/lfrfid/protocols/protocol_fdx_a.c b/lib/lfrfid/protocols/protocol_fdx_a.c index 058dc553..87daa0eb 100644 --- a/lib/lfrfid/protocols/protocol_fdx_a.c +++ b/lib/lfrfid/protocols/protocol_fdx_a.c @@ -79,6 +79,14 @@ static bool protocol_fdx_a_decode(const uint8_t* from, uint8_t* to) { return true; } +static void protocol_fdx_a_fix_parity(ProtocolFDXA* protocol) { + for(size_t i = 0; i < FDXA_DECODED_DATA_SIZE; i++) { + if(bit_lib_test_parity_32(protocol->data[i], BitLibParityOdd)) { + protocol->data[i] ^= (1 << 7); + } + } +} + static bool protocol_fdx_a_can_be_decoded(const uint8_t* data) { // check preamble if(data[0] != FDXA_PREAMBLE_0 || data[1] != FDXA_PREAMBLE_1 || data[12] != FDXA_PREAMBLE_0 || @@ -179,6 +187,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) { bool result = false; // Correct protocol data by redecoding + protocol_fdx_a_fix_parity(protocol); protocol_fdx_a_encoder_start(protocol); protocol_fdx_a_decode(protocol->encoded_data, protocol->data); diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index 20e44a70..099fd168 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -170,6 +170,7 @@ bool protocol_keri_encoder_start(ProtocolKeri* protocol) { memset(protocol->encoded_data, 0, KERI_ENCODED_DATA_SIZE); *(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000011100000; bit_lib_copy_bits(protocol->encoded_data, 32, 32, protocol->data, 0); + bit_lib_set_bits(protocol->encoded_data, 32, 1, 1); protocol->encoder.last_bit = bit_lib_get_bit(protocol->encoded_data, KERI_ENCODED_BIT_SIZE - 1); @@ -224,6 +225,8 @@ bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data; bool result = false; + // Start bit should be always set + protocol->data[0] |= (1 << 7); protocol_keri_encoder_start(protocol); if(request->write_type == LFRFIDWriteTypeT5577) { diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index 2e1b57ed..54574458 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -221,6 +221,7 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) { // Correct protocol data by redecoding protocol_pyramid_encode(protocol); + bit_lib_remove_bit_every_nth(protocol->encoded_data, 8, 15 * 8, 8); protocol_pyramid_decode(protocol); protocol_pyramid_encoder_start(protocol); From 9bf11d9fd20576165a5c8c4ece68944abeea9dba Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 6 Oct 2022 17:55:57 +0400 Subject: [PATCH 04/49] [FL-2859,2838] fbt: improvements for FAPs (#1813) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fbt: assets builder for apps WIP * fbt: automatically building private fap assets * docs: details on how to use image assets * fbt: renamed fap_assets -> fap_icons * fbt: support for fap_extbuild field * docs: info on fap_extbuild * fbt: added --proxy-env parame ter * fbt: made firmware_cdb & updater_cdb targets always available * fbt: renamed fap_icons -> fap_icon_assets * fbt: deprecated firmware_* target names for faps; new alias is "fap_APPID" * fbt: changed intermediate file locations for external apps * fbt: support for fap_private_libs; docs: updates * restored mbedtls as global lib * scripts: lint.py: skip "lib" subfolder * fbt: Sanity checks for building advanced faps as part of fw * docs: info on fap_private_libs; fbt: optimized *.fam indexing * fbt: cleanup; samples: added sample_icons app * fbt: moved example app to applications/examples * linter fix * docs: readme fixes * added applications/examples/application.fam stub * docs: more info on private libs Co-authored-by: あく --- applications/examples/application.fam | 5 + .../examples/example_images/application.fam | 10 ++ .../examples/example_images/example_images.c | 79 +++++++++ .../example_images/images/dolphin_71x25.png | Bin 0 -> 1188 bytes applications/plugins/picopass/application.fam | 9 +- .../{ => lib}/loclass/optimized_cipher.c | 0 .../{ => lib}/loclass/optimized_cipher.h | 0 .../{ => lib}/loclass/optimized_cipherutils.c | 0 .../{ => lib}/loclass/optimized_cipherutils.h | 0 .../{ => lib}/loclass/optimized_elite.c | 0 .../{ => lib}/loclass/optimized_elite.h | 0 .../{ => lib}/loclass/optimized_ikeys.c | 0 .../{ => lib}/loclass/optimized_ikeys.h | 0 .../plugins/picopass/picopass_device.h | 4 +- assets/SConscript | 19 +-- documentation/AppManifests.md | 57 ++++++- documentation/AppsOnSDCard.md | 17 +- documentation/fbt.md | 11 +- firmware.scons | 35 ++-- scripts/assets.py | 19 ++- scripts/lint.py | 4 + site_scons/commandline.scons | 9 ++ site_scons/environ.scons | 10 +- site_scons/extapps.scons | 26 ++- site_scons/fbt/appmanifest.py | 25 +++ site_scons/site_tools/fbt_assets.py | 30 +++- site_scons/site_tools/fbt_extapps.py | 150 ++++++++++++++---- 27 files changed, 438 insertions(+), 81 deletions(-) create mode 100644 applications/examples/application.fam create mode 100644 applications/examples/example_images/application.fam create mode 100644 applications/examples/example_images/example_images.c create mode 100644 applications/examples/example_images/images/dolphin_71x25.png rename applications/plugins/picopass/{ => lib}/loclass/optimized_cipher.c (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_cipher.h (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_cipherutils.c (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_cipherutils.h (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_elite.c (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_elite.h (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_ikeys.c (100%) rename applications/plugins/picopass/{ => lib}/loclass/optimized_ikeys.h (100%) diff --git a/applications/examples/application.fam b/applications/examples/application.fam new file mode 100644 index 00000000..16d240cc --- /dev/null +++ b/applications/examples/application.fam @@ -0,0 +1,5 @@ +App( + appid="sample_apps", + name="Sample apps bundle", + apptype=FlipperAppType.METAPACKAGE, +) diff --git a/applications/examples/example_images/application.fam b/applications/examples/example_images/application.fam new file mode 100644 index 00000000..9a5f8e03 --- /dev/null +++ b/applications/examples/example_images/application.fam @@ -0,0 +1,10 @@ +App( + appid="example_images", + name="Example: Images", + apptype=FlipperAppType.EXTERNAL, + entry_point="example_images_main", + requires=["gui"], + stack_size=1 * 1024, + fap_category="Examples", + fap_icon_assets="images", +) diff --git a/applications/examples/example_images/example_images.c b/applications/examples/example_images/example_images.c new file mode 100644 index 00000000..48fa5e77 --- /dev/null +++ b/applications/examples/example_images/example_images.c @@ -0,0 +1,79 @@ +#include +#include + +#include +#include + +#include "example_images_icons.h" + +typedef struct { + uint8_t x, y; +} ImagePosition; + +static ImagePosition image_position = {.x = 0, .y = 0}; + +// Screen is 128x64 px +static void app_draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + + canvas_clear(canvas); + canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25); +} + +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t example_images_main(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_input_callback_set(view_port, app_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + InputEvent event; + + bool running = true; + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) { + switch(event.key) { + case InputKeyLeft: + image_position.x -= 2; + break; + case InputKeyRight: + image_position.x += 2; + break; + case InputKeyUp: + image_position.y -= 2; + break; + case InputKeyDown: + image_position.y += 2; + break; + default: + running = false; + break; + } + } + } + view_port_update(view_port); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/applications/examples/example_images/images/dolphin_71x25.png b/applications/examples/example_images/images/dolphin_71x25.png new file mode 100644 index 0000000000000000000000000000000000000000..6b3f8aa59b91c644a942bbe12f16c93f4c2d4619 GIT binary patch literal 1188 zcmaJ>TWAzl7@kEf7@I;~nks=zCO(*wx$f*`#%yF}XLqwDyN&A>qX;^elkAYpoN;E7 zT_ad+1+A!okV0Py4WTxu1Va$ocu7nty*w!DqxewhOYlKo`cO5bXEwXhhv>kWbN(~m z_uv2drZ1mqY}nO+VOV3fM=78^gVxT_7W6*!a_R}%LS7*wW3%^LR*YCPxa}3AQ3{SH>$uMGA5P2T2Jp{6c<6W*XAQqH#%^s2xM9KFZk*3S#GF1*!&>f^% zK@ez$qdAU52+})Y`)Y->z4mn_H8l$Gbk}rz6WVy7R@LB$pCFLS>#V-n3T8~@-t~m;fvub zaw?2&QUafr!$gg1Y?8kkH}Y;SU2Q?+5*@V5TkW&nn$=s>o55hv8Yf7xu#|2!_;DXYyRGERL7p5^$ #include "rfal_picopass.h" -#include "loclass/optimized_ikeys.h" -#include "loclass/optimized_cipher.h" +#include +#include #define PICOPASS_DEV_NAME_MAX_LEN 22 #define PICOPASS_READER_DATA_MAX_SIZE 64 diff --git a/assets/SConscript b/assets/SConscript index a0b3b13a..e1bf546c 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -9,28 +9,13 @@ assetsenv = env.Clone( ) assetsenv.ApplyLibFlags() -if not assetsenv["VERBOSE"]: - assetsenv.SetDefault( - ICONSCOMSTR="\tICONS\t${TARGET}", - PROTOCOMSTR="\tPROTO\t${SOURCE}", - DOLPHINCOMSTR="\tDOLPHIN\t${DOLPHIN_RES_TYPE}", - RESMANIFESTCOMSTR="\tMANIFEST\t${TARGET}", - PBVERCOMSTR="\tPBVER\t${TARGET}", - ) - -# Gathering icons sources -icons_src = assetsenv.GlobRecursive("*.png", "icons") -icons_src += assetsenv.GlobRecursive("frame_rate", "icons") - -icons = assetsenv.IconBuilder( - assetsenv.Dir("compiled"), ICON_SRC_DIR=assetsenv.Dir("#/assets/icons") +icons = assetsenv.CompileIcons( + assetsenv.Dir("compiled"), assetsenv.Dir("#/assets/icons") ) -assetsenv.Depends(icons, icons_src) assetsenv.Alias("icons", icons) # Protobuf .proto -> .c + .h - proto_src = assetsenv.Glob("protobuf/*.proto", source=True) proto_options = assetsenv.Glob("protobuf/*.options", source=True) proto = assetsenv.ProtoBuilder(assetsenv.Dir("compiled"), proto_src) diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 0a4f5e9b..14c0ae3a 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -41,9 +41,12 @@ Only 2 parameters are mandatory: ***appid*** and ***apptype***, others are optio * **order**: Order of an application within its group when sorting entries in it. The lower the order is, the closer to the start of the list the item is placed. *Used for ordering startup hooks and menu entries.* * **sdk_headers**: List of C header files from this app's code to include in API definitions for external applications. + +#### Parameters for external applications + The following parameters are used only for [FAPs](./AppsOnSDCard.md): -* **sources**: list of strings, file name masks, used for gathering sources within app folder. Default value of `["*.c*"]` includes C and CPP source files. +* **sources**: list of strings, file name masks, used for gathering sources within app folder. Default value of `["*.c*"]` includes C and C++ source files. Application cannot use `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**. * **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meanig version "0.1". * **fap_icon**: name of a .png file, 1-bit color depth, 10x10px, to be embedded within .fap file. * **fap_libs**: list of extra libraries to link application against. Provides access to extra functions that are not exported as a part of main firmware at expense of increased .fap file size and RAM consumption. @@ -51,6 +54,58 @@ The following parameters are used only for [FAPs](./AppsOnSDCard.md): * **fap_description**: string, may be empty. Short application description. * **fap_author**: string, may be empty. Application's author. * **fap_weburl**: string, may be empty. Application's homepage. +* **fap_icon_assets**: string. If present, defines a folder name to be used for gathering image assets for this application. These images will be preprocessed and built alongside the application. See [FAP assets](./AppsOnSDCard.md#fap-assets) for details. +* **fap_extbuild**: provides support for parts of application sources to be build by external tools. Contains a list of `ExtFile(path="file name", command="shell command")` definitions. **`fbt`** will run the specified command for each file in the list. +Note that commands are executed at the firmware root folder's root, and all intermediate files must be placed in a application's temporary build folder. For that, you can use pattern expansion by **`fbt`**: `${FAP_WORK_DIR}` will be replaced with the path to the application's temporary build folder, and `${FAP_SRC_DIR}` will be replaced with the path to the application's source folder. You can also use other variables defined internally by **`fbt`**. + +Example for building an app from Rust sources: + +```python + sources=["target/thumbv7em-none-eabihf/release/libhello_rust.a"], + fap_extbuild=( + ExtFile( + path="${FAP_WORK_DIR}/target/thumbv7em-none-eabihf/release/libhello_rust.a", + command="cargo build --release --verbose --target thumbv7em-none-eabihf --target-dir ${FAP_WORK_DIR}/target --manifest-path ${FAP_SRC_DIR}/Cargo.toml", + ), + ), +``` + +* **fap_private_libs**: list of additional libraries that are distributed as sources alongside the application. These libraries will be built as a part of the application build process. +Library sources must be placed in a subfolder of "`lib`" folder within the application's source folder. +Each library is defined as a call to `Lib()` function, accepting the following parameters: + + - **name**: name of library's folder. Required. + - **fap_include_paths**: list of library's relative paths to add to parent fap's include path list. Default value is `["."]` meaning library's source root. + - **sources**: list of filename masks to be used for gathering include files for this library. Default value is `["*.c*"]`. + - **cflags**: list of additional compiler flags to be used for building this library. Default value is `[]`. + - **cdefines**: list of additional preprocessor definitions to be used for building this library. Default value is `[]`. + - **cincludes**: list of additional include paths to be used for building this library. Can be used for providing external search paths for this library's code - for configuration headers. Default value is `[]`. + +Example for building an app with a private library: + +```python + fap_private_libs=[ + Lib( + name="mbedtls", + fap_include_paths=["include"], + sources=[ + "library/des.c", + "library/sha1.c", + "library/platform_util.c", + ], + cdefines=["MBEDTLS_ERROR_C"], + ), + Lib( + name="loclass", + cflags=["-Wno-error"], + ), + ], +``` + +For that snippet, **`fbt`** will build 2 libraries: one from sources in `lib/mbedtls` folder, and another from sources in `lib/loclass` folder. For `mbedtls` library, **`fbt`** will add `lib/mbedtls/include` to the list of include paths for the application and compile only the files specified in `sources` list. Additionally, **`fbt`** will enable `MBEDTLS_ERROR_C` preprocessor definition for `mbedtls` sources. +For `loclass` library, **`fbt`** will add `lib/loclass` to the list of include paths for the application and build all sources in that folder. Also **`fbt`** will disable treating compiler warnings as errors for `loclass` library specifically - that can be useful when compiling large 3rd-party codebases. + +Both libraries will be linked into the application. ## .fam file contents diff --git a/documentation/AppsOnSDCard.md b/documentation/AppsOnSDCard.md index 52582153..552be13e 100644 --- a/documentation/AppsOnSDCard.md +++ b/documentation/AppsOnSDCard.md @@ -2,7 +2,7 @@ [fbt](./fbt.md) has support for building applications as FAP files. FAP are essentially .elf executables with extra metadata and resources bundled in. -FAPs are built with `firmware_extapps` (or `plugin_dist`) **`fbt`** targets. +FAPs are built with `faps` **`fbt`** target. They can also be deployed to `dist` folder with `plugin_dist` **`fbt`** target. FAPs do not depend on being run on a specific firmware version. Compatibility is determined by the FAP's metadata, which includes the required [API version](#api-versioning). @@ -18,6 +18,17 @@ To build your application as a FAP, just create a folder with your app's source * To build all FAPs, run `./fbt plugin_dist`. +## FAP assets + +FAPs can include static and animated images as private assets. They will be automatically compiled alongside application sources and can be referenced the same way as assets from the main firmware. + +To use that feature, put your images in a subfolder inside your application's folder, then reference that folder in your application's manifest in `fap_icon_assets` field. See [Application Manifests](./AppManifests.md#application-definition) for more details. + +To use these assets in your application, put `#include "{APPID}_icons.h"` in your application's source code, where `{APPID}` is the `appid` value field from your application's manifest. Then you can use all icons from your application's assets the same way as if they were a part of `assets_icons.h` of the main firmware. + +Images and animated icons must follow the same [naming convention](../assets/ReadMe.md#asset-naming-rules) as those from the main firmware. + + ## Debugging FAPs **`fbt`** includes a script for gdb-py to provide debugging support for FAPs, `debug/flipperapps.py`. It is loaded in default debugging configurations by **`fbt`** and stock VSCode configurations. @@ -53,13 +64,13 @@ App loader allocates memory for the application and copies it to RAM, processing Not all parts of firmware are available for external applications. A subset of available functions and variables is defined in "api_symbols.csv" file, which is a part of firmware target definition in `firmware/targets/` directory. -**`fbt`** uses semantic versioning for API versioning. Major version is incremented when there are breaking changes in the API, minor version is incremented when there are new features added. +**`fbt`** uses semantic versioning for API. Major version is incremented when there are breaking changes in the API, minor version is incremented when new features are added. Breaking changes include: - removal of a function or a global variable; - changing the signature of a function. -API versioning is mostly automated by **`fbt`**. When rebuilding the firmware, **`fbt`** checks if there are any changes in the API exposed by headers gathered from `SDK_HEADERS`. If there are, it stops the build, adjusts the API version and asks the user to go through the changes in .csv file. New entries are marked with "`?`" mark, and the user is supposed to change the mark to "`+`" for the entry to be exposed for FAPs, "`-`" for it to be unavailable. +API versioning is mostly automated by **`fbt`**. When rebuilding the firmware, **`fbt`** checks if there are any changes in the API exposed by headers gathered from `SDK_HEADERS`. If so, it stops the build, adjusts the API version and asks the user to go through the changes in .csv file. New entries are marked with "`?`" mark, and the user is supposed to change the mark to "`+`" for the entry to be exposed for FAPs, "`-`" for it to be unavailable. **`fbt`** will not allow building a firmware until all "`?`" entries are changed to "`+`" or "`-`". diff --git a/documentation/fbt.md b/documentation/fbt.md index 090ff78f..e20d4317 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -59,10 +59,11 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. ### Firmware targets -- `firmware_extapps` - build all plug-ins as separate .elf files - - `firmware_snake_game`, etc - build single plug-in as .elf by its name - - Check out `--extra-ext-apps` for force adding extra apps to external build - - `firmware_snake_game_list`, etc - generate source + assembler listing for app's .elf +- `faps` - build all external & plugin apps as [.faps](./AppsOnSDCard.md#fap-flipper-application-package). +- **`fbt`** also defines per-app targets. For example, for an app with `appid=snake_game` target names are: + - `fap_snake_game`, etc - build single app as .fap by its application ID. + - Check out [`--extra-ext-apps`](#command-line-parameters) for force adding extra apps to external build + - `fap_snake_game_list`, etc - generate source + assembler listing for app's .fap - `flash`, `firmware_flash` - flash current version to attached device with OpenOCD over ST-Link - `jflash` - flash current version to attached device with JFlash using J-Link probe. JFlash executable must be on your $PATH - `flash_blackmagic` - flash current version to attached device with Blackmagic probe @@ -83,9 +84,9 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. ## Command-line parameters - `--options optionfile.py` (default value `fbt_options.py`) - load file with multiple configuration values -- `--with-updater` - enables updater-related targets and dependency tracking. Enabling this option introduces extra startup time costs, so use it when bundling update packages. _Explicily enabling this should no longer be required, **`fbt`** now has specific handling for updater-related targets_ - `--extra-int-apps=app1,app2,appN` - forces listed apps to be built as internal with `firmware` target - `--extra-ext-apps=app1,app2,appN` - forces listed apps to be built as external with `firmware_extapps` target +- `--proxy-env=VAR1,VAR2` - additional environment variables to expose to subprocesses spawned by `fbt`. By default, `fbt` sanitizes execution environment and doesn't forward all inherited environment variables. You can find list of variables that are always forwarded in `environ.scons` file. ## Configuration diff --git a/firmware.scons b/firmware.scons index 0970541e..dd13b6b3 100644 --- a/firmware.scons +++ b/firmware.scons @@ -1,5 +1,6 @@ Import("ENV", "fw_build_meta") +from SCons.Errors import UserError import itertools from fbt.util import ( @@ -164,13 +165,25 @@ apps_c = fwenv.ApplicationsC( # Adding dependency on manifest files so apps.c is rebuilt when any manifest is changed for app_dir, _ in env["APPDIRS"]: app_dir_node = env.Dir("#").Dir(app_dir) - fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", app_dir_node)) + fwenv.Depends(apps_c, app_dir_node.glob("*/application.fam")) + +# Sanity check - certain external apps are using features that are not available in base firmware +if advanced_faps := list( + filter( + lambda app: app.fap_extbuild or app.fap_private_libs or app.fap_icon_assets, + fwenv["APPBUILD"].get_builtin_apps(), + ) +): + raise UserError( + "An Application that is using fap-specific features cannot be built into base firmware." + f" Offending app(s): {', '.join(app.appid for app in advanced_faps)}" + ) sources = [apps_c] # Gather sources only from app folders in current configuration sources.extend( itertools.chain.from_iterable( - fwenv.GlobRecursive(source_type, appdir.relpath) + fwenv.GlobRecursive(source_type, appdir.relpath, exclude="lib") for appdir, source_type in fwenv["APPBUILD"].get_builtin_app_folders() ) ) @@ -259,18 +272,18 @@ fw_artifacts = fwenv["FW_ARTIFACTS"] = [ fwenv["FW_VERSION_JSON"], ] + +fwcdb = fwenv.CompilationDatabase() +# without filtering, both updater & firmware commands would be generated in same file +fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*")) +AlwaysBuild(fwcdb) +Precious(fwcdb) +NoClean(fwcdb) +Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) + # If current configuration was explicitly requested, generate compilation database # and link its directory as build/latest if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): - fwcdb = fwenv.CompilationDatabase() - # without filtering, both updater & firmware commands would be generated - fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*")) - AlwaysBuild(fwcdb) - Precious(fwcdb) - NoClean(fwcdb) - Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) - AlwaysBuild(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) - Alias(fwcdb, "") fw_artifacts.append(fwcdb) # Adding as a phony target, so folder link is updated even if elf didn't change diff --git a/scripts/assets.py b/scripts/assets.py index 9b4ee5b6..75bebcfb 100755 --- a/scripts/assets.py +++ b/scripts/assets.py @@ -14,7 +14,7 @@ ICONS_TEMPLATE_H_HEADER = """#pragma once """ ICONS_TEMPLATE_H_ICON_NAME = "extern const Icon {name};\n" -ICONS_TEMPLATE_C_HEADER = """#include \"assets_icons.h\" +ICONS_TEMPLATE_C_HEADER = """#include "{assets_filename}.h" #include @@ -33,6 +33,13 @@ class Main(App): ) self.parser_icons.add_argument("input_directory", help="Source directory") self.parser_icons.add_argument("output_directory", help="Output directory") + self.parser_icons.add_argument( + "--filename", + help="Base filename for file with icon data", + required=False, + default="assets_icons", + ) + self.parser_icons.set_defaults(func=self.icons) self.parser_manifest = self.subparsers.add_parser( @@ -102,13 +109,15 @@ class Main(App): return extension in ICONS_SUPPORTED_FORMATS def icons(self): - self.logger.debug(f"Converting icons") + self.logger.debug("Converting icons") icons_c = open( - os.path.join(self.args.output_directory, "assets_icons.c"), + os.path.join(self.args.output_directory, f"{self.args.filename}.c"), "w", newline="\n", ) - icons_c.write(ICONS_TEMPLATE_C_HEADER) + icons_c.write( + ICONS_TEMPLATE_C_HEADER.format(assets_filename=self.args.filename) + ) icons = [] # Traverse icons tree, append image data to source file for dirpath, dirnames, filenames in os.walk(self.args.input_directory): @@ -194,7 +203,7 @@ class Main(App): # Create Public Header self.logger.debug(f"Creating header") icons_h = open( - os.path.join(self.args.output_directory, "assets_icons.h"), + os.path.join(self.args.output_directory, f"{self.args.filename}.h"), "w", newline="\n", ) diff --git a/scripts/lint.py b/scripts/lint.py index 30a5699a..c178c876 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -54,6 +54,10 @@ class Main(App): output = [] for folder in folders: for dirpath, dirnames, filenames in os.walk(folder): + # Skipping 3rd-party code - usually resides in subfolder "lib" + if "lib" in dirnames: + dirnames.remove("lib") + for filename in filenames: ext = os.path.splitext(filename.lower())[1] if not ext in SOURCE_CODE_FILE_EXTENSIONS: diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 2eeda247..765af08f 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -34,6 +34,14 @@ AddOption( help="List of applications to forcefully build as standalone .elf", ) +AddOption( + "--proxy-env", + action="store", + dest="proxy_env", + default="", + help="Comma-separated list of additional environment variables to pass to child SCons processes", +) + # Construction environment variables @@ -230,6 +238,7 @@ vars.Add( ("applications/system", False), ("applications/debug", False), ("applications/plugins", False), + ("applications/examples", False), ("applications_user", False), ], ) diff --git a/site_scons/environ.scons b/site_scons/environ.scons index c61f2961..3e0c6bea 100644 --- a/site_scons/environ.scons +++ b/site_scons/environ.scons @@ -12,14 +12,20 @@ forward_os_env = { "PATH": os.environ["PATH"], } # Proxying CI environment to child processes & scripts -for env_value_name in ( +variables_to_forward = [ "WORKFLOW_BRANCH_OR_TAG", "DIST_SUFFIX", "HOME", "APPDATA", "PYTHONHOME", "PYTHONNOUSERSITE", -): + "TMP", + "TEMP", +] +if proxy_env := GetOption("proxy_env"): + variables_to_forward.extend(proxy_env.split(",")) + +for env_value_name in variables_to_forward: if environ_value := os.environ.get(env_value_name, None): forward_os_env[env_value_name] = environ_value diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 66002915..c976fbbe 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -1,10 +1,23 @@ +from SCons.Errors import UserError + + Import("ENV") from fbt.appmanifest import FlipperAppType appenv = ENV.Clone( - tools=[("fbt_extapps", {"EXT_APPS_WORK_DIR": ENV.subst("${BUILD_DIR}/.extapps")})] + tools=[ + ( + "fbt_extapps", + { + "EXT_APPS_WORK_DIR": ENV.subst( + "${BUILD_DIR}/.extapps", + ) + }, + ), + "fbt_assets", + ] ) appenv.Replace( @@ -83,7 +96,16 @@ if extra_app_list := GetOption("extra_ext_apps"): if appenv["FORCE"]: appenv.AlwaysBuild(extapps["compact"].values()) -Alias(appenv["FIRMWARE_BUILD_CFG"] + "_extapps", extapps["compact"].values()) + +# Deprecation stub +def legacy_app_build_stub(**kw): + raise UserError(f"Target name 'firmware_extapps' is deprecated, use 'faps' instead") + + +appenv.PhonyTarget("firmware_extapps", appenv.Action(legacy_app_build_stub, None)) + + +Alias("faps", extapps["compact"].values()) if appsrc := appenv.subst("$APPSRC"): app_manifest, fap_file, app_validator = appenv.GetExtAppFromPath(appsrc) diff --git a/site_scons/fbt/appmanifest.py b/site_scons/fbt/appmanifest.py index a1132eea..de7c6b68 100644 --- a/site_scons/fbt/appmanifest.py +++ b/site_scons/fbt/appmanifest.py @@ -23,6 +23,22 @@ class FlipperAppType(Enum): @dataclass class FlipperApplication: + @dataclass + class ExternallyBuiltFile: + path: str + command: str + + @dataclass + class Library: + name: str + fap_include_paths: List[str] = field(default_factory=lambda: ["."]) + sources: List[str] = field(default_factory=lambda: ["*.c*"]) + cflags: List[str] = field(default_factory=list) + cdefines: List[str] = field(default_factory=list) + cincludes: List[str] = field(default_factory=list) + + PRIVATE_FIELD_PREFIX = "_" + appid: str apptype: FlipperAppType name: Optional[str] = "" @@ -45,6 +61,9 @@ class FlipperApplication: fap_description: str = "" fap_author: str = "" fap_weburl: str = "" + fap_icon_assets: Optional[str] = None + fap_extbuild: List[ExternallyBuiltFile] = field(default_factory=list) + fap_private_libs: List[Library] = field(default_factory=list) # Internally used by fbt _appdir: Optional[object] = None _apppath: Optional[str] = None @@ -88,6 +107,12 @@ class AppManager: ), ) + def ExtFile(*args, **kw): + return FlipperApplication.ExternallyBuiltFile(*args, **kw) + + def Lib(*args, **kw): + return FlipperApplication.Library(*args, **kw) + try: with open(app_manifest_path, "rt") as manifest_file: exec(manifest_file.read()) diff --git a/site_scons/site_tools/fbt_assets.py b/site_scons/site_tools/fbt_assets.py index 87794847..f058d15f 100644 --- a/site_scons/site_tools/fbt_assets.py +++ b/site_scons/site_tools/fbt_assets.py @@ -10,8 +10,8 @@ import subprocess def icons_emitter(target, source, env): target = [ - "compiled/assets_icons.c", - "compiled/assets_icons.h", + target[0].File(env.subst("${ICON_FILE_NAME}.c")), + target[0].File(env.subst("${ICON_FILE_NAME}.h")), ] source = env.GlobRecursive("*.*", env["ICON_SRC_DIR"]) return target, source @@ -99,17 +99,41 @@ def proto_ver_generator(target, source, env): file.write("\n".join(version_file_data)) +def CompileIcons(env, target_dir, source_dir, *, icon_bundle_name="assets_icons"): + # Gathering icons sources + icons_src = env.GlobRecursive("*.png", source_dir) + icons_src += env.GlobRecursive("frame_rate", source_dir) + + icons = env.IconBuilder( + target_dir, + ICON_SRC_DIR=source_dir, + ICON_FILE_NAME=icon_bundle_name, + ) + env.Depends(icons, icons_src) + return icons + + def generate(env): env.SetDefault( ASSETS_COMPILER="${ROOT_DIR.abspath}/scripts/assets.py", NANOPB_COMPILER="${ROOT_DIR.abspath}/lib/nanopb/generator/nanopb_generator.py", ) + env.AddMethod(CompileIcons) + + if not env["VERBOSE"]: + env.SetDefault( + ICONSCOMSTR="\tICONS\t${TARGET}", + PROTOCOMSTR="\tPROTO\t${SOURCE}", + DOLPHINCOMSTR="\tDOLPHIN\t${DOLPHIN_RES_TYPE}", + RESMANIFESTCOMSTR="\tMANIFEST\t${TARGET}", + PBVERCOMSTR="\tPBVER\t${TARGET}", + ) env.Append( BUILDERS={ "IconBuilder": Builder( action=Action( - '${PYTHON3} "${ASSETS_COMPILER}" icons ${ICON_SRC_DIR} ${TARGET.dir}', + '${PYTHON3} "${ASSETS_COMPILER}" icons ${ICON_SRC_DIR} ${TARGET.dir} --filename ${ICON_FILE_NAME}', "${ICONSCOMSTR}", ), emitter=icons_emitter, diff --git a/site_scons/site_tools/fbt_extapps.py b/site_scons/site_tools/fbt_extapps.py index fec24071..a1fa7714 100644 --- a/site_scons/site_tools/fbt_extapps.py +++ b/site_scons/site_tools/fbt_extapps.py @@ -6,56 +6,146 @@ import SCons.Warnings import os import pathlib from fbt.elfmanifest import assemble_manifest_data +from fbt.appmanifest import FlipperManifestException from fbt.sdk import SdkCache import itertools +from site_scons.fbt.appmanifest import FlipperApplication + def BuildAppElf(env, app): - work_dir = env.subst("$EXT_APPS_WORK_DIR") + ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR") + app_work_dir = os.path.join(ext_apps_work_dir, app.appid) + + env.VariantDir(app_work_dir, app._appdir, duplicate=False) + + app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir) + + app_alias = f"fap_{app.appid}" + + # Deprecation stub + legacy_app_taget_name = f"{app_env['FIRMWARE_BUILD_CFG']}_{app.appid}" + + def legacy_app_build_stub(**kw): + raise UserError( + f"Target name '{legacy_app_taget_name}' is deprecated, use '{app_alias}' instead" + ) + + app_env.PhonyTarget(legacy_app_taget_name, Action(legacy_app_build_stub, None)) + + externally_built_files = [] + if app.fap_extbuild: + for external_file_def in app.fap_extbuild: + externally_built_files.append(external_file_def.path) + app_env.Alias(app_alias, external_file_def.path) + app_env.AlwaysBuild( + app_env.Command( + external_file_def.path, + None, + Action( + external_file_def.command, + "" if app_env["VERBOSE"] else "\tEXTCMD\t${TARGET}", + ), + ) + ) + + if app.fap_icon_assets: + app_env.CompileIcons( + app_env.Dir(app_work_dir), + app._appdir.Dir(app.fap_icon_assets), + icon_bundle_name=f"{app.appid}_icons", + ) + + private_libs = [] + + for lib_def in app.fap_private_libs: + lib_src_root_path = os.path.join(app_work_dir, "lib", lib_def.name) + app_env.AppendUnique( + CPPPATH=list( + app_env.Dir(lib_src_root_path).Dir(incpath).srcnode() + for incpath in lib_def.fap_include_paths + ), + ) + + lib_sources = list( + itertools.chain.from_iterable( + app_env.GlobRecursive(source_type, lib_src_root_path) + for source_type in lib_def.sources + ) + ) + if len(lib_sources) == 0: + raise UserError(f"No sources gathered for private library {lib_def}") + + private_lib_env = app_env.Clone() + private_lib_env.AppendUnique( + CCFLAGS=[ + *lib_def.cflags, + ], + CPPDEFINES=lib_def.cdefines, + CPPPATH=list( + os.path.join(app._appdir.path, cinclude) + for cinclude in lib_def.cincludes + ), + ) + + lib = private_lib_env.StaticLibrary( + os.path.join(app_work_dir, lib_def.name), + lib_sources, + ) + private_libs.append(lib) - app_alias = f"{env['FIRMWARE_BUILD_CFG']}_{app.appid}" - app_original_elf = os.path.join(work_dir, f"{app.appid}_d") app_sources = list( itertools.chain.from_iterable( - env.GlobRecursive(source_type, os.path.join(work_dir, app._appdir.relpath)) + app_env.GlobRecursive( + source_type, + app_work_dir, + exclude="lib", + ) for source_type in app.sources ) ) - app_elf_raw = env.Program( - app_original_elf, - app_sources, - APP_ENTRY=app.entry_point, - LIBS=env["LIBS"] + app.fap_libs, + + app_env.Append( + LIBS=[*app.fap_libs, *private_libs], + CPPPATH=env.Dir(app_work_dir), ) - app_elf_dump = env.ObjDump(app_elf_raw) - env.Alias(f"{app_alias}_list", app_elf_dump) + app_elf_raw = app_env.Program( + os.path.join(app_work_dir, f"{app.appid}_d"), + app_sources, + APP_ENTRY=app.entry_point, + ) - app_elf_augmented = env.EmbedAppMetadata( - os.path.join(env.subst("$PLUGIN_ELF_DIR"), app.appid), + app_env.Clean(app_elf_raw, [*externally_built_files, app_env.Dir(app_work_dir)]) + + app_elf_dump = app_env.ObjDump(app_elf_raw) + app_env.Alias(f"{app_alias}_list", app_elf_dump) + + app_elf_augmented = app_env.EmbedAppMetadata( + os.path.join(ext_apps_work_dir, app.appid), app_elf_raw, APP=app, ) - manifest_vals = vars(app) manifest_vals = { - k: v for k, v in manifest_vals.items() if k not in ("_appdir", "_apppath") + k: v + for k, v in vars(app).items() + if not k.startswith(FlipperApplication.PRIVATE_FIELD_PREFIX) } - env.Depends( + app_env.Depends( app_elf_augmented, - [env["SDK_DEFINITION"], env.Value(manifest_vals)], + [app_env["SDK_DEFINITION"], app_env.Value(manifest_vals)], ) if app.fap_icon: - env.Depends( + app_env.Depends( app_elf_augmented, - env.File(f"{app._apppath}/{app.fap_icon}"), + app_env.File(f"{app._apppath}/{app.fap_icon}"), ) - env.Alias(app_alias, app_elf_augmented) - app_elf_import_validator = env.ValidateAppImports(app_elf_augmented) - env.AlwaysBuild(app_elf_import_validator) - env.Alias(app_alias, app_elf_import_validator) + app_elf_import_validator = app_env.ValidateAppImports(app_elf_augmented) + app_env.AlwaysBuild(app_elf_import_validator) + app_env.Alias(app_alias, app_elf_import_validator) return (app_elf_augmented, app_elf_raw, app_elf_import_validator) @@ -101,9 +191,15 @@ def GetExtAppFromPath(env, app_dir): appmgr = env["APPMGR"] app = None - for dir_part in reversed(pathlib.Path(app_dir).parts): - if app := appmgr.find_by_appdir(dir_part): - break + try: + # Maybe used passed an appid? + app = appmgr.get(app_dir) + except FlipperManifestException as _: + # Look up path components in known app dits + for dir_part in reversed(pathlib.Path(app_dir).parts): + if app := appmgr.find_by_appdir(dir_part): + break + if not app: raise UserError(f"Failed to resolve application for given APPSRC={app_dir}") @@ -120,7 +216,7 @@ def GetExtAppFromPath(env, app_dir): def generate(env, **kw): env.SetDefault(EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR")) - env.VariantDir(env.subst("$EXT_APPS_WORK_DIR"), env.Dir("#"), duplicate=False) + # env.VariantDir(env.subst("$EXT_APPS_WORK_DIR"), env.Dir("#"), duplicate=False) env.AddMethod(BuildAppElf) env.AddMethod(GetExtAppFromPath) From 61189c3c82cbd397bb9a18619c4ad3bce4d9293d Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Thu, 6 Oct 2022 17:18:20 +0300 Subject: [PATCH 05/49] [FL-2847] FFF trailing space fix (#1811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve whitespace handlilng in FFF * Add tests for odd fff user input * Adjust formatting Co-authored-by: あく --- .../flipper_format/flipper_format_test.c | 26 ++++++++ lib/flipper_format/flipper_format_stream.c | 63 +++++++++++-------- 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index ccd5e751..012e905b 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n" "Hex data: DE AD BE"; #define READ_TEST_FLP "ff_flp.test" +#define READ_TEST_ODD "ff_oddities.test" +static const char* test_data_odd = "Filetype: Flipper File test\n" + // Tabs before newline + "Version: 666\t\t\n" + "# This is comment\n" + // Windows newline in a UNIX file + "String data: String\r\n" + // Trailing whitespace + "Int32 data: 1234 -6345 7813 0 \n" + // Extra whitespace + "Uint32 data: 1234 0 5678 9098 7654321 \n" + // Mixed whitespace + "Float data: 1.5\t \t1000.0\n" + // Leading tabs after key + "Bool data:\t\ttrue false\n" + // Mixed trailing whitespace + "Hex data: DE AD BE\t "; // data created by user on linux machine static const char* test_file_linux = TEST_DIR READ_TEST_NIX; @@ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX; static const char* test_file_windows = TEST_DIR READ_TEST_WIN; // data created by flipper itself static const char* test_file_flipper = TEST_DIR READ_TEST_FLP; +// data containing odd user input +static const char* test_file_oddities = TEST_DIR READ_TEST_ODD; static bool storage_write_string(const char* path, const char* data) { Storage* storage = furi_record_open(RECORD_STORAGE); @@ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) { mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error"); } +MU_TEST(flipper_format_oddities_test) { + mu_assert( + storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); + mu_assert(test_read(test_file_linux), "Read test error [Oddities]"); +} + MU_TEST_SUITE(flipper_format) { tests_setup(); MU_RUN_TEST(flipper_format_write_test); @@ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) { MU_RUN_TEST(flipper_format_update_2_test); MU_RUN_TEST(flipper_format_update_2_result_test); MU_RUN_TEST(flipper_format_multikey_test); + MU_RUN_TEST(flipper_format_oddities_test); tests_teardown(); } diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index ecc68d4e..41934a3b 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -4,6 +4,10 @@ #include "flipper_format_stream.h" #include "flipper_format_stream_i.h" +static inline bool flipper_format_stream_is_space(char c) { + return c == ' ' || c == '\t' || c == flipper_format_eolr; +} + static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) { size_t bytes_written = stream_write(stream, data, data_size); return bytes_written == data_size; @@ -118,55 +122,64 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str } static bool flipper_format_stream_read_value(Stream* stream, FuriString* value, bool* last) { - furi_string_reset(value); + enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace; const size_t buffer_size = 32; uint8_t buffer[buffer_size]; bool result = false; bool error = false; + furi_string_reset(value); + while(true) { size_t was_read = stream_read(stream, buffer, buffer_size); if(was_read == 0) { - // check EOF - if(stream_eof(stream) && furi_string_size(value) > 0) { + if(state != LeadingSpace && stream_eof(stream)) { result = true; *last = true; - break; + } else { + error = true; } } for(uint16_t i = 0; i < was_read; i++) { - uint8_t data = buffer[i]; - if(data == flipper_format_eoln) { - if(furi_string_size(value) > 0) { - if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { - error = true; - break; - } + const uint8_t data = buffer[i]; - result = true; - *last = true; + if(state == LeadingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(data == flipper_format_eoln) { + stream_seek(stream, i - was_read, StreamOffsetFromCurrent); + error = true; break; } else { - error = true; + state = ReadValue; + furi_string_push_back(value, data); } - } else if(data == ' ') { - if(furi_string_size(value) > 0) { + } else if(state == ReadValue) { + if(flipper_format_stream_is_space(data)) { + state = TrailingSpace; + } else if(data == flipper_format_eoln) { if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { error = true; - break; + } else { + result = true; + *last = true; } - - result = true; - *last = false; break; + } else { + furi_string_push_back(value, data); } - - } else if(data == flipper_format_eolr) { - // Ignore - } else { - furi_string_push_back(value, data); + } else if(state == TrailingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { + error = true; + } else { + *last = (data == flipper_format_eoln); + result = true; + } + break; } } From 061f53cd3c9493bfff34a370d087281fe495ca22 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 6 Oct 2022 18:43:17 +0400 Subject: [PATCH 06/49] [FL-2849] SubGhz: read RAW auto generation of names (#1772) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: read RAW auto auto generation of names depending on the date of the entry * SubGhz: name generation modification RAW-YYYYMMDD-HHMMSS * SubGhz: replace m-string with FuriString Co-authored-by: あく --- .../main/subghz/scenes/subghz_scene_save_name.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index b9bb3636..dfcb6586 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -13,6 +13,20 @@ void subghz_scene_save_name_text_input_callback(void* context) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneSaveName); } +void subghz_scene_save_name_get_timefilename(FuriString* name) { + FuriHalRtcDateTime datetime = {0}; + furi_hal_rtc_get_datetime(&datetime); + furi_string_printf( + name, + "RAW-%.4d%.2d%.2d-%.2d%.2d%.2d", + datetime.year, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second); +} + void subghz_scene_save_name_on_enter(void* context) { SubGhz* subghz = context; @@ -41,9 +55,8 @@ void subghz_scene_save_name_on_enter(void* context) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubGhzCustomEventManagerSetRAW) { dev_name_empty = true; - subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME); + subghz_scene_save_name_get_timefilename(file_name); } - path_extract_filename(subghz->file_path, file_name, true); } furi_string_set(subghz->file_path, dir_name); } From 11681d8ee8b62f74401164d002c81951b14db82a Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 6 Oct 2022 18:48:29 +0400 Subject: [PATCH 07/49] [FL-2866, FL-2865] SubGhz: add frequency analyzer history (#1810) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: frequency analyzer history * SubGhz: add vibro * SubGhz: turn on the display when receiving a signal * SubGhz: add signal reception indicator * SubGhz: fix indicator * SubGhz: fix FA history Co-authored-by: あく --- .../subghz_frequency_analyzer_worker.c | 24 ++++++- .../subghz_frequency_analyzer_worker.h | 7 ++- .../scenes/subghz_scene_frequency_analyzer.c | 2 + .../subghz/views/subghz_frequency_analyzer.c | 63 +++++++++++++++++-- 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 10c5a9ea..35abbddc 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -71,6 +71,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { .frequency_coarse = 0, .rssi_coarse = 0, .frequency_fine = 0, .rssi_fine = 0}; float rssi = 0; uint32_t frequency = 0; + float rssi_temp = 0; + uint32_t frequency_temp = 0; CC1101Status status; //Start CC1101 @@ -194,6 +196,9 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); instance->sample_hold_counter = 20; + rssi_temp = frequency_rssi.rssi_fine; + frequency_temp = frequency_rssi.frequency_fine; + if(instance->filVal) { frequency_rssi.frequency_fine = subghz_frequency_analyzer_worker_expRunningAverageAdaptive( @@ -202,7 +207,10 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { // Deliver callback if(instance->pair_callback) { instance->pair_callback( - instance->context, frequency_rssi.frequency_fine, frequency_rssi.rssi_fine); + instance->context, + frequency_rssi.frequency_fine, + frequency_rssi.rssi_fine, + true); } } else if( // Deliver results coarse (frequency_rssi.rssi_coarse > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) && @@ -214,6 +222,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { (double)frequency_rssi.rssi_coarse); instance->sample_hold_counter = 20; + rssi_temp = frequency_rssi.rssi_coarse; + frequency_temp = frequency_rssi.frequency_coarse; if(instance->filVal) { frequency_rssi.frequency_coarse = subghz_frequency_analyzer_worker_expRunningAverageAdaptive( @@ -224,14 +234,22 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { instance->pair_callback( instance->context, frequency_rssi.frequency_coarse, - frequency_rssi.rssi_coarse); + frequency_rssi.rssi_coarse, + true); } } else { if(instance->sample_hold_counter > 0) { instance->sample_hold_counter--; + if(instance->sample_hold_counter == 18) { + if(instance->pair_callback) { + instance->pair_callback( + instance->context, frequency_temp, rssi_temp, false); + } + } } else { instance->filVal = 0; - if(instance->pair_callback) instance->pair_callback(instance->context, 0, 0); + if(instance->pair_callback) + instance->pair_callback(instance->context, 0, 0, false); } } } diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h index 50687c76..8bd1addc 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h @@ -5,8 +5,11 @@ typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker; -typedef void ( - *SubGhzFrequencyAnalyzerWorkerPairCallback)(void* context, uint32_t frequency, float rssi); +typedef void (*SubGhzFrequencyAnalyzerWorkerPairCallback)( + void* context, + uint32_t frequency, + float rssi, + bool signal); typedef struct { uint32_t frequency_coarse; diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index b42acd4d..9595c61b 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -21,6 +21,8 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneAnalyzerLock) { notification_message(subghz->notifications, &sequence_set_green_255); + notification_message(subghz->notifications, &sequence_single_vibro); + notification_message(subghz->notifications, &sequence_display_backlight_on); return true; } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) { notification_message(subghz->notifications, &sequence_reset_rgb); diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index d3f77315..608cf586 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -25,6 +25,8 @@ struct SubGhzFrequencyAnalyzer { typedef struct { uint32_t frequency; float rssi; + uint32_t history_frequency[3]; + bool signal; } SubGhzFrequencyAnalyzerModel; void subghz_frequency_analyzer_set_callback( @@ -38,8 +40,8 @@ void subghz_frequency_analyzer_set_callback( } void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { - uint8_t x = 48; - uint8_t y = 56; + uint8_t x = 20; + uint8_t y = 64; uint8_t column_number = 0; if(rssi) { rssi = (rssi + 90) / 3; @@ -53,6 +55,31 @@ void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { } } +static void subghz_frequency_analyzer_history_frequency_draw( + Canvas* canvas, + SubGhzFrequencyAnalyzerModel* model) { + char buffer[64]; + uint8_t x = 66; + uint8_t y = 43; + + canvas_set_font(canvas, FontKeyboard); + for(uint8_t i = 0; i < 3; i++) { + if(model->history_frequency[i]) { + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld", + model->history_frequency[i] / 1000000 % 1000, + model->history_frequency[i] / 1000 % 1000); + canvas_draw_str(canvas, x, y + i * 10, buffer); + } else { + canvas_draw_str(canvas, x, y + i * 10, "---.---"); + } + canvas_draw_str(canvas, x + 44, y + i * 10, "MHz"); + } + canvas_set_font(canvas, FontSecondary); +} + void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel* model) { char buffer[64]; @@ -60,9 +87,11 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 20, 8, "Frequency Analyzer"); - canvas_draw_str(canvas, 28, 60, "RSSI"); + canvas_draw_str(canvas, 0, 64, "RSSI"); subghz_frequency_analyzer_draw_rssi(canvas, model->rssi); + subghz_frequency_analyzer_history_frequency_draw(canvas, model); + //Frequency canvas_set_font(canvas, FontBigNumbers); snprintf( @@ -71,8 +100,14 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel "%03ld.%03ld", model->frequency / 1000000 % 1000, model->frequency / 1000 % 1000); - canvas_draw_str(canvas, 8, 35, buffer); - canvas_draw_icon(canvas, 96, 24, &I_MHz_25x11); + if(model->signal) { + canvas_draw_box(canvas, 4, 12, 121, 22); + canvas_set_color(canvas, ColorWhite); + } else { + } + + canvas_draw_str(canvas, 8, 30, buffer); + canvas_draw_icon(canvas, 96, 19, &I_MHz_25x11); } bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { @@ -85,12 +120,24 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { return true; } -void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) { +void subghz_frequency_analyzer_pair_callback( + void* context, + uint32_t frequency, + float rssi, + bool signal) { SubGhzFrequencyAnalyzer* instance = context; if((rssi == 0.f) && (instance->locked)) { if(instance->callback) { instance->callback(SubGhzCustomEventSceneAnalyzerUnlock, instance->context); } + //update history + with_view_model( + instance->view, (SubGhzFrequencyAnalyzerModel * model) { + model->history_frequency[2] = model->history_frequency[1]; + model->history_frequency[1] = model->history_frequency[0]; + model->history_frequency[0] = model->frequency; + return false; + }); } else if((rssi != 0.f) && (!instance->locked)) { if(instance->callback) { instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context); @@ -102,6 +149,7 @@ void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, instance->view, (SubGhzFrequencyAnalyzerModel * model) { model->rssi = rssi; model->frequency = frequency; + model->signal = signal; return true; }); } @@ -124,6 +172,9 @@ void subghz_frequency_analyzer_enter(void* context) { instance->view, (SubGhzFrequencyAnalyzerModel * model) { model->rssi = 0; model->frequency = 0; + model->history_frequency[2] = 0; + model->history_frequency[1] = 0; + model->history_frequency[0] = 0; return true; }); } From d07c2dbe548a52cef6f76e513068da8657ef1bfc Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Thu, 6 Oct 2022 20:37:53 +0500 Subject: [PATCH 08/49] ".fap" extention in file browser and archive tab (#1812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add .fap extention, and Applications tab * Using new icon, renaming tab to Apps * Change tabs order * Add first ugly implementation of in-app icons in archive browser * Starting using FAPLoader callback * Getting all metafata from fap * add app filename fallback * using fap_loader_item_callback in archive_list_item_cb * FAP-Loader: removed minimal allocation * Removed strange code Co-authored-by: SG Co-authored-by: あく --- .../main/archive/helpers/archive_browser.c | 23 ++++++- .../main/archive/helpers/archive_browser.h | 3 + .../main/archive/helpers/archive_files.h | 44 +++++++++--- .../archive/scenes/archive_scene_browser.c | 1 + .../main/archive/views/archive_browser_view.c | 23 ++++++- .../main/archive/views/archive_browser_view.h | 1 + applications/main/fap_loader/fap_loader_app.c | 68 +++++++++++-------- applications/main/fap_loader/fap_loader_app.h | 27 ++++++++ 8 files changed, 148 insertions(+), 42 deletions(-) create mode 100644 applications/main/fap_loader/fap_loader_app.h diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 1f4ca0f7..f6603070 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -5,6 +5,7 @@ #include #include #include "gui/modules/file_browser_worker.h" +#include #include static void @@ -351,16 +352,32 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { ArchiveFile_t_clear(&item); } +static bool archive_get_fap_meta(FuriString* file_path, FuriString* fap_name, uint8_t** icon_ptr) { + Storage* storage = furi_record_open(RECORD_STORAGE); + bool success = false; + if(fap_loader_load_name_and_icon(file_path, storage, icon_ptr, fap_name)) { + success = true; + } + furi_record_close(RECORD_STORAGE); + return success; +} + void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const char* name) { furi_assert(browser); furi_assert(name); ArchiveFile_t item; - ArchiveFile_t_init(&item); - item.path = furi_string_alloc_set(name); - archive_set_file_type(&item, furi_string_get_cstr(browser->path), is_folder, false); + furi_string_set(item.path, name); + archive_set_file_type(&item, furi_string_get_cstr(browser->path), is_folder, false); + if(item.type == ArchiveFileTypeApplication) { + item.custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + if(!archive_get_fap_meta(item.path, item.custom_name, &item.custom_icon_data)) { + free(item.custom_icon_data); + item.custom_icon_data = NULL; + } + } with_view_model( browser->view, (ArchiveBrowserViewModel * model) { files_array_push_back(model->files, item); diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h index c9e3bfa3..519a34a2 100644 --- a/applications/main/archive/helpers/archive_browser.h +++ b/applications/main/archive/helpers/archive_browser.h @@ -16,6 +16,7 @@ static const char* tab_default_paths[] = { [ArchiveTabInfrared] = ANY_PATH("infrared"), [ArchiveTabBadUsb] = ANY_PATH("badusb"), [ArchiveTabU2f] = "/app:u2f", + [ArchiveTabApplications] = ANY_PATH("apps"), [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX, }; @@ -27,6 +28,7 @@ static const char* known_ext[] = { [ArchiveFileTypeInfrared] = ".ir", [ArchiveFileTypeBadUsb] = ".txt", [ArchiveFileTypeU2f] = "?", + [ArchiveFileTypeApplication] = ".fap", [ArchiveFileTypeUpdateManifest] = ".fuf", [ArchiveFileTypeFolder] = "?", [ArchiveFileTypeUnknown] = "*", @@ -41,6 +43,7 @@ static const ArchiveFileTypeEnum known_type[] = { [ArchiveTabInfrared] = ArchiveFileTypeInfrared, [ArchiveTabBadUsb] = ArchiveFileTypeBadUsb, [ArchiveTabU2f] = ArchiveFileTypeU2f, + [ArchiveTabApplications] = ArchiveFileTypeApplication, [ArchiveTabBrowser] = ArchiveFileTypeUnknown, }; diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index a50a1d53..2017a957 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -4,6 +4,8 @@ #include #include +#define FAP_MANIFEST_MAX_ICON_SIZE 32 + typedef enum { ArchiveFileTypeIButton, ArchiveFileTypeNFC, @@ -13,6 +15,7 @@ typedef enum { ArchiveFileTypeBadUsb, ArchiveFileTypeU2f, ArchiveFileTypeUpdateManifest, + ArchiveFileTypeApplication, ArchiveFileTypeFolder, ArchiveFileTypeUnknown, ArchiveFileTypeLoading, @@ -21,33 +24,56 @@ typedef enum { typedef struct { FuriString* path; ArchiveFileTypeEnum type; + uint8_t* custom_icon_data; + FuriString* custom_name; bool fav; bool is_app; } ArchiveFile_t; static void ArchiveFile_t_init(ArchiveFile_t* obj) { - obj->type = ArchiveFileTypeUnknown; - obj->is_app = false; - obj->fav = false; obj->path = furi_string_alloc(); + obj->type = ArchiveFileTypeUnknown; + obj->custom_icon_data = NULL; + obj->custom_name = furi_string_alloc(); + obj->fav = false; + obj->is_app = false; } static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { - obj->type = src->type; - obj->is_app = src->is_app; - obj->fav = src->fav; obj->path = furi_string_alloc_set(src->path); + obj->type = src->type; + if(src->custom_icon_data) { + obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE); + } else { + obj->custom_icon_data = NULL; + } + obj->custom_name = furi_string_alloc_set(src->custom_name); + obj->fav = src->fav; + obj->is_app = src->is_app; } static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { - obj->type = src->type; - obj->is_app = src->is_app; - obj->fav = src->fav; furi_string_set(obj->path, src->path); + obj->type = src->type; + if(src->custom_icon_data) { + obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE); + } else { + obj->custom_icon_data = NULL; + } + furi_string_set(obj->custom_name, src->custom_name); + obj->fav = src->fav; + obj->is_app = src->is_app; } static void ArchiveFile_t_clear(ArchiveFile_t* obj) { furi_string_free(obj->path); + if(obj->custom_icon_data) { + free(obj->custom_icon_data); + obj->custom_icon_data = NULL; + } + furi_string_free(obj->custom_name); } ARRAY_DEF( diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index b4fd0482..9dc67161 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -20,6 +20,7 @@ static const char* flipper_app_name[] = { [ArchiveFileTypeBadUsb] = "Bad USB", [ArchiveFileTypeU2f] = "U2F", [ArchiveFileTypeUpdateManifest] = "UpdaterApp", + [ArchiveFileTypeApplication] = "Applications", }; static void archive_loader_callback(const void* message, void* context) { diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 4a0f2f3c..f13094a1 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -14,6 +14,7 @@ static const char* ArchiveTabNames[] = { [ArchiveTabInfrared] = "Infrared", [ArchiveTabBadUsb] = "Bad USB", [ArchiveTabU2f] = "U2F", + [ArchiveTabApplications] = "Apps", [ArchiveTabBrowser] = "Browser", }; @@ -29,6 +30,7 @@ static const Icon* ArchiveItemIcons[] = { [ArchiveFileTypeFolder] = &I_dir_10px, [ArchiveFileTypeUnknown] = &I_unknown_10px, [ArchiveFileTypeLoading] = &I_loading_10px, + [ArchiveFileTypeApplication] = &I_unknown_10px, }; void archive_browser_set_callback( @@ -124,12 +126,23 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0; ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading; + uint8_t* custom_icon_data = NULL; if(archive_is_item_in_array(model, idx)) { ArchiveFile_t* file = files_array_get( model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); - path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); file_type = file->type; + if(file_type == ArchiveFileTypeApplication) { + if(file->custom_icon_data) { + custom_icon_data = file->custom_icon_data; + furi_string_set(str_buf, file->custom_name); + } else { + file_type = ArchiveFileTypeUnknown; + path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); + } + } else { + path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); + } } else { furi_string_set(str_buf, "---"); } @@ -143,7 +156,13 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorBlack); } - canvas_draw_icon(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]); + if(custom_icon_data) { + canvas_draw_bitmap( + canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, 11, 10, custom_icon_data); + } else { + canvas_draw_icon( + canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]); + } canvas_draw_str( canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buf)); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 447cb0e1..308af4e4 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -26,6 +26,7 @@ typedef enum { ArchiveTabIButton, ArchiveTabBadUsb, ArchiveTabU2f, + ArchiveTabApplications, ArchiveTabBrowser, ArchiveTabTotal, } ArchiveTabEnum; diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index 1486cc1a..fb0a300e 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -1,34 +1,31 @@ #include #include #include -#include #include +#include #include -#include "elf_cpp/elf_hashtable.h" #include +#include "elf_cpp/elf_hashtable.h" +#include "fap_loader_app.h" #define TAG "fap_loader_app" -typedef struct { +struct FapLoader { FlipperApplication* app; Storage* storage; DialogsApp* dialogs; Gui* gui; FuriString* fap_path; - ViewDispatcher* view_dispatcher; Loading* loading; -} FapLoader; +}; -static bool fap_loader_item_callback( +bool fap_loader_load_name_and_icon( FuriString* path, - void* context, + Storage* storage, uint8_t** icon_ptr, FuriString* item_name) { - FapLoader* loader = context; - furi_assert(loader); - - FlipperApplication* app = flipper_application_alloc(loader->storage, &hashtable_api_interface); + FlipperApplication* app = flipper_application_alloc(storage, &hashtable_api_interface); FlipperApplicationPreloadStatus preload_res = flipper_application_preload_manifest(app, furi_string_get_cstr(path)); @@ -51,6 +48,16 @@ static bool fap_loader_item_callback( return load_success; } +static bool fap_loader_item_callback( + FuriString* path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { + FapLoader* fap_loader = context; + furi_assert(fap_loader); + return fap_loader_load_name_and_icon(path, fap_loader->storage, icon_ptr, item_name); +} + static bool fap_loader_run_selected_app(FapLoader* loader) { furi_assert(loader); @@ -134,7 +141,7 @@ static bool fap_loader_select_app(FapLoader* loader) { const DialogsFileBrowserOptions browser_options = { .extension = ".fap", .skip_assets = true, - .icon = &I_badusb_10px, + .icon = &I_unknown_10px, .hide_ext = true, .item_loader_callback = fap_loader_item_callback, .item_loader_context = loader, @@ -144,39 +151,44 @@ static bool fap_loader_select_app(FapLoader* loader) { loader->dialogs, loader->fap_path, loader->fap_path, &browser_options); } -int32_t fap_loader_app(void* p) { +static FapLoader* fap_loader_alloc(const char* path) { FapLoader* loader = malloc(sizeof(FapLoader)); + loader->fap_path = furi_string_alloc_set(path); loader->storage = furi_record_open(RECORD_STORAGE); loader->dialogs = furi_record_open(RECORD_DIALOGS); loader->gui = furi_record_open(RECORD_GUI); - loader->view_dispatcher = view_dispatcher_alloc(); loader->loading = loading_alloc(); - view_dispatcher_attach_to_gui( loader->view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen); view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading)); + return loader; +} +static void fap_loader_free(FapLoader* loader) { + view_dispatcher_remove_view(loader->view_dispatcher, 0); + loading_free(loader->loading); + view_dispatcher_free(loader->view_dispatcher); + furi_string_free(loader->fap_path); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_STORAGE); + free(loader); +} + +int32_t fap_loader_app(void* p) { + FapLoader* loader; if(p) { - loader->fap_path = furi_string_alloc_set((const char*)p); + loader = fap_loader_alloc((const char*)p); fap_loader_run_selected_app(loader); } else { - loader->fap_path = furi_string_alloc_set(EXT_PATH("apps")); - + loader = fap_loader_alloc(EXT_PATH("apps")); while(fap_loader_select_app(loader)) { view_dispatcher_switch_to_view(loader->view_dispatcher, 0); fap_loader_run_selected_app(loader); }; } - view_dispatcher_remove_view(loader->view_dispatcher, 0); - loading_free(loader->loading); - view_dispatcher_free(loader->view_dispatcher); - - furi_string_free(loader->fap_path); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_DIALOGS); - furi_record_close(RECORD_STORAGE); - free(loader); + fap_loader_free(loader); return 0; -} \ No newline at end of file +} diff --git a/applications/main/fap_loader/fap_loader_app.h b/applications/main/fap_loader/fap_loader_app.h new file mode 100644 index 00000000..9ed725ef --- /dev/null +++ b/applications/main/fap_loader/fap_loader_app.h @@ -0,0 +1,27 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FapLoader FapLoader; + +/** + * @brief Load name and icon from FAP file. + * + * @param path Path to FAP file. + * @param storage Storage instance. + * @param icon_ptr Icon pointer. + * @param item_name Application name. + * @return true if icon and name were loaded successfully. + */ +bool fap_loader_load_name_and_icon( + FuriString* path, + Storage* storage, + uint8_t** icon_ptr, + FuriString* item_name); + +#ifdef __cplusplus +} +#endif \ No newline at end of file From e3a5df5959e401da7fcf3916f0d71ca5105df616 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 7 Oct 2022 02:13:02 +1000 Subject: [PATCH 09/49] CLI: log command argument (#1817) Co-authored-by: Aleksandr Kutuzov --- applications/services/cli/cli_commands.c | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index 21927f81..cee2ca98 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -143,11 +143,37 @@ void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* conte xStreamBufferSend(context, buffer, size, 0); } +void cli_command_log_level_set_from_string(FuriString* level) { + if(furi_string_cmpi_str(level, "default") == 0) { + furi_log_set_level(FuriLogLevelDefault); + } else if(furi_string_cmpi_str(level, "none") == 0) { + furi_log_set_level(FuriLogLevelNone); + } else if(furi_string_cmpi_str(level, "error") == 0) { + furi_log_set_level(FuriLogLevelError); + } else if(furi_string_cmpi_str(level, "warn") == 0) { + furi_log_set_level(FuriLogLevelWarn); + } else if(furi_string_cmpi_str(level, "info") == 0) { + furi_log_set_level(FuriLogLevelInfo); + } else if(furi_string_cmpi_str(level, "debug") == 0) { + furi_log_set_level(FuriLogLevelDebug); + } else if(furi_string_cmpi_str(level, "trace") == 0) { + furi_log_set_level(FuriLogLevelTrace); + } else { + printf("Unknown log level\r\n"); + } +} + void cli_command_log(Cli* cli, FuriString* args, void* context) { - UNUSED(args); UNUSED(context); StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; + FuriLogLevel previous_level = furi_log_get_level(); + bool restore_log_level = false; + + if(furi_string_size(args) > 0) { + cli_command_log_level_set_from_string(args); + restore_log_level = true; + } furi_hal_console_set_tx_callback(cli_command_log_tx_callback, ring); @@ -159,6 +185,11 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { furi_hal_console_set_tx_callback(NULL, NULL); + if(restore_log_level) { + // There will be strange behaviour if log level is set from settings while log command is running + furi_log_set_level(previous_level); + } + vStreamBufferDelete(ring); } From 69b9c54b2f17856d105520dc7028d73b0c546b14 Mon Sep 17 00:00:00 2001 From: Evgenii Tereshkov Date: Thu, 6 Oct 2022 23:18:23 +0700 Subject: [PATCH 10/49] Update ac.ir: add Daichi model DA25AVQS1-W (#1819) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- assets/resources/infrared/assets/ac.ir | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 7866febc..97c38459 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -74,3 +74,41 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 8972 4491 592 1651 592 1655 598 532 599 535 597 542 600 541 601 544 598 1656 597 526 595 1652 591 1658 595 539 593 545 597 545 597 546 596 537 594 529 592 535 596 1653 600 534 597 541 601 539 592 552 600 533 598 525 596 530 591 538 593 539 592 1665 598 1662 591 1673 601 533 598 526 595 533 598 532 600 534 597 540 591 548 594 550 592 542 600 523 598 528 593 536 595 537 594 543 599 542 600 543 599 517 594 7937 593 531 601 526 595 535 597 537 594 542 600 541 601 543 599 1654 599 523 598 528 593 536 596 538 594 542 600 541 590 552 600 532 599 524 597 528 593 536 595 537 595 541 601 539 593 551 591 542 600 522 599 527 594 536 595 537 594 543 599 540 591 552 600 532 600 523 598 527 594 535 596 537 595 542 600 540 591 552 600 532 600 523 598 528 593 536 595 538 593 543 599 541 601 543 599 535 596 527 594 532 600 531 601 534 597 540 592 549 593 552 600 534 597 525 596 529 592 1655 598 534 597 1656 597 1661 592 1671 592 1644 599 7934 596 529 592 535 597 535 597 538 593 544 598 543 599 545 597 538 593 1650 593 535 596 534 597 536 595 540 591 547 595 547 595 536 595 526 595 529 592 536 595 535 596 539 593 546 596 547 595 538 593 528 593 531 601 529 592 541 601 536 596 545 597 548 594 540 592 532 600 526 595 535 596 1656 597 541 601 540 592 553 599 534 597 526 595 532 599 531 600 533 598 539 593 548 594 552 600 535 596 1647 596 531 590 538 593 1656 597 538 594 545 597 545 597 518 593 +# +# Model: Daichi DA25AVQS1-W +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9131 4318 815 389 817 1523 784 391 815 1523 784 1494 813 422 784 391 816 421 785 1524 784 392 814 422 783 1525 782 424 782 422 784 422 784 422 784 396 809 423 783 422 782 423 783 423 783 1496 812 1525 782 424 783 423 783 422 783 423 783 394 811 1526 782 424 782 1524 782 423 783 423 782 1525 782 423 675 19938 810 425 781 424 674 502 811 423 675 531 675 531 675 531 676 530 675 531 675 531 675 502 704 530 675 530 676 530 676 502 704 530 676 530 676 530 675 530 675 530 676 530 675 530 676 530 676 529 677 529 677 529 677 530 677 529 677 1631 676 529 677 1630 678 1631 677 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9076 4455 677 1629 678 528 677 528 677 1630 677 529 677 530 676 530 676 531 675 531 675 531 675 531 675 531 674 531 675 532 674 531 674 532 674 531 675 532 674 531 674 531 674 532 674 1633 674 1633 674 532 674 532 674 532 674 532 674 532 674 1634 673 533 673 1634 673 533 674 532 674 1633 674 533 673 19965 674 531 674 532 675 531 675 531 675 531 675 531 675 531 675 531 675 532 674 531 675 531 676 531 674 531 675 531 675 531 674 531 675 531 675 532 674 532 674 531 675 532 674 532 674 531 675 531 675 532 674 532 674 532 674 532 674 1633 674 1633 674 532 674 532 674 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9076 4453 679 1628 703 503 703 503 702 1607 700 506 699 507 699 507 699 507 699 1609 698 1610 698 1609 699 507 699 508 698 508 698 508 698 508 698 508 698 507 699 508 698 508 698 508 697 1609 698 1610 698 508 698 508 698 508 698 508 698 509 697 1610 697 508 698 1610 698 508 698 508 698 1610 697 509 697 19941 699 507 699 507 699 507 699 508 698 508 698 508 698 508 698 508 697 508 698 508 698 507 699 508 698 508 698 508 698 508 698 508 698 508 698 508 697 509 697 509 697 508 698 508 698 508 698 508 698 509 697 508 697 509 697 509 696 509 697 1635 673 533 673 1611 696 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 148 110377 9082 4422 707 499 706 500 704 1603 703 1606 701 505 700 507 699 506 700 507 699 506 700 1607 700 1608 700 1609 699 506 699 507 699 506 699 507 699 507 699 506 700 507 699 507 699 507 699 1608 699 1607 699 507 699 507 699 507 699 507 699 507 699 1609 699 507 699 1608 699 507 699 507 699 1609 699 507 699 19940 700 506 700 506 699 507 699 507 699 506 700 506 700 507 699 507 699 507 700 507 699 506 699 507 699 507 699 507 699 507 699 507 699 507 699 507 699 507 698 507 700 507 699 507 699 507 699 507 699 507 699 508 698 508 698 507 699 507 699 508 698 1610 699 508 698 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9081 4423 707 499 706 500 704 1604 702 1606 701 505 701 506 700 506 700 506 700 1608 700 1607 700 1609 699 506 700 506 700 506 700 506 700 506 700 507 699 506 700 506 700 507 699 507 699 1608 700 1608 699 507 699 507 699 507 699 507 699 507 699 1608 699 507 698 1609 698 507 699 507 699 1609 699 507 699 19938 699 506 700 506 700 507 699 506 699 506 700 506 699 506 700 507 699 507 699 507 700 506 699 507 699 507 699 507 699 507 699 507 698 507 699 507 699 507 699 507 699 507 699 507 699 507 699 507 700 507 699 507 698 507 699 507 699 1609 699 507 698 1609 699 1609 699 +# +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9106 4398 731 499 706 500 705 502 702 504 701 505 701 505 701 1606 701 505 701 1607 701 505 701 506 700 1607 700 506 700 506 700 505 700 505 701 506 700 506 700 506 699 506 700 506 700 1607 700 506 700 506 700 506 700 505 701 506 700 506 700 1608 699 506 700 1608 699 506 700 506 700 1608 700 506 700 19941 701 1606 700 505 701 505 701 506 700 505 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 701 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 699 506 700 506 700 1608 700 1607 700 506 700 506 700 + From 5de2c32c815d3a5322232abb7a5e77bb9052bbcf Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 6 Oct 2022 21:58:17 +0500 Subject: [PATCH 11/49] [FL-2864] NFC update detect reader (#1820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: update detect reader view * nfc: make detect reader more interractive * nfc: update icons * nfc: fix detect reader gui * nfc: fix gui, fix worker events * nfc: fix notifications * nfc: add nfc_worker NULL assert Co-authored-by: あく --- .../main/nfc/scenes/nfc_scene_detect_reader.c | 45 ++++++++++- .../nfc/scenes/nfc_scene_mfkey_nonces_info.c | 6 +- applications/main/nfc/views/detect_reader.c | 73 ++++++++++++++---- applications/main/nfc/views/detect_reader.h | 13 +++- assets/icons/NFC/Modern_reader_18x34.png | Bin 0 -> 3670 bytes assets/icons/NFC/Move_flipper_26x39.png | Bin 0 -> 3698 bytes assets/icons/NFC/Release_arrow_18x15.png | Bin 0 -> 3631 bytes firmware/targets/f7/api_symbols.csv | 3 + lib/nfc/helpers/mfkey32.c | 2 +- lib/nfc/nfc_worker.c | 21 ++++- lib/nfc/nfc_worker.h | 2 + 11 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 assets/icons/NFC/Modern_reader_18x34.png create mode 100644 assets/icons/NFC/Move_flipper_26x39.png create mode 100644 assets/icons/NFC/Release_arrow_18x15.png diff --git a/applications/main/nfc/scenes/nfc_scene_detect_reader.c b/applications/main/nfc/scenes/nfc_scene_detect_reader.c index 5f4582d8..e8c2b5ee 100644 --- a/applications/main/nfc/scenes/nfc_scene_detect_reader.c +++ b/applications/main/nfc/scenes/nfc_scene_detect_reader.c @@ -1,6 +1,15 @@ #include "../nfc_i.h" #include +#define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U) + +static const NotificationSequence sequence_detect_reader = { + &message_green_255, + &message_blue_255, + &message_do_not_reset, + NULL, +}; + bool nfc_detect_reader_worker_callback(NfcWorkerEvent event, void* context) { UNUSED(event); furi_assert(context); @@ -20,21 +29,26 @@ void nfc_scene_detect_reader_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedNfcEmulate); detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc); + detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX); + + // Store number of collected nonces in scene state + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDetectReader, 0); + notification_message(nfc->notifications, &sequence_detect_reader); + nfc_worker_start( nfc->worker, NfcWorkerStateAnalyzeReader, &nfc->dev->dev_data, nfc_detect_reader_worker_callback, nfc); - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDetectReader); - - nfc_blink_read_start(nfc); } bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; + uint32_t nonces_collected = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDetectReader); if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { @@ -42,8 +56,29 @@ bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyNoncesInfo); consumed = true; } else if(event.event == NfcWorkerEventDetectReaderMfkeyCollected) { - detect_reader_inc_nonce_cnt(nfc->detect_reader); + nonces_collected += 2; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, nonces_collected); + detect_reader_set_nonces_collected(nfc->detect_reader, nonces_collected); + if(nonces_collected >= NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + detect_reader_set_state(nfc->detect_reader, DetectReaderStateDone); + nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_single_vibro); + notification_message(nfc->notifications, &sequence_set_green_255); + nfc_worker_stop(nfc->worker); + } consumed = true; + } else if(event.event == NfcWorkerEventDetectReaderDetected) { + if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + notification_message(nfc->notifications, &sequence_blink_start_cyan); + detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderDetected); + } + } else if(event.event == NfcWorkerEventDetectReaderLost) { + if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_detect_reader); + detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderLost); + } } } @@ -59,5 +94,7 @@ void nfc_scene_detect_reader_on_exit(void* context) { // Clear view detect_reader_reset(nfc->detect_reader); + // Stop notifications nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_reset_green); } diff --git a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c index 9fd4f5ae..6d9852f3 100644 --- a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c +++ b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c @@ -16,14 +16,14 @@ void nfc_scene_mfkey_nonces_info_on_enter(void* context) { uint16_t nonces_saved = mfkey32_get_auth_sectors(temp_str); widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, furi_string_get_cstr(temp_str)); - furi_string_printf(temp_str, "Nonces saved %d", nonces_saved); + furi_string_printf(temp_str, "Nonce pairs saved: %d", nonces_saved); widget_add_string_element( nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(temp_str)); widget_add_string_element( nfc->widget, 0, 12, AlignLeft, AlignTop, FontSecondary, "Authenticated sectors:"); widget_add_button_element( - nfc->widget, GuiButtonTypeRight, "Next", nfc_scene_mfkey_nonces_info_callback, nfc); + nfc->widget, GuiButtonTypeCenter, "OK", nfc_scene_mfkey_nonces_info_callback, nfc); furi_string_free(temp_str); @@ -35,7 +35,7 @@ bool nfc_scene_mfkey_nonces_info_on_event(void* context, SceneManagerEvent event bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeRight) { + if(event.event == GuiButtonTypeCenter) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyComplete); consumed = true; } diff --git a/applications/main/nfc/views/detect_reader.c b/applications/main/nfc/views/detect_reader.c index 177c13f7..9a077043 100644 --- a/applications/main/nfc/views/detect_reader.c +++ b/applications/main/nfc/views/detect_reader.c @@ -10,29 +10,50 @@ struct DetectReader { typedef struct { uint16_t nonces; + uint16_t nonces_max; + DetectReaderState state; } DetectReaderViewModel; static void detect_reader_draw_callback(Canvas* canvas, void* model) { DetectReaderViewModel* m = model; char text[32] = {}; - snprintf(text, sizeof(text), "Tap the reader several times"); - canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Tap the reader several times"); + // Draw header and icon + canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34); + if(m->state == DetectReaderStateStart) { + snprintf(text, sizeof(text), "Touch the reader"); + canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39); + } else if(m->state == DetectReaderStateReaderDetected) { + snprintf(text, sizeof(text), "Move the Flipper away"); + canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15); + } else if(m->state == DetectReaderStateReaderLost) { + snprintf(text, sizeof(text), "Touch the reader again"); + canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39); + } - if(m->nonces == 0) { + canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, text); + + // Draw collected nonces + if(m->state == DetectReaderStateStart) { canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 52, 22, AlignLeft, AlignTop, "Emulating..."); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Emulating..."); canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 52, 35, AlignLeft, AlignTop, "MIFARE Classic"); - canvas_draw_icon(canvas, 0, 13, &I_Tap_reader_36x38); + canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, "MIFARE MFkey32"); } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 54, 22, AlignLeft, AlignTop, "Collecting..."); + if(m->state == DetectReaderStateDone) { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Completed!"); + } else { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Collecting..."); + } canvas_set_font(canvas, FontSecondary); - snprintf(text, sizeof(text), "Nonces: %d", m->nonces); - canvas_draw_str_aligned(canvas, 54, 35, AlignLeft, AlignTop, text); - elements_button_right(canvas, "Next"); - canvas_draw_icon(canvas, 6, 15, &I_ArrowC_1_36x36); + snprintf(text, sizeof(text), "Nonce pairs: %d/%d", m->nonces, m->nonces_max); + canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, text); + } + // Draw button + if(m->nonces > 0) { + elements_button_center(canvas, "Done"); } } @@ -49,7 +70,7 @@ static bool detect_reader_input_callback(InputEvent* event, void* context) { }); if(event->type == InputTypeShort) { - if(event->key == InputKeyRight) { + if(event->key == InputKeyOk) { if(nonces > 0) { detect_reader->callback(detect_reader->context); consumed = true; @@ -84,6 +105,8 @@ void detect_reader_reset(DetectReader* detect_reader) { with_view_model( detect_reader->view, (DetectReaderViewModel * model) { model->nonces = 0; + model->nonces_max = 0; + model->state = DetectReaderStateStart; return false; }); } @@ -105,11 +128,31 @@ void detect_reader_set_callback( detect_reader->context = context; } -void detect_reader_inc_nonce_cnt(DetectReader* detect_reader) { +void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max) { furi_assert(detect_reader); + with_view_model( detect_reader->view, (DetectReaderViewModel * model) { - model->nonces++; + model->nonces_max = nonces_max; return false; }); } + +void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected) { + furi_assert(detect_reader); + + with_view_model( + detect_reader->view, (DetectReaderViewModel * model) { + model->nonces = nonces_collected; + return false; + }); +} + +void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state) { + furi_assert(detect_reader); + with_view_model( + detect_reader->view, (DetectReaderViewModel * model) { + model->state = state; + return true; + }); +} diff --git a/applications/main/nfc/views/detect_reader.h b/applications/main/nfc/views/detect_reader.h index 12cd03db..aabdd7c8 100644 --- a/applications/main/nfc/views/detect_reader.h +++ b/applications/main/nfc/views/detect_reader.h @@ -5,6 +5,13 @@ typedef struct DetectReader DetectReader; +typedef enum { + DetectReaderStateStart, + DetectReaderStateReaderDetected, + DetectReaderStateReaderLost, + DetectReaderStateDone, +} DetectReaderState; + typedef void (*DetectReaderDoneCallback)(void* context); DetectReader* detect_reader_alloc(); @@ -20,4 +27,8 @@ void detect_reader_set_callback( DetectReaderDoneCallback callback, void* context); -void detect_reader_inc_nonce_cnt(DetectReader* detect_reader); +void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max); + +void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected); + +void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state); diff --git a/assets/icons/NFC/Modern_reader_18x34.png b/assets/icons/NFC/Modern_reader_18x34.png new file mode 100644 index 0000000000000000000000000000000000000000..b19c0f30c9f3928d3129acc9da92d5a9e962d084 GIT binary patch literal 3670 zcmaJ@c{r478-GRiEm@Lu#t;&-TAE=jGh>S(jEuAxj4^2zV`?lVl&v}>Wo<-dUn)uo zWeX)lN%pcNI{1zyPGY`s&gp#LA79^lz3=-x&wbs$-~GFn_qyJMgHE9q!yUB8;Xo`l)1P*d0stWcJU1%QZCV+#GO~nqh>yJH zz;sm-2f1P|MJgt1>uE^HABfk;?N@SX*k)}lqSlrZFPxYdd0ELtU;3itd$9?PTZ!jy z$6tK8_A&f+;JezDPaPW%`^=|G7kQOkV)f$Esdh*gqe$r@?CxzJ&bKzVe4Kz-MoDV1 z0D19BKaJpZO(9@4!pv+RxL)ijAQbXON*t&sWYxoV#qs54uo*{$A}O1A7Dgbe50Ok@OvlkEv2fW)fHA8?4 z8GxeAf`{4f`^x2~^aPd4s4%P6LRm+7i5mood3Zo}>vr0!>{B!*Zy{$|LK;IeR1r~z zavv670YFZ&k|5i~^^i{4^3G1<#46e21~bn@`CuQP@r}u@5|$+ZeB?xQZ|FlScSf3u zM$$KK?U@q^I3|^IYUPrDg`DL>AZL2OW0AF48|&OF)&2dG6BF+bG-JKUFFnp~P#cfe zd#s=QBf{+a%JPS&V_H#&qfxdZs~;L)Eji}x>bfd%!Dr}GlI{0LQvC1gZ@|s=KGh^W z#c>yfphSG;@-q zi($!qBa3G@=+;I_h*-6WZzpRE#0&XcBxxp!t7OEiYBbo1C|uG4y@*$I0Xrlc*}+{e z5<%{E>I)e57F663nr15gw%-SrN|&_kymzQnxF%uQ zx9dJvL?Oz$Ucy*}iv^K)TiKBuNlx$W3PHQH47UwPm`Dg;aB0*5rxZFo(0;P*kLDdd z2zVUHPG9q#Leh4qe0V&r*+fer0f*43zOu#s{vBeELXS-k!&P%yzbMPlZl`9-ivhpD z3Nh3*ebBzPmlcJP#gq8d4OxNMU zT;evPq{G;<+$z_*E^&q14NqmFI?gNGJLHw!y8dQofJ(p$?e1sJlWoJ-cRQuM_ULJ! zw*8#;S$K&nEfcGBzBQhztD3b#YzI}9yW?)UW4`K}ORB9zmvhMMG|jQOWccj2fw(fxlxNu z3*(BZg-oKwoe0nM1X0f>$0ldo9haQ@$H!}1KvKS{l_B~Xfifkrr=pCSweNTIpE<2p zlfJHAa|u&il#9Y44-290%eK-a(MoA8(Lw3X9cIss zf|zFN(AL4*TbL7m};H&2IPF{Awe2nbvY-Tx*=(LT|aPEvl`d?Le3z z%w@U~s`K~en>w00wsySgxYhA4!zc>_??X&wO=b0EjXv@|9CBE{s<7%Y#lB+VaK7hU zRV^dtFv>HJQrA-;HY|p!zvYLWz1=UU|P9@pzs7?2NuX<5c^hovII|O` zW;Mlf{?(j)bKHE~%wz;H;(7d)N&Ta?NA1o{%D3JMF*rFDrSyLgmYQ7PfQuBua)hsy9->&~D@I`1iOYdb^z# z?DPm>SAR>cH44>wj?B}atiGUAbfwl&#&I|covoaC8bn86&~@L>rx?WL5MijC)tOOK$tuZz71th`dX)zd(-3Y-6#cv!bjPppDU@$i4vk?<0gT9Uo5 zWA;_$%fTxqH|B5hXB8S1K3=WLi*@iYP$zw=D?Nd#FbfJDlpI&ux-a&SXsOxbi&c8` zUgwfokF@fLI_)q*VAQdOm(dLmg#y1wxl2yQoc%J?H+$5X1oa$!Nd6YfQ!`gexLB?@ zsFJ31?!E3%$fQ~v^X0RQp=%F{N}8+vy8L_mr$3DtWP8b`7N>nmlV!;C4?K_=J@jC9 z`K$FHG_6B-u;zRfuKM;fv&XfRf)||~rWV9I#3kZ4qVZhM@I!LnDx-T&Exh)t;cvZz zUbQRh<}aQOx(m4zdi{GTYxZlED;DJm#nY>)YxJXKPV}JJR^cAubumrZs=n&Cz3M#} zqHEH-eP3*4TYq`F!JFqA$QaAG|9YckOp}EVotR#c7+u*dgC012IlT0v*qdKYt5emX zC$O0dnKoH&nQLA?UQe7~nRmaN843GtJNS#-4MQ`}&;yIa7qo%t=r<|Ug|5rI>%6lO zkUxgJ2X9q{Px*F^o{(eCKauBr?6Kxwnli05?L4yZn6pqZIJw>9u}9`z^l|zOXU1$J z<&AS|&5fGO^6Ddj)pKEW55xUerq!}dI)|6)LVs80zw6CLVTS7#!z(a2{al^7vRdcb<4cyaR{gl)xLymdjiLARL+4J^b8{BEhiq3wW6pPNBrhk);kG7a zB(=xN#D2-%Z;nEZS+LiqzZc-T{JONWRW@#Iw3n+WLnBsuzw~u>r+4S3Eu^J9qo2uJ zpQ-<%dUvp;v1Rwu7a>Uav86+6vklxKuKN7#Q90*{GoW+2{D431FT1@iSW8h&N#TnK zr!Rh=H@X%r_^(vuSd%zzOn(lS%%%WVeoP+<$evE7Qd}uyztEr;6f*!2)};|i91_71 z?aQP?$eTWp5IReM1^_dQ5Ej`tkir4^P^dHp20UN$3=E?AVZa_n1Q>yZqXf|G!q^nI zFejpKSfDS;4{Tu$G7CWq2_OC4Htbb@3!GBjuP%~%ok9RP~ zmGU3G|C2bF7|NnRT`9rLQ*2*B@BB44L$S~}HigV#vWZOQ$sdJ07{KH(g9Df>5CRE- zgLDaGUm9c6viDC2fq=GW1ars?Uy3~*0~U}#Xf!`G9uC9W*z89l_alwqaBKX2BnoZ? zvw|5T_oLv3CfFZXJk$3SoxWBq=v1@TiXR3HYr+1vl>^$(L^fHt@P46oqu&-haqf|+LvhFcAp;MtHb?>>aojMU&+$&Jw2#YyGzNAg?=0N~xO|1%9#hzl z?cEASvP%gSwpPE+s1{*#d-3TN&&Ml8>K`_AH+6iBd^^X2G{h(8k literal 0 HcmV?d00001 diff --git a/assets/icons/NFC/Move_flipper_26x39.png b/assets/icons/NFC/Move_flipper_26x39.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4af9ff05989e5ff04d3888971b7f7801c59ed4 GIT binary patch literal 3698 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 literal 0 HcmV?d00001 diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a140ff0b..4e1704d0 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2693,6 +2693,8 @@ Variable,+,I_Lock_7x8,const Icon, Variable,+,I_Lock_8x8,const Icon, Variable,+,I_MHz_25x11,const Icon, Variable,+,I_Medium_chip_22x21,const Icon, +Variable,+,I_Modern_reader_18x34,const Icon, +Variable,+,I_Move_flipper_26x39,const Icon, Variable,+,I_Mute_25x27,const Icon, Variable,+,I_Mute_hvr_25x27,const Icon, Variable,+,I_NFC_manual_60x50,const Icon, @@ -2720,6 +2722,7 @@ Variable,+,I_RFIDDolphinReceive_97x61,const Icon, Variable,+,I_RFIDDolphinSend_97x61,const Icon, Variable,+,I_RFIDDolphinSuccess_108x57,const Icon, Variable,+,I_Reader_detect_43x40,const Icon, +Variable,+,I_Release_arrow_18x15,const Icon, Variable,+,I_Restoring_38x32,const Icon, Variable,+,I_Right_mouse_icon_9x9,const Icon, Variable,+,I_SDQuestion_35x43,const Icon, diff --git a/lib/nfc/helpers/mfkey32.c b/lib/nfc/helpers/mfkey32.c index 8eb417eb..fa5713f2 100644 --- a/lib/nfc/helpers/mfkey32.c +++ b/lib/nfc/helpers/mfkey32.c @@ -92,7 +92,7 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { FuriString* str = furi_string_alloc_printf( - "Sector %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", + "Sec %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", params->sector, params->key == MfClassicKeyA ? 'A' : 'B', params->cuid, diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 2feae443..996e68f0 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -647,7 +647,8 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* furi_assert(context); NfcWorker* nfc_worker = context; - if(event == ReaderAnalyzerEventMfkeyCollected) { + if((nfc_worker->state == NfcWorkerStateAnalyzeReader) && + (event == ReaderAnalyzerEventMfkeyCollected)) { if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context); } @@ -655,6 +656,9 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* } void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { + furi_assert(nfc_worker); + furi_assert(nfc_worker->callback); + FuriHalNfcTxRxContext tx_rx = {}; ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer; @@ -673,17 +677,32 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { rfal_platform_spi_acquire(); FURI_LOG_D(TAG, "Start reader analyzer"); + + uint8_t reader_no_data_received_cnt = 0; + bool reader_no_data_notified = true; + while(nfc_worker->state == NfcWorkerStateAnalyzeReader) { furi_hal_nfc_stop_cmd(); furi_delay_ms(5); furi_hal_nfc_listen_start(nfc_data); if(furi_hal_nfc_listen_rx(&tx_rx, 300)) { + if(reader_no_data_notified) { + nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context); + } + reader_no_data_received_cnt = 0; + reader_no_data_notified = false; NfcProtocol protocol = reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8); if(protocol == NfcDeviceProtocolMifareClassic) { mf_classic_emulator(&emulator, &tx_rx); } } else { + reader_no_data_received_cnt++; + if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) { + nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context); + reader_no_data_received_cnt = 0; + reader_no_data_notified = true; + } FURI_LOG_D(TAG, "No data from reader"); continue; } diff --git a/lib/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h index b7bf4da9..84615f5d 100644 --- a/lib/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -56,6 +56,8 @@ typedef enum { NfcWorkerEventFoundKeyB, // Detect Reader events + NfcWorkerEventDetectReaderDetected, + NfcWorkerEventDetectReaderLost, NfcWorkerEventDetectReaderMfkeyCollected, // Mifare Ultralight events From 6dde5586af130a8ca85416c502bee1a69da5220e Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:07:56 +0300 Subject: [PATCH 12/49] [FL-2803] Mifare Classic read improvements Part 1 (#1822) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Reuse found keys when reading a card * Fix keys not being read if no newline at the end of the file * Actually read all keys from the dictionary * Support for furi_string * Check only for re-used key after the current sector * Declare the key attack function as static * nfc: change logs, check worker state Co-authored-by: gornekich Co-authored-by: あく --- lib/nfc/helpers/mf_classic_dict.c | 13 ++++++-- lib/nfc/nfc_worker.c | 53 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c index 57841afc..356f6f7c 100644 --- a/lib/nfc/helpers/mf_classic_dict.c +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -69,9 +69,18 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { FuriString* next_line; next_line = furi_string_alloc(); while(true) { - if(!stream_read_line(dict->stream, next_line)) break; + if(!stream_read_line(dict->stream, next_line)) { + FURI_LOG_T(TAG, "No keys left in dict"); + break; + } + furi_string_trim(next_line); + FURI_LOG_T( + TAG, + "Read line: %s, len: %d", + furi_string_get_cstr(next_line), + furi_string_size(next_line)); if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN - 1) continue; dict->total_keys++; } furi_string_free(next_line); diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 996e68f0..c61ad444 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -453,6 +453,54 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) { } } +static void nfc_worker_mf_classic_key_attack( + NfcWorker* nfc_worker, + uint64_t key, + FuriHalNfcTxRxContext* tx_rx, + uint16_t start_sector) { + furi_assert(nfc_worker); + + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; + uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); + + furi_assert(start_sector < total_sectors); + + // Check every sector's A and B keys with the given key + for(size_t i = start_sector; i < total_sectors; i++) { + uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); + if(mf_classic_is_sector_read(data, i)) continue; + if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { + FURI_LOG_D( + TAG, + "Trying A key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { + mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + } + } + if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { + FURI_LOG_D( + TAG, + "Trying B key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { + mf_classic_set_key_found(data, i, MfClassicKeyB, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + } + } + if(mf_classic_is_sector_read(data, i)) continue; + mf_classic_read_sector(tx_rx, data, i); + if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; + } +} + void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { furi_assert(nfc_worker); furi_assert(nfc_worker->callback); @@ -484,6 +532,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); uint16_t key_index = 0; while(mf_classic_dict_get_next_key(dict, &key)) { + FURI_LOG_T(TAG, "Key %d", key_index); if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) { nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context); } @@ -505,15 +554,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) { mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); } furi_hal_nfc_sleep(); } if(!is_key_b_found) { is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) { + FURI_LOG_D(TAG, "Key found"); mf_classic_set_key_found(data, i, MfClassicKeyB, key); nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); } } if(is_key_a_found && is_key_b_found) break; From 01f7a3e5b52fa1842bb3117d7adddf059807c9ef Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 6 Oct 2022 22:12:45 +0500 Subject: [PATCH 13/49] [FL-2874] Remove bank card uid emulation (#1823) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: open bank card info from archive * nfc: remove emulate uid option from bank cards menu Co-authored-by: あく --- applications/main/nfc/nfc.c | 2 ++ applications/main/nfc/scenes/nfc_scene_saved_menu.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index 44a0f636..0b685f54 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -277,6 +277,8 @@ int32_t nfc_app(void* p) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/applications/main/nfc/scenes/nfc_scene_saved_menu.c b/applications/main/nfc/scenes/nfc_scene_saved_menu.c index c1043b3a..fe65b5b8 100644 --- a/applications/main/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_saved_menu.c @@ -20,8 +20,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { Submenu* submenu = nfc->submenu; if(nfc->dev->format == NfcDeviceSaveFormatUid || - nfc->dev->format == NfcDeviceSaveFormatMifareDesfire || - nfc->dev->format == NfcDeviceSaveFormatBankCard) { + nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) { submenu_add_item( submenu, "Emulate UID", From 19cb469e4b884c31cad69e711ede34c2acda60ae Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:19:35 +0300 Subject: [PATCH 14/49] [FL-2877] Don't turn off the backlight on MFC dict attack #1826 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c index b23f4b8f..81354690 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -91,6 +91,7 @@ void nfc_scene_mf_classic_dict_attack_on_enter(void* context) { nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack); nfc_blink_read_start(nfc); + notification_message(nfc->notifications, &sequence_display_backlight_enforce_on); } bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) { @@ -167,4 +168,5 @@ void nfc_scene_mf_classic_dict_attack_on_exit(void* context) { } dict_attack_reset(nfc->dict_attack); nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_display_backlight_enforce_auto); } From 72b3d7f41424c2489bb9466d2b131e0d4ff3e4e1 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:25:54 +0300 Subject: [PATCH 15/49] [FL-2620] Infrared error message (#1827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Show an error message if the remote could not be saved/renamed Co-authored-by: あく --- .../main/infrared/scenes/infrared_scene_learn_enter_name.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c b/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c index b7f4179e..b6a7eac0 100644 --- a/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c +++ b/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c @@ -50,8 +50,10 @@ bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent e if(success) { scene_manager_next_scene(scene_manager, InfraredSceneLearnDone); } else { - scene_manager_search_and_switch_to_previous_scene( - scene_manager, InfraredSceneRemoteList); + dialog_message_show_storage_error(infrared->dialogs, "Failed to save file"); + const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart}; + scene_manager_search_and_switch_to_previous_scene_one_of( + scene_manager, possible_scenes, COUNT_OF(possible_scenes)); } consumed = true; } From dde18cd343a67a2ed42b2fe20b42bdffd05ad693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Kimminich?= Date: Thu, 6 Oct 2022 19:40:18 +0200 Subject: [PATCH 16/49] Add exit label to keyboard connection screen (#1830) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add exit label to keyboard connection screen (resolves #1814) * BtHid: align baselines on connection screen Co-authored-by: あく --- applications/plugins/bt_hid_app/views/bt_hid_keyboard.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c index 3617dc0f..8b9ae593 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c @@ -209,6 +209,11 @@ static void bt_hid_keyboard_draw_callback(Canvas* canvas, void* context) { canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keyboard"); + + canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit"); + elements_multiline_text_aligned( canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection..."); return; // Dont render the keyboard if we are not yet connected From eaa3adf98ac4dcad5dec8d5f7eb716c242eb9ee4 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 6 Oct 2022 21:51:30 +0300 Subject: [PATCH 17/49] [FL-2868] Remove string_push_uint64 (#1832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove string_pust_uint64 * Oops, furi strings now * Remove dead code * Remove unneeded import Co-authored-by: あく --- lib/nfc/parsers/plantain_4k_parser.c | 14 +---------- lib/nfc/parsers/plantain_parser.c | 36 +--------------------------- lib/nfc/parsers/plantain_parser.h | 2 -- lib/nfc/parsers/two_cities.c | 13 +--------- 4 files changed, 3 insertions(+), 62 deletions(-) diff --git a/lib/nfc/parsers/plantain_4k_parser.c b/lib/nfc/parsers/plantain_4k_parser.c index c970d74e..eddebac2 100644 --- a/lib/nfc/parsers/plantain_4k_parser.c +++ b/lib/nfc/parsers/plantain_4k_parser.c @@ -1,5 +1,4 @@ #include "nfc_supported_card.h" -#include "plantain_parser.h" // For luhn and string_push_uint64 #include #include @@ -121,26 +120,15 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) { FuriString* card_number_str; card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string FuriString* card_number_suffix; card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // FuriString* luhn_checksum_str; - // luhn_checksum_str = furi_string_alloc(); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - furi_string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings furi_string_free(card_number_suffix); - // furi_string_free(luhn_checksum_str); furi_string_printf( dev_data->parsed_data, diff --git a/lib/nfc/parsers/plantain_parser.c b/lib/nfc/parsers/plantain_parser.c index 8ef8ee14..ac7a90b2 100644 --- a/lib/nfc/parsers/plantain_parser.c +++ b/lib/nfc/parsers/plantain_parser.c @@ -55,29 +55,6 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16; } -void string_push_uint64(uint64_t input, FuriString* output) { - const uint8_t base = 10; - - do { - char c = input % base; - input /= base; - - if(c < 10) - c += '0'; - else - c += 'A' - 10; - furi_string_push_back(output, c); - } while(input); - - // reverse string - for(uint8_t i = 0; i < furi_string_size(output) / 2; i++) { - char c = furi_string_get_char(output, i); - furi_string_set_char( - output, i, furi_string_get_char(output, furi_string_size(output) - i - 1)); - furi_string_set_char(output, furi_string_size(output) - i - 1, c); - } -} - uint8_t plantain_calculate_luhn(uint64_t number) { // No. UNUSED(number); @@ -116,26 +93,15 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) { FuriString* card_number_str; card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string FuriString* card_number_suffix; card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // FuriString* luhn_checksum_str; - // luhn_checksum_str = furi_string_alloc(); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - furi_string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings furi_string_free(card_number_suffix); - // furi_string_free(luhn_checksum_str); furi_string_printf( dev_data->parsed_data, diff --git a/lib/nfc/parsers/plantain_parser.h b/lib/nfc/parsers/plantain_parser.h index 65f396f1..1af8c506 100644 --- a/lib/nfc/parsers/plantain_parser.h +++ b/lib/nfc/parsers/plantain_parser.h @@ -8,6 +8,4 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); bool plantain_parser_parse(NfcDeviceData* dev_data); -void string_push_uint64(uint64_t input, FuriString* output); - uint8_t plantain_calculate_luhn(uint64_t number); diff --git a/lib/nfc/parsers/two_cities.c b/lib/nfc/parsers/two_cities.c index 3dc97586..f5e31d51 100644 --- a/lib/nfc/parsers/two_cities.c +++ b/lib/nfc/parsers/two_cities.c @@ -121,26 +121,15 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { FuriString* card_number_str; card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string FuriString* card_number_suffix; card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = two_cities_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // FuriString* luhn_checksum_str; - // luhn_checksum_str = furi_string_alloc(); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - furi_string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings furi_string_free(card_number_suffix); - // furi_string_free(luhn_checksum_str); // ===== // --PLANTAIN-- From 3367bc6f68b4ff0f87863d5a773307e12b24370d Mon Sep 17 00:00:00 2001 From: Matvey Gerasimov <48400794+spherebread@users.noreply.github.com> Date: Fri, 7 Oct 2022 10:23:21 +0400 Subject: [PATCH 18/49] Documentation: AppManifests.md typo fix (#1836) --- documentation/AppManifests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 14c0ae3a..4fec9d22 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -47,7 +47,7 @@ Only 2 parameters are mandatory: ***appid*** and ***apptype***, others are optio The following parameters are used only for [FAPs](./AppsOnSDCard.md): * **sources**: list of strings, file name masks, used for gathering sources within app folder. Default value of `["*.c*"]` includes C and C++ source files. Application cannot use `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**. -* **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meanig version "0.1". +* **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meaning version "0.1". * **fap_icon**: name of a .png file, 1-bit color depth, 10x10px, to be embedded within .fap file. * **fap_libs**: list of extra libraries to link application against. Provides access to extra functions that are not exported as a part of main firmware at expense of increased .fap file size and RAM consumption. * **fap_category**: string, may be empty. App subcategory, also works as path of FAP within apps folder in the file system. From d1843c009415bf5213777044734ec5e227e70ac6 Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Fri, 7 Oct 2022 11:56:19 +0500 Subject: [PATCH 19/49] Disable PVS-Studio license check (#1840) --- .github/workflows/pvs_studio.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 7bd71de4..98157555 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -65,6 +65,7 @@ jobs: pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} pvs-studio-analyzer analyze \ @.pvsoptions \ + --disableLicenseExpirationCheck \ -j$(grep -c processor /proc/cpuinfo) \ -f build/f7-firmware-DC/compile_commands.json \ -o PVS-Studio.log From 38a82a1907008fda1d8aa655e66c80faf26e61ef Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 7 Oct 2022 22:27:11 +1000 Subject: [PATCH 20/49] [FL-2839] Furi stream buffer (#1834) * Core: stream buffer * stream buffer: API and usage * stream buffer: documentation * stream buffer: more documentation * Furi: fix spelling Co-authored-by: Aleksandr Kutuzov --- applications/debug/uart_echo/uart_echo.c | 13 +- applications/debug/unit_tests/rpc/rpc_test.c | 18 +-- applications/main/gpio/usb_uart_bridge.c | 17 +-- applications/main/subghz/subghz_cli.c | 18 +-- applications/services/cli/cli_commands.c | 9 +- applications/services/cli/cli_vcp.c | 32 ++-- applications/services/rpc/rpc.c | 21 ++- firmware/targets/f7/api_symbols.csv | 12 +- furi/core/stream_buffer.c | 77 ++++++++++ furi/core/stream_buffer.h | 152 +++++++++++++++++++ furi/furi.h | 33 ++-- lib/infrared/worker/infrared_worker.c | 38 +++-- lib/lfrfid/lfrfid_raw_worker.c | 21 +-- lib/lfrfid/lfrfid_worker_modes.c | 18 +-- lib/nfc/helpers/reader_analyzer.c | 17 +-- lib/one_wire/ibutton/ibutton_worker_modes.c | 12 +- lib/subghz/subghz_file_encoder_worker.c | 18 +-- lib/subghz/subghz_tx_rx_worker.c | 37 +++-- lib/subghz/subghz_worker.c | 18 +-- lib/toolbox/buffer_stream.c | 23 ++- lib/toolbox/buffer_stream.h | 7 +- 21 files changed, 403 insertions(+), 208 deletions(-) create mode 100644 furi/core/stream_buffer.c create mode 100644 furi/core/stream_buffer.h diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 03b6a31a..122862dd 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -20,7 +19,7 @@ typedef struct { ViewDispatcher* view_dispatcher; View* view; FuriThread* worker_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; } UartEchoApp; typedef struct { @@ -92,13 +91,11 @@ static uint32_t uart_echo_exit(void* context) { static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { furi_assert(context); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; UartEchoApp* app = context; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(app->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(app->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -158,7 +155,7 @@ static int32_t uart_echo_worker(void* context) { size_t length = 0; do { uint8_t data[64]; - length = xStreamBufferReceive(app->rx_stream, data, 64, 0); + length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0); if(length > 0) { furi_hal_uart_tx(FuriHalUartIdUSART1, data, length); with_view_model( @@ -186,7 +183,7 @@ static int32_t uart_echo_worker(void* context) { static UartEchoApp* uart_echo_app_alloc() { UartEchoApp* app = malloc(sizeof(UartEchoApp)); - app->rx_stream = xStreamBufferCreate(2048, 1); + app->rx_stream = furi_stream_buffer_alloc(2048, 1); // Gui app->gui = furi_record_open(RECORD_GUI); @@ -260,7 +257,7 @@ static void uart_echo_app_free(UartEchoApp* app) { furi_record_close(RECORD_NOTIFICATION); app->gui = NULL; - vStreamBufferDelete(app->rx_stream); + furi_stream_buffer_free(app->rx_stream); // Free rest free(app); diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 6ee2aed6..5b52df2f 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -10,7 +10,6 @@ #include #include "../minunit.h" #include -#include #include #include #include @@ -34,7 +33,7 @@ static uint32_t command_id = 0; typedef struct { RpcSession* session; - StreamBufferHandle_t output_stream; + FuriStreamBuffer* output_stream; SemaphoreHandle_t close_session_semaphore; SemaphoreHandle_t terminate_semaphore; TickType_t timeout; @@ -90,7 +89,7 @@ static void test_rpc_setup(void) { } furi_check(rpc_session[0].session); - rpc_session[0].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[0].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback); rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary(); @@ -110,7 +109,7 @@ static void test_rpc_setup_second_session(void) { } furi_check(rpc_session[1].session); - rpc_session[1].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback); rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary(); @@ -126,7 +125,7 @@ static void test_rpc_teardown(void) { rpc_session_close(rpc_session[0].session); furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY)); furi_record_close(RECORD_RPC); - vStreamBufferDelete(rpc_session[0].output_stream); + furi_stream_buffer_free(rpc_session[0].output_stream); vSemaphoreDelete(rpc_session[0].close_session_semaphore); vSemaphoreDelete(rpc_session[0].terminate_semaphore); ++command_id; @@ -141,7 +140,7 @@ static void test_rpc_teardown_second_session(void) { xSemaphoreTake(rpc_session[1].terminate_semaphore, 0); rpc_session_close(rpc_session[1].session); furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY)); - vStreamBufferDelete(rpc_session[1].output_stream); + furi_stream_buffer_free(rpc_session[1].output_stream); vSemaphoreDelete(rpc_session[1].close_session_semaphore); vSemaphoreDelete(rpc_session[1].terminate_semaphore); ++command_id; @@ -268,8 +267,8 @@ static PB_CommandStatus test_rpc_storage_get_file_error(File* file) { static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size) { RpcSessionContext* callbacks_context = ctx; - size_t bytes_sent = - xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); + size_t bytes_sent = furi_stream_buffer_send( + callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); (void)bytes_sent; furi_check(bytes_sent == got_size); } @@ -534,7 +533,8 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_ TickType_t now = xTaskGetTickCount(); int32_t time_left = session_context->timeout - now; time_left = MAX(time_left, 0); - bytes_received = xStreamBufferReceive(session_context->output_stream, buf, count, time_left); + bytes_received = + furi_stream_buffer_receive(session_context->output_stream, buf, count, time_left); return (count == bytes_received); } diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 02f58ed1..6e0bce73 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -1,6 +1,5 @@ #include "usb_uart_bridge.h" #include "furi_hal.h" -#include #include #include "usb_cdc.h" #include "cli/cli_vcp.h" @@ -43,7 +42,7 @@ struct UsbUartBridge { FuriThread* thread; FuriThread* tx_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; FuriMutex* usb_mutex; @@ -74,12 +73,10 @@ static int32_t usb_uart_tx_thread(void* context); static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { UsbUartBridge* usb_uart = (UsbUartBridge*)context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(usb_uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -156,7 +153,7 @@ static int32_t usb_uart_worker(void* context) { memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); - usb_uart->rx_stream = xStreamBufferCreate(USB_UART_RX_BUF_SIZE, 1); + usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1); usb_uart->tx_sem = furi_semaphore_alloc(1, 1); usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); @@ -189,8 +186,8 @@ static int32_t usb_uart_worker(void* context) { furi_check((events & FuriFlagError) == 0); if(events & WorkerEvtStop) break; if(events & WorkerEvtRxDone) { - size_t len = - xStreamBufferReceive(usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); + size_t len = furi_stream_buffer_receive( + usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); if(len > 0) { if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) { usb_uart->st.rx_cnt += len; @@ -199,7 +196,7 @@ static int32_t usb_uart_worker(void* context) { furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len); furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); } else { - xStreamBufferReset(usb_uart->rx_stream); + furi_stream_buffer_reset(usb_uart->rx_stream); } } } @@ -270,7 +267,7 @@ static int32_t usb_uart_worker(void* context) { furi_thread_join(usb_uart->tx_thread); furi_thread_free(usb_uart->tx_thread); - vStreamBufferDelete(usb_uart->rx_stream); + furi_stream_buffer_free(usb_uart->rx_stream); furi_mutex_free(usb_uart->usb_mutex); furi_semaphore_free(usb_uart->tx_sem); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index c6e196fb..7fa0f454 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -194,23 +193,21 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { typedef struct { volatile bool overrun; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t packet_count; } SubGhzCliCommandRx; static void subghz_cli_command_rx_capture_callback(bool level, uint32_t duration, void* context) { SubGhzCliCommandRx* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static void subghz_cli_command_rx_callback( @@ -249,7 +246,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { // Allocate context and buffers SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); furi_check(instance->stream); SubGhzEnvironment* environment = subghz_environment_alloc(); @@ -279,8 +277,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { printf("."); @@ -304,7 +302,7 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { // Cleanup subghz_receiver_free(receiver); subghz_environment_free(environment); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index cee2ca98..239434b7 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -7,7 +7,6 @@ #include #include #include -#include // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'` #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" @@ -140,7 +139,7 @@ void cli_command_date(Cli* cli, FuriString* args, void* context) { #define CLI_COMMAND_LOG_BUFFER_SIZE 64 void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* context) { - xStreamBufferSend(context, buffer, size, 0); + furi_stream_buffer_send(context, buffer, size, 0); } void cli_command_log_level_set_from_string(FuriString* level) { @@ -165,7 +164,7 @@ void cli_command_log_level_set_from_string(FuriString* level) { void cli_command_log(Cli* cli, FuriString* args, void* context) { UNUSED(context); - StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); + FuriStreamBuffer* ring = furi_stream_buffer_alloc(CLI_COMMAND_LOG_RING_SIZE, 1); uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; FuriLogLevel previous_level = furi_log_get_level(); bool restore_log_level = false; @@ -179,7 +178,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { printf("Press CTRL+C to stop...\r\n"); while(!cli_cmd_interrupt_received(cli)) { - size_t ret = xStreamBufferReceive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); + size_t ret = furi_stream_buffer_receive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); cli_write(cli, buffer, ret); } @@ -190,7 +189,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { furi_log_set_level(previous_level); } - vStreamBufferDelete(ring); + furi_stream_buffer_free(ring); } void cli_command_vibro(Cli* cli, FuriString* args, void* context) { diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index f2893a48..1e27e185 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "cli_i.h" #define TAG "CliVcp" @@ -29,8 +28,8 @@ typedef enum { typedef struct { FuriThread* thread; - StreamBufferHandle_t tx_stream; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* tx_stream; + FuriStreamBuffer* rx_stream; volatile bool connected; volatile bool running; @@ -62,8 +61,8 @@ static const uint8_t ascii_eot = 0x04; static void cli_vcp_init() { if(vcp == NULL) { vcp = malloc(sizeof(CliVcp)); - vcp->tx_stream = xStreamBufferCreate(VCP_TX_BUF_SIZE, 1); - vcp->rx_stream = xStreamBufferCreate(VCP_RX_BUF_SIZE, 1); + vcp->tx_stream = furi_stream_buffer_alloc(VCP_TX_BUF_SIZE, 1); + vcp->rx_stream = furi_stream_buffer_alloc(VCP_RX_BUF_SIZE, 1); } furi_assert(vcp->thread == NULL); @@ -113,7 +112,7 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == false) { vcp->connected = true; - xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); + furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); } } @@ -124,8 +123,8 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == true) { vcp->connected = false; - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); } } @@ -134,7 +133,7 @@ static int32_t vcp_worker(void* context) { #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "StreamRx"); #endif - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { flags |= VcpEvtRx; missed_rx--; } @@ -142,14 +141,15 @@ static int32_t vcp_worker(void* context) { // New data received if(flags & VcpEvtRx) { - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { int32_t len = furi_hal_cdc_receive(VCP_IF_NUM, vcp->data_buffer, USB_CDC_PKT_LEN); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Rx %d", len); #endif if(len > 0) { furi_check( - xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == + furi_stream_buffer_send( + vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == (size_t)len); } } else { @@ -173,7 +173,7 @@ static int32_t vcp_worker(void* context) { // CDC write transfer done if(flags & VcpEvtTx) { size_t len = - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Tx %d", len); #endif @@ -202,8 +202,8 @@ static int32_t vcp_worker(void* context) { furi_hal_usb_unlock(); furi_hal_usb_set_config(vcp->usb_if_prev, NULL); } - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); break; } } @@ -229,7 +229,7 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) { size_t batch_size = size; if(batch_size > VCP_RX_BUF_SIZE) batch_size = VCP_RX_BUF_SIZE; - size_t len = xStreamBufferReceive(vcp->rx_stream, buffer, batch_size, timeout); + size_t len = furi_stream_buffer_receive(vcp->rx_stream, buffer, batch_size, timeout); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "rx %u ", batch_size); #endif @@ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { size_t batch_size = size; if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; - xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever); + furi_stream_buffer_send(vcp->tx_stream, buffer, batch_size, FuriWaitForever); furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "tx %u", batch_size); diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 4e8c29b4..06c05173 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #define TAG "RpcSrv" @@ -61,7 +60,7 @@ struct RpcSession { FuriThread* thread; RpcHandlerDict_t handlers; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; PB_Main* decoded_message; bool terminate; void** system_contexts; @@ -151,7 +150,7 @@ size_t furi_assert(encoded_bytes); furi_assert(size > 0); - size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout); + size_t bytes_sent = furi_stream_buffer_send(session->stream, encoded_bytes, size, timeout); furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData); @@ -160,7 +159,7 @@ size_t size_t rpc_session_get_available_size(RpcSession* session) { furi_assert(session); - return xStreamBufferSpacesAvailable(session->stream); + return furi_stream_buffer_spaces_available(session->stream); } bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { @@ -174,9 +173,9 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { size_t bytes_received = 0; while(1) { - bytes_received += - xStreamBufferReceive(session->stream, buf + bytes_received, count - bytes_received, 0); - if(xStreamBufferIsEmpty(session->stream)) { + bytes_received += furi_stream_buffer_receive( + session->stream, buf + bytes_received, count - bytes_received, 0); + if(furi_stream_buffer_is_empty(session->stream)) { if(session->buffer_is_empty_callback) { session->buffer_is_empty_callback(session->context); } @@ -190,7 +189,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { } else { flags = furi_thread_flags_wait(RPC_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); if(flags & RpcEvtDisconnect) { - if(xStreamBufferIsEmpty(session->stream)) { + if(furi_stream_buffer_is_empty(session->stream)) { session->terminate = true; istream->bytes_left = 0; bytes_received = 0; @@ -279,7 +278,7 @@ static int32_t rpc_session_worker(void* context) { } if(message_decode_failed) { - xStreamBufferReset(session->stream); + furi_stream_buffer_reset(session->stream); if(!session->terminate) { /* Protobuf can't determine start and end of message. * Handle this by adding varint at beginning @@ -329,7 +328,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex free(session->system_contexts); free(session->decoded_message); RpcHandlerDict_clear(session->handlers); - vStreamBufferDelete(session->stream); + furi_stream_buffer_free(session->stream); furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->terminated_callback) { @@ -348,7 +347,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { RpcSession* session = malloc(sizeof(RpcSession)); session->callbacks_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - session->stream = xStreamBufferCreate(RPC_BUFFER_SIZE, 1); + session->stream = furi_stream_buffer_alloc(RPC_BUFFER_SIZE, 1); session->rpc = rpc; session->terminate = false; session->decode_error = false; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 4e1704d0..03bad58e 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,2.0,, +Version,+,2.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1342,6 +1342,16 @@ Function,+,furi_semaphore_alloc,FuriSemaphore*,"uint32_t, uint32_t" Function,+,furi_semaphore_free,void,FuriSemaphore* Function,+,furi_semaphore_get_count,uint32_t,FuriSemaphore* Function,+,furi_semaphore_release,FuriStatus,FuriSemaphore* +Function,+,furi_stream_buffer_alloc,FuriStreamBuffer*,"size_t, size_t" +Function,+,furi_stream_buffer_bytes_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_buffer_free,void,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_empty,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_full,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_receive,size_t,"FuriStreamBuffer*, void*, size_t, uint32_t" +Function,+,furi_stream_buffer_reset,FuriStatus,FuriStreamBuffer* +Function,+,furi_stream_buffer_send,size_t,"FuriStreamBuffer*, const void*, size_t, uint32_t" +Function,+,furi_stream_buffer_spaces_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_set_trigger_level,_Bool,"FuriStreamBuffer*, size_t" Function,+,furi_string_alloc,FuriString*, Function,+,furi_string_alloc_move,FuriString*,FuriString* Function,+,furi_string_alloc_printf,FuriString*,"const char[], ..." diff --git a/furi/core/stream_buffer.c b/furi/core/stream_buffer.c new file mode 100644 index 00000000..b9d0629f --- /dev/null +++ b/furi/core/stream_buffer.c @@ -0,0 +1,77 @@ +#include "base.h" +#include "stream_buffer.h" +#include "common_defines.h" +#include +#include + +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level) { + return xStreamBufferCreate(size, trigger_level); +}; + +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer) { + vStreamBufferDelete(stream_buffer); +}; + +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level) { + return xStreamBufferSetTriggerLevel(stream_buffer, trigger_level) == pdTRUE; +}; + +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferSendFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferSend(stream_buffer, data, length, timeout); + } + + return ret; +}; + +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferReceiveFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferReceive(stream_buffer, data, length, timeout); + } + + return ret; +} + +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferBytesAvailable(stream_buffer); +}; + +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferSpacesAvailable(stream_buffer); +}; + +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer) { + return xStreamBufferIsFull(stream_buffer) == pdTRUE; +}; + +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer) { + return (xStreamBufferIsEmpty(stream_buffer) == pdTRUE); +}; + +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer) { + if(xStreamBufferReset(stream_buffer) == pdPASS) { + return FuriStatusOk; + } else { + return FuriStatusError; + } +} \ No newline at end of file diff --git a/furi/core/stream_buffer.h b/furi/core/stream_buffer.h new file mode 100644 index 00000000..d07f7e60 --- /dev/null +++ b/furi/core/stream_buffer.h @@ -0,0 +1,152 @@ +/** + * @file stream_buffer.h + * Furi stream buffer primitive. + * + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriStreamBuffer; + +/** + * @brief Allocate stream buffer instance. + * Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + * + * @param size The total number of bytes the stream buffer will be able to hold at any one time. + * @param trigger_level The number of bytes that must be in the stream buffer + * before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state. + * @return The stream buffer instance. + */ +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level); + +/** + * @brief Free stream buffer instance + * + * @param stream_buffer The stream buffer instance. + */ +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer); + +/** + * @brief Set trigger level for stream buffer. + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. + * + * @param stream_buffer The stream buffer instance + * @param trigger_level The new trigger level for the stream buffer. + * @return true if trigger level can be be updated (new trigger level was less than or equal to the stream buffer's length). + * @return false if trigger level can't be be updated (new trigger level was greater than the stream buffer's length). + */ +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level); + +/** + * @brief Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * Wakes up task waiting for data to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the data that is to be copied into the stream buffer. + * @param length The maximum number of bytes to copy from data into the stream buffer. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for space to become available if the stream buffer is full. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes actually written to the stream buffer. + */ +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Receives bytes from a stream buffer. + * Wakes up task waiting for space to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the buffer into which the received bytes will be + * copied. + * @param length The length of the buffer pointed to by the data parameter. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is empty. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes read from the stream buffer, if any. + */ +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + */ +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + */ +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is full. + * + * @param stream_buffer stream buffer instance. + * @return true if the stream buffer is full. + * @return false if the stream buffer is not full. + */ +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is empty. + * + * @param stream_buffer The stream buffer instance. + * @return true if the stream buffer is empty. + * @return false if the stream buffer is not empty. + */ +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer); + +/** + * @brief Resets a stream buffer to its initial, empty, state. Any data that was + * in the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream buffer. + * + * @param stream_buffer The stream buffer instance. + * @return FuriStatusOk if the stream buffer is reset. + * @return FuriStatusError if there was a task blocked waiting to send to or read + * from the stream buffer then the stream buffer is not reset. + */ +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/furi/furi.h b/furi/furi.h index 306c9b94..3ce83422 100644 --- a/furi/furi.h +++ b/furi/furi.h @@ -2,22 +2,23 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "core/check.h" +#include "core/common_defines.h" +#include "core/event_flag.h" +#include "core/kernel.h" +#include "core/log.h" +#include "core/memmgr.h" +#include "core/memmgr_heap.h" +#include "core/message_queue.h" +#include "core/mutex.h" +#include "core/pubsub.h" +#include "core/record.h" +#include "core/semaphore.h" +#include "core/thread.h" +#include "core/timer.h" +#include "core/valuemutex.h" +#include "core/string.h" +#include "core/stream_buffer.h" #include diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 2b4e3cdb..86b19114 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -9,7 +9,6 @@ #include #include -#include #define INFRARED_WORKER_RX_TIMEOUT INFRARED_RAW_RX_TIMING_DELAY_US @@ -50,7 +49,7 @@ struct InfraredWorkerSignal { struct InfraredWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; InfraredWorkerSignal signal; InfraredWorkerState state; @@ -100,15 +99,13 @@ static void infrared_worker_rx_timeout_callback(void* context) { static void infrared_worker_rx_callback(void* context, bool level, uint32_t duration) { InfraredWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; furi_assert(duration != 0); LevelDuration level_duration = level_duration_make(level, duration); - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); uint32_t events = (ret == sizeof(LevelDuration)) ? INFRARED_WORKER_RX_RECEIVED : INFRARED_WORKER_OVERRUN; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); uint32_t flags_set = furi_thread_flags_set(furi_thread_get_id(instance->thread), events); furi_check(flags_set & events); @@ -179,7 +176,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { if(instance->signal.timings_cnt == 0) notification_message(instance->notification, &sequence_display_backlight_on); while(sizeof(LevelDuration) == - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream, &level_duration, sizeof(LevelDuration), 0)) { if(!instance->rx.overrun) { bool level = level_duration_get_level(level_duration); @@ -232,7 +229,7 @@ InfraredWorker* infrared_worker_alloc() { size_t buffer_size = MAX(sizeof(InfraredWorkerTiming) * (MAX_TIMINGS_AMOUNT + 1), sizeof(LevelDuration) * MAX_TIMINGS_AMOUNT); - instance->stream = xStreamBufferCreate(buffer_size, sizeof(InfraredWorkerTiming)); + instance->stream = furi_stream_buffer_alloc(buffer_size, sizeof(InfraredWorkerTiming)); instance->infrared_decoder = infrared_alloc_decoder(); instance->infrared_encoder = infrared_alloc_encoder(); instance->blink_enable = false; @@ -249,7 +246,7 @@ void infrared_worker_free(InfraredWorker* instance) { furi_record_close(RECORD_NOTIFICATION); infrared_free_decoder(instance->infrared_decoder); infrared_free_encoder(instance->infrared_encoder); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); @@ -259,7 +256,7 @@ void infrared_worker_rx_start(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state == InfraredWorkerStateIdle); - xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); + furi_stream_set_trigger_level(instance->stream, sizeof(LevelDuration)); furi_thread_set_callback(instance->thread, infrared_worker_rx_thread); furi_thread_start(instance->thread); @@ -285,9 +282,9 @@ void infrared_worker_rx_stop(InfraredWorker* instance) { furi_thread_flags_set(furi_thread_get_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); - BaseType_t xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } @@ -325,7 +322,7 @@ void infrared_worker_tx_start(InfraredWorker* instance) { furi_assert(instance->tx.get_signal_callback); // size have to be greater than api hal infrared async tx buffer size - xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming)); + furi_stream_set_trigger_level(instance->stream, sizeof(InfraredWorkerTiming)); furi_thread_set_callback(instance->thread, infrared_worker_tx_thread); @@ -358,7 +355,7 @@ static FuriHalInfraredTxGetDataState FuriHalInfraredTxGetDataState state; if(sizeof(InfraredWorkerTiming) == - xStreamBufferReceiveFromISR(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { + furi_stream_buffer_receive(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { *level = timing.level; *duration = timing.duration; state = timing.state; @@ -420,7 +417,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { InfraredWorkerTiming timing; InfraredStatus status = InfraredStatusError; - while(!xStreamBufferIsFull(instance->stream) && !instance->tx.need_reinitialization && + while(!furi_stream_buffer_is_full(instance->stream) && !instance->tx.need_reinitialization && new_data_available) { if(instance->signal.decoded) { status = infrared_encode(instance->infrared_encoder, &timing.duration, &timing.level); @@ -454,7 +451,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { furi_assert(0); } uint32_t written_size = - xStreamBufferSend(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); + furi_stream_buffer_send(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); furi_assert(sizeof(InfraredWorkerTiming) == written_size); (void)written_size; } @@ -564,10 +561,9 @@ void infrared_worker_tx_stop(InfraredWorker* instance) { furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL); instance->signal.timings_cnt = 0; - BaseType_t xReturn = pdFAIL; - xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index b277bbd3..9bab77db 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "lfrfid_raw_worker.h" #include "lfrfid_raw_file.h" #include "tools/varint_pair.h" @@ -16,7 +15,7 @@ // emulate mode typedef struct { size_t overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } RfidEmulateCtx; typedef struct { @@ -126,20 +125,13 @@ void lfrfid_raw_worker_stop(LFRFIDRawWorker* worker) { static void lfrfid_raw_worker_capture(bool level, uint32_t duration, void* context) { LFRFIDRawWorkerReadData* ctx = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { @@ -236,7 +228,7 @@ static void rfid_emulate_dma_isr(bool half, void* context) { RfidEmulateCtx* ctx = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - size_t len = xStreamBufferSendFromISR(ctx->stream, &flag, sizeof(uint32_t), pdFALSE); + size_t len = furi_stream_buffer_send(ctx->stream, &flag, sizeof(uint32_t), 0); if(len != sizeof(uint32_t)) { ctx->overrun_count++; } @@ -251,7 +243,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { Storage* storage = furi_record_open(RECORD_STORAGE); data->ctx.overrun_count = 0; - data->ctx.stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + data->ctx.stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); @@ -287,7 +279,8 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { uint32_t flag = 0; while(true) { - size_t size = xStreamBufferReceive(data->ctx.stream, &flag, sizeof(uint32_t), 100); + size_t size = + furi_stream_buffer_receive(data->ctx.stream, &flag, sizeof(uint32_t), 100); if(size == sizeof(uint32_t)) { size_t start = 0; @@ -348,7 +341,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count); } - vStreamBufferDelete(data->ctx.stream); + furi_stream_buffer_free(data->ctx.stream); lfrfid_raw_file_free(file); furi_record_close(RECORD_STORAGE); free(data); diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 56447057..1fbae04c 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -2,7 +2,6 @@ #include #include "lfrfid_worker_i.h" #include "tools/t5577.h" -#include #include #include #include "tools/varint_pair.h" @@ -81,17 +80,12 @@ static void lfrfid_worker_read_capture(bool level, uint32_t duration, void* cont furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, level); #endif - BaseType_t xHigherPriorityTaskWoken = pdFALSE; bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } typedef enum { @@ -407,14 +401,14 @@ typedef enum { } LFRFIDWorkerEmulateDMAEvent; static void lfrfid_worker_emulate_dma_isr(bool half, void* context) { - StreamBufferHandle_t stream = context; + FuriStreamBuffer* stream = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - xStreamBufferSendFromISR(stream, &flag, sizeof(uint32_t), pdFALSE); + furi_stream_buffer_send(stream, &flag, sizeof(uint32_t), 0); } static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { LFRFIDWorkerEmulateBuffer* buffer = malloc(sizeof(LFRFIDWorkerEmulateBuffer)); - StreamBufferHandle_t stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + FuriStreamBuffer* stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDProtocol protocol = worker->protocol; PulseGlue* pulse_glue = pulse_glue_alloc(); @@ -449,7 +443,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { while(true) { uint32_t flag = 0; - size_t size = xStreamBufferReceive(stream, &flag, sizeof(uint32_t), 100); + size_t size = furi_stream_buffer_receive(stream, &flag, sizeof(uint32_t), 100); #ifdef LFRFID_WORKER_READ_DEBUG_GPIO furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true); @@ -497,7 +491,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { #endif free(buffer); - vStreamBufferDelete(stream); + furi_stream_buffer_free(stream); pulse_glue_free(pulse_glue); } diff --git a/lib/nfc/helpers/reader_analyzer.c b/lib/nfc/helpers/reader_analyzer.c index 680b8cef..0ba657a2 100644 --- a/lib/nfc/helpers/reader_analyzer.c +++ b/lib/nfc/helpers/reader_analyzer.c @@ -1,5 +1,4 @@ #include "reader_analyzer.h" -#include #include #include #include @@ -26,7 +25,7 @@ struct ReaderAnalyzer { FuriHalNfcDevData nfc_data; bool alive; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; FuriThread* thread; ReaderAnalyzerParseDataCallback callback; @@ -86,8 +85,8 @@ int32_t reader_analyzer_thread(void* context) { ReaderAnalyzer* reader_analyzer = context; uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {}; - while(reader_analyzer->alive || !xStreamBufferIsEmpty(reader_analyzer->stream)) { - size_t ret = xStreamBufferReceive( + while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) { + size_t ret = furi_stream_buffer_receive( reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50); if(ret) { reader_analyzer_parse(reader_analyzer, buffer, ret); @@ -103,7 +102,7 @@ ReaderAnalyzer* reader_analyzer_alloc() { instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; instance->alive = false; instance->stream = - xStreamBufferCreate(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); + furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); instance->thread = furi_thread_alloc(); furi_thread_set_name(instance->thread, "ReaderAnalyzerWorker"); @@ -129,7 +128,7 @@ static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) { void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) { furi_assert(instance); - xStreamBufferReset(instance->stream); + furi_stream_buffer_reset(instance->stream); if(mode & ReaderAnalyzerModeDebugLog) { instance->debug_log = nfc_debug_log_alloc(); } @@ -171,7 +170,7 @@ void reader_analyzer_free(ReaderAnalyzer* instance) { reader_analyzer_stop(instance); furi_thread_free(instance->thread); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } @@ -215,12 +214,12 @@ static void reader_analyzer_write( ReaderAnalyzerHeader header = { .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len}; size_t data_sent = 0; - data_sent = xStreamBufferSend( + data_sent = furi_stream_buffer_send( instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever); if(data_sent != sizeof(ReaderAnalyzerHeader)) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, sizeof(ReaderAnalyzerHeader)); } - data_sent = xStreamBufferSend(instance->stream, data, len, FuriWaitForever); + data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever); if(data_sent != len) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, len); } diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index d585e27f..691aea9e 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -2,7 +2,6 @@ #include #include "ibutton_worker_i.h" #include "ibutton_key_command.h" -#include void ibutton_worker_mode_idle_start(iButtonWorker* worker); void ibutton_worker_mode_idle_tick(iButtonWorker* worker); @@ -65,7 +64,7 @@ void ibutton_worker_mode_idle_stop(iButtonWorker* worker) { typedef struct { uint32_t last_dwt_value; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } iButtonReadContext; void ibutton_worker_comparator_callback(bool level, void* context) { @@ -75,7 +74,7 @@ void ibutton_worker_comparator_callback(bool level, void* context) { LevelDuration data = level_duration_make(level, current_dwt_value - read_context->last_dwt_value); - xStreamBufferSend(read_context->stream, &data, sizeof(LevelDuration), 0); + furi_stream_buffer_send(read_context->stream, &data, sizeof(LevelDuration), 0); read_context->last_dwt_value = current_dwt_value; } @@ -91,7 +90,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { iButtonReadContext read_context = { .last_dwt_value = DWT->CYCCNT, - .stream = xStreamBufferCreate(sizeof(LevelDuration) * 512, 1), + .stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 512, 1), }; furi_hal_rfid_comp_set_callback(ibutton_worker_comparator_callback, &read_context); @@ -100,7 +99,8 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { uint32_t tick_start = furi_get_tick(); while(true) { LevelDuration level; - size_t ret = xStreamBufferReceive(read_context.stream, &level, sizeof(LevelDuration), 100); + size_t ret = + furi_stream_buffer_receive(read_context.stream, &level, sizeof(LevelDuration), 100); if((furi_get_tick() - tick_start) > 100) { break; @@ -141,7 +141,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { furi_hal_rfid_comp_set_callback(NULL, NULL); furi_hal_rfid_pins_reset(); - vStreamBufferDelete(read_context.stream); + furi_stream_buffer_free(read_context.stream); return result; } diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 1b8e99f1..29834b41 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -1,5 +1,4 @@ #include "subghz_file_encoder_worker.h" -#include #include #include @@ -11,7 +10,7 @@ struct SubGhzFileEncoderWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; Storage* storage; FlipperFormat* flipper_format; @@ -48,7 +47,7 @@ void subghz_file_encoder_worker_add_level_duration( if(res) { instance->level = !instance->level; - xStreamBufferSend(instance->stream, &duration, sizeof(int32_t), 100); + furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100); } else { FURI_LOG_E(TAG, "Invalid level in the stream"); } @@ -83,10 +82,7 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { furi_assert(context); SubGhzFileEncoderWorker* instance = context; int32_t duration; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - int ret = xStreamBufferReceiveFromISR( - instance->stream, &duration, sizeof(int32_t), &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + int ret = furi_stream_buffer_receive(instance->stream, &duration, sizeof(int32_t), 0); if(ret == sizeof(int32_t)) { LevelDuration level_duration = {.level = LEVEL_DURATION_RESET}; if(duration < 0) { @@ -137,7 +133,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { } while(0); while(res && instance->worker_running) { - size_t stream_free_byte = xStreamBufferSpacesAvailable(instance->stream); + size_t stream_free_byte = furi_stream_buffer_spaces_available(instance->stream); if((stream_free_byte / sizeof(int32_t)) >= SUBGHZ_FILE_ENCODER_LOAD) { if(stream_read_line(stream, instance->str_data)) { furi_string_trim(instance->str_data); @@ -183,7 +179,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { furi_thread_set_stack_size(instance->thread, 2048); furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_file_encoder_worker_thread); - instance->stream = xStreamBufferCreate(sizeof(int32_t) * 2048, sizeof(int32_t)); + instance->stream = furi_stream_buffer_alloc(sizeof(int32_t) * 2048, sizeof(int32_t)); instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_format = flipper_format_file_alloc(instance->storage); @@ -199,7 +195,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); furi_string_free(instance->str_data); @@ -215,7 +211,7 @@ bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const c furi_assert(instance); furi_assert(!instance->worker_running); - xStreamBufferReset(instance->stream); + furi_stream_buffer_reset(instance->stream); furi_string_set(instance->file_path, file_path); instance->worker_running = true; furi_thread_start(instance->thread); diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index 78a18693..37c0bfc5 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -1,6 +1,5 @@ #include "subghz_tx_rx_worker.h" -#include #include #define TAG "SubGhzTxRxWorker" @@ -13,8 +12,8 @@ struct SubGhzTxRxWorker { FuriThread* thread; - StreamBufferHandle_t stream_tx; - StreamBufferHandle_t stream_rx; + FuriStreamBuffer* stream_tx; + FuriStreamBuffer* stream_rx; volatile bool worker_running; volatile bool worker_stoping; @@ -30,9 +29,9 @@ struct SubGhzTxRxWorker { bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); bool ret = false; - size_t stream_tx_free_byte = xStreamBufferSpacesAvailable(instance->stream_tx); + size_t stream_tx_free_byte = furi_stream_buffer_spaces_available(instance->stream_tx); if(size && (stream_tx_free_byte >= size)) { - if(xStreamBufferSend( + if(furi_stream_buffer_send( instance->stream_tx, data, size, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == size) { ret = true; @@ -43,12 +42,12 @@ bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { furi_assert(instance); - return xStreamBufferBytesAvailable(instance->stream_rx); + return furi_stream_buffer_bytes_available(instance->stream_rx); } size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); - return xStreamBufferReceive(instance->stream_rx, data, size, 0); + return furi_stream_buffer_receive(instance->stream_rx, data, size, 0); } void subghz_tx_rx_worker_set_callback_have_read( @@ -148,11 +147,11 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { while(instance->worker_running) { //transmit - size_tx = xStreamBufferBytesAvailable(instance->stream_tx); + size_tx = furi_stream_buffer_bytes_available(instance->stream_tx); if(size_tx > 0 && !timeout_tx) { timeout_tx = 10; //20ms if(size_tx > SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, @@ -160,20 +159,20 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); } else { //todo checking that he managed to write all the data to the TX buffer - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, size_tx); } } else { //recive if(subghz_tx_rx_worker_rx(instance, data, size_rx)) { - if(xStreamBufferSpacesAvailable(instance->stream_rx) >= size_rx[0]) { + if(furi_stream_buffer_spaces_available(instance->stream_rx) >= size_rx[0]) { if(instance->callback_have_read && - xStreamBufferBytesAvailable(instance->stream_rx) == 0) { + furi_stream_buffer_bytes_available(instance->stream_rx) == 0) { callback_rx = true; } //todo checking that he managed to write all the data to the RX buffer - xStreamBufferSend( + furi_stream_buffer_send( instance->stream_rx, &data, size_rx[0], @@ -208,9 +207,9 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread); instance->stream_tx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->stream_rx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->status = SubGhzTxRxWorkerStatusIDLE; instance->worker_stoping = true; @@ -221,8 +220,8 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { furi_assert(instance); furi_assert(!instance->worker_running); - vStreamBufferDelete(instance->stream_tx); - vStreamBufferDelete(instance->stream_rx); + furi_stream_buffer_free(instance->stream_tx); + furi_stream_buffer_free(instance->stream_rx); furi_thread_free(instance->thread); free(instance); @@ -232,8 +231,8 @@ bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) { furi_assert(instance); furi_assert(!instance->worker_running); bool res = false; - xStreamBufferReset(instance->stream_tx); - xStreamBufferReset(instance->stream_rx); + furi_stream_buffer_reset(instance->stream_tx); + furi_stream_buffer_reset(instance->stream_rx); instance->worker_running = true; diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c index 58db8ea5..61146c16 100644 --- a/lib/subghz/subghz_worker.c +++ b/lib/subghz/subghz_worker.c @@ -1,13 +1,12 @@ #include "subghz_worker.h" -#include #include #define TAG "SubGhzWorker" struct SubGhzWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; volatile bool running; volatile bool overrun; @@ -30,16 +29,14 @@ struct SubGhzWorker { void subghz_worker_rx_callback(bool level, uint32_t duration, void* context) { SubGhzWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /** Worker callback thread @@ -52,8 +49,8 @@ static int32_t subghz_worker_thread_callback(void* context) { LevelDuration level_duration; while(instance->running) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { FURI_LOG_E(TAG, "Overrun buffer"); @@ -97,7 +94,8 @@ SubGhzWorker* subghz_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_worker_thread_callback); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); //setting filter instance->filter_running = true; @@ -109,7 +107,7 @@ SubGhzWorker* subghz_worker_alloc() { void subghz_worker_free(SubGhzWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); diff --git a/lib/toolbox/buffer_stream.c b/lib/toolbox/buffer_stream.c index 66d21096..37b2514e 100644 --- a/lib/toolbox/buffer_stream.c +++ b/lib/toolbox/buffer_stream.c @@ -1,5 +1,4 @@ #include "buffer_stream.h" -#include struct Buffer { volatile bool occupied; @@ -10,7 +9,7 @@ struct Buffer { struct BufferStream { size_t stream_overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t index; Buffer* buffers; @@ -54,7 +53,7 @@ BufferStream* buffer_stream_alloc(size_t buffer_size, size_t buffers_count) { buffer_stream->buffers[i].data = malloc(buffer_size); buffer_stream->buffers[i].max_data_size = buffer_size; } - buffer_stream->stream = xStreamBufferCreate( + buffer_stream->stream = furi_stream_buffer_alloc( sizeof(BufferStream*) * buffer_stream->max_buffers_count, sizeof(BufferStream*)); buffer_stream->stream_overrun_count = 0; buffer_stream->index = 0; @@ -66,7 +65,7 @@ void buffer_stream_free(BufferStream* buffer_stream) { for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { free(buffer_stream->buffers[i].data); } - vStreamBufferDelete(buffer_stream->stream); + furi_stream_buffer_free(buffer_stream->stream); free(buffer_stream->buffers); free(buffer_stream); } @@ -83,11 +82,7 @@ static inline int8_t buffer_stream_get_free_buffer(BufferStream* buffer_stream) return id; } -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken) { +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size) { Buffer* buffer = &buffer_stream->buffers[buffer_stream->index]; bool result = true; @@ -96,7 +91,7 @@ bool buffer_stream_send_from_isr( // if buffer is full - send it buffer->occupied = true; // we always have space for buffer in stream - xStreamBufferSendFromISR(buffer_stream->stream, &buffer, sizeof(Buffer*), task_woken); + furi_stream_buffer_send(buffer_stream->stream, &buffer, sizeof(Buffer*), 0); // get new buffer from the pool int8_t index = buffer_stream_get_free_buffer(buffer_stream); @@ -119,7 +114,8 @@ bool buffer_stream_send_from_isr( Buffer* buffer_stream_receive(BufferStream* buffer_stream, TickType_t timeout) { Buffer* buffer; - size_t size = xStreamBufferReceive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); + size_t size = + furi_stream_buffer_receive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); if(size == sizeof(Buffer*)) { return buffer; @@ -134,9 +130,8 @@ size_t buffer_stream_get_overrun_count(BufferStream* buffer_stream) { void buffer_stream_reset(BufferStream* buffer_stream) { FURI_CRITICAL_ENTER(); - BaseType_t xReturn = xStreamBufferReset(buffer_stream->stream); - furi_assert(xReturn == pdPASS); - UNUSED(xReturn); + furi_stream_buffer_reset(buffer_stream->stream); + buffer_stream->stream_overrun_count = 0; for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { buffer_reset(&buffer_stream->buffers[i]); diff --git a/lib/toolbox/buffer_stream.h b/lib/toolbox/buffer_stream.h index d4c3cddf..9db54775 100644 --- a/lib/toolbox/buffer_stream.h +++ b/lib/toolbox/buffer_stream.h @@ -59,14 +59,9 @@ void buffer_stream_free(BufferStream* buffer_stream); * @param buffer_stream * @param data * @param size - * @param task_woken * @return bool */ -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken); +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size); /** * @brief Receive buffer from stream From 1f742b611a793e4b17d7036541ba48557cb5e766 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Fri, 7 Oct 2022 15:46:58 +0300 Subject: [PATCH 21/49] [FL-2651, FL-2863] App name in CLI loader command, RFID data edit fix #1835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/gpio/views/gpio_usb_uart.c | 4 +-- .../lfrfid/scenes/lfrfid_scene_save_data.c | 9 +++-- .../lfrfid/scenes/lfrfid_scene_save_success.c | 3 ++ applications/services/loader/loader.c | 33 +++++++++++++++++-- applications/services/storage/storage_cli.c | 6 ++-- .../storage_settings_scene_internal_info.c | 2 +- .../scenes/storage_settings_scene_sd_info.c | 2 +- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/applications/main/gpio/views/gpio_usb_uart.c b/applications/main/gpio/views/gpio_usb_uart.c index d2d371b6..d190ecab 100644 --- a/applications/main/gpio/views/gpio_usb_uart.c +++ b/applications/main/gpio/views/gpio_usb_uart.c @@ -54,7 +54,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 24, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->tx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 24, AlignRight, AlignBottom, temp_str); @@ -68,7 +68,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 41, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->rx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 41, AlignRight, AlignBottom, temp_str); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c index 2ca1bb43..6c5ea2f2 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c @@ -9,14 +9,11 @@ void lfrfid_scene_save_data_on_enter(void* context) { bool need_restore = scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveData); - if(need_restore) { - protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); - } else { + if(!need_restore) { protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); + protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); } - protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); - byte_input_set_header_text(byte_input, "Enter the data in hex"); byte_input_set_result_callback( @@ -41,6 +38,8 @@ bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) { } } else if(event.type == SceneManagerEventTypeBack) { scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 0); + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c index 830ef336..e91ad04e 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c @@ -5,6 +5,9 @@ void lfrfid_scene_save_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; + // Clear state of data enter scene + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0); + DOLPHIN_DEED(DolphinDeedRfidSave); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 51cddec7..bc456536 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -61,6 +61,7 @@ static void loader_cli_print_usage() { printf("Cmd list:\r\n"); printf("\tlist\t - List available applications\r\n"); printf("\topen \t - Open application by name\r\n"); + printf("\tinfo\t - Show loader state\r\n"); } static FlipperApplication const* loader_find_application_by_name_in_list( @@ -98,10 +99,15 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { return application; } -void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { +static void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); if(loader_is_locked(instance)) { - printf("Can't start, furi application is running"); + if(instance->application) { + furi_assert(instance->application->name); + printf("Can't start, %s application is running", instance->application->name); + } else { + printf("Can't start, furi application is running"); + } return; } @@ -137,7 +143,7 @@ void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { furi_string_free(application_name); } -void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { +static void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); UNUSED(args); UNUSED(instance); @@ -159,6 +165,22 @@ void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { } } +static void loader_cli_info(Cli* cli, FuriString* args, Loader* instance) { + UNUSED(cli); + UNUSED(args); + if(!loader_is_locked(instance)) { + printf("No application is running\r\n"); + } else { + printf("Running application: "); + if(instance->application) { + furi_assert(instance->application->name); + printf("%s\r\n", instance->application->name); + } else { + printf("unknown\r\n"); + } + } +} + static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { furi_assert(_ctx); Loader* instance = _ctx; @@ -182,6 +204,11 @@ static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { break; } + if(furi_string_cmp_str(cmd, "info") == 0) { + loader_cli_info(cli, args, instance); + break; + } + loader_cli_print_usage(); } while(false); diff --git a/applications/services/storage/storage_cli.c b/applications/services/storage/storage_cli.c index 5e72dce8..880fb970 100644 --- a/applications/services/storage/storage_cli.c +++ b/applications/services/storage/storage_cli.c @@ -52,7 +52,7 @@ static void storage_cli_info(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: LittleFS\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: LittleFS\r\n%luKiB total\r\n%luKiB free\r\n", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); @@ -65,7 +65,7 @@ static void storage_cli_info(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: %s\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: %s\r\n%luKiB total\r\n%luKiB free\r\n", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, @@ -364,7 +364,7 @@ static void storage_cli_stat(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Storage, %luKB total, %luKB free\r\n", + "Storage, %luKiB total, %luKiB free\r\n", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c index d2d4ecd8..f205efc0 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c @@ -27,7 +27,7 @@ void storage_settings_scene_internal_info_on_enter(void* context) { } else { furi_string_printf( app->text_string, - "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", + "Label: %s\nType: LittleFS\n%lu KiB total\n%lu KiB free", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c index f5d286c7..ede610d0 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c @@ -26,7 +26,7 @@ void storage_settings_scene_sd_info_on_enter(void* context) { } else { furi_string_printf( app->text_string, - "Label: %s\nType: %s\n%lu KB total\n%lu KB free", + "Label: %s\nType: %s\n%lu KiB total\n%lu KiB free", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, From 4000f0cac51fa32006c7737ea8c34494bf4003f2 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 7 Oct 2022 23:35:15 +1000 Subject: [PATCH 22/49] [FL-2870] Printf function attributes (#1841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Furi strings: printf attribute * Logs: printf attribute * Plugins: adapt * Plugins: accommodate * Unit tests: accommodate Co-authored-by: あく --- .../debug/unit_tests/infrared/infrared_test.c | 10 +++---- applications/debug/unit_tests/nfc/nfc_test.c | 10 +++---- .../main/archive/helpers/archive_favorites.h | 4 +-- .../main/archive/helpers/archive_files.h | 6 ++-- applications/main/bad_usb/bad_usb_script.c | 6 ++-- .../main/bad_usb/views/bad_usb_view.c | 2 +- .../main/fap_loader/elf_cpp/elf_hashtable.cpp | 2 +- applications/main/infrared/infrared.c | 4 +-- applications/main/infrared/infrared_signal.c | 4 +-- .../scenes/nfc_scene_mf_classic_keys_list.c | 2 +- .../nfc_scene_mf_desfire_read_success.c | 4 +-- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 4 +-- .../subghz_frequency_analyzer_worker.c | 8 +++--- applications/main/subghz/subghz_cli.c | 6 ++-- applications/main/subghz/subghz_i.c | 2 +- .../music_player/music_player_worker.c | 6 ++-- applications/services/bt/bt_service/bt.c | 4 +-- .../desktop/animations/animation_storage.c | 4 +-- .../services/dolphin/helpers/dolphin_state.c | 2 +- applications/services/gui/gui.c | 6 ++-- .../gui/modules/file_browser_worker.c | 9 +++--- applications/services/gui/view_dispatcher.c | 4 +-- applications/services/rpc/rpc_app.c | 18 ++++++------ applications/services/rpc/rpc_cli.c | 2 +- applications/services/rpc/rpc_debug.c | 4 +-- .../services/storage/storage_external_api.c | 28 +++++++++++++++---- .../services/storage/storages/storage_int.c | 14 +++++----- .../updater/util/update_task_worker_flasher.c | 8 +++--- firmware/targets/f7/ble_glue/gap.c | 4 +-- firmware/targets/f7/ble_glue/serial_service.c | 4 +-- .../targets/f7/furi_hal/furi_hal_console.h | 3 +- firmware/targets/f7/furi_hal/furi_hal_flash.c | 6 ++-- .../targets/f7/furi_hal/furi_hal_memory.c | 4 +-- firmware/targets/f7/furi_hal/furi_hal_power.c | 6 ++-- .../targets/f7/furi_hal/furi_hal_subghz.c | 2 +- furi/core/log.h | 3 +- furi/core/string.h | 9 ++++-- lib/lfrfid/lfrfid_raw_worker.c | 2 +- lib/lfrfid/protocols/protocol_gallagher.c | 2 +- lib/lfrfid/protocols/protocol_keri.c | 2 +- lib/lfrfid/protocols/protocol_paradox.c | 2 +- lib/lfrfid/protocols/protocol_pyramid.c | 2 +- lib/nfc/helpers/mf_classic_dict.c | 2 +- lib/nfc/helpers/mfkey32.c | 2 +- lib/nfc/nfc_worker.c | 3 +- lib/nfc/parsers/all_in_one.c | 2 +- lib/nfc/parsers/plantain_4k_parser.c | 2 +- lib/nfc/parsers/plantain_parser.c | 2 +- lib/nfc/parsers/two_cities.c | 2 +- lib/nfc/protocols/mifare_classic.c | 4 +-- lib/nfc/protocols/mifare_desfire.c | 8 +++--- lib/nfc/protocols/mifare_ultralight.c | 4 +-- lib/print/printf_tiny.h | 11 +++++--- lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/came_twee.c | 2 +- lib/subghz/protocols/doitrand.c | 2 +- lib/subghz/protocols/faac_slh.c | 2 +- lib/subghz/protocols/gate_tx.c | 2 +- lib/subghz/protocols/honeywell_wdb.c | 2 +- lib/subghz/protocols/ido.c | 2 +- lib/subghz/protocols/keeloq.c | 4 +-- lib/subghz/protocols/kia.c | 2 +- lib/subghz/protocols/magellen.c | 2 +- lib/subghz/protocols/marantec.c | 2 +- lib/subghz/protocols/megacode.c | 4 +-- lib/subghz/protocols/nice_flor_s.c | 2 +- lib/subghz/protocols/oregon2.c | 4 +-- lib/subghz/protocols/phoenix_v2.c | 2 +- lib/subghz/protocols/princeton.c | 2 +- lib/subghz/protocols/princeton_for_testing.c | 2 +- lib/subghz/protocols/raw.c | 2 +- lib/subghz/protocols/scher_khan.c | 2 +- lib/subghz/protocols/secplus_v1.c | 4 +-- lib/subghz/protocols/secplus_v2.c | 2 +- lib/subghz/protocols/somfy_keytis.c | 2 +- lib/subghz/protocols/somfy_telis.c | 2 +- lib/subghz/protocols/star_line.c | 4 +-- lib/toolbox/stream/stream.h | 9 ++++-- 78 files changed, 187 insertions(+), 156 deletions(-) diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index d861f266..8879c8fc 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -221,13 +221,13 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - furi_string_printf(buf, "encoder_input%d", test_index); + furi_string_printf(buf, "encoder_input%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); - furi_string_printf(buf, "encoder_expected%d", test_index); + furi_string_printf(buf, "encoder_expected%ld", test_index); mu_assert( infrared_test_load_raw_signal( test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count), @@ -277,7 +277,7 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_ const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - furi_string_printf(buf, "encoder_decoder_input%d", test_index); + furi_string_printf(buf, "encoder_decoder_input%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), @@ -336,13 +336,13 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i infrared_test_prepare_file(infrared_get_protocol_name(protocol)), "Failed to prepare test file"); - furi_string_printf(buf, "decoder_input%d", test_index); + furi_string_printf(buf, "decoder_input%ld", test_index); mu_assert( infrared_test_load_raw_signal( test->ff, furi_string_get_cstr(buf), &timings, &timings_count), "Failed to load raw signal from file"); - furi_string_printf(buf, "decoder_expected%d", test_index); + furi_string_printf(buf, "decoder_expected%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &messages, &messages_count), diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index c1468c86..f149508b 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -112,7 +112,7 @@ static bool nfc_test_digital_signal_test_encode( // Check timings if(time > encode_max_time) { FURI_LOG_E( - TAG, "Encoding time: %d us while accepted value: %d us", time, encode_max_time); + TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time); break; } @@ -132,7 +132,7 @@ static bool nfc_test_digital_signal_test_encode( ref_timings_sum += ref[i]; if(timings_diff > timing_tolerance) { FURI_LOG_E( - TAG, "Too big differece in %d timings. Ref: %d, DUT: %d", i, ref[i], dut[i]); + TAG, "Too big differece in %d timings. Ref: %ld, DUT: %ld", i, ref[i], dut[i]); timing_check_success = false; break; } @@ -143,16 +143,16 @@ static bool nfc_test_digital_signal_test_encode( if(sum_diff > timings_sum_tolerance) { FURI_LOG_E( TAG, - "Too big difference in timings sum. Ref: %d, DUT: %d", + "Too big difference in timings sum. Ref: %ld, DUT: %ld", ref_timings_sum, dut_timings_sum); break; } - FURI_LOG_I(TAG, "Encoding time: %d us. Acceptable time: %d us", time, encode_max_time); + FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time); FURI_LOG_I( TAG, - "Timings sum difference: %d [1/64MHZ]. Acceptable difference: %d [1/64MHz]", + "Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]", sum_diff, timings_sum_tolerance); success = true; diff --git a/applications/main/archive/helpers/archive_favorites.h b/applications/main/archive/helpers/archive_favorites.h index 29eedcdb..db894337 100644 --- a/applications/main/archive/helpers/archive_favorites.h +++ b/applications/main/archive/helpers/archive_favorites.h @@ -7,8 +7,8 @@ uint16_t archive_favorites_count(void* context); bool archive_favorites_read(void* context); -bool archive_favorites_delete(const char* format, ...); -bool archive_is_favorite(const char* format, ...); +bool archive_favorites_delete(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); +bool archive_is_favorite(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); bool archive_favorites_rename(const char* src, const char* dst); void archive_add_to_favorites(const char* file_path); void archive_favorites_save(void* context); diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 2017a957..1822befa 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -86,5 +86,7 @@ ARRAY_DEF( void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app); bool archive_get_items(void* context, const char* path); -void archive_file_append(const char* path, const char* format, ...); -void archive_delete_file(void* context, const char* format, ...); +void archive_file_append(const char* path, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); +void archive_delete_file(void* context, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 4166642b..1e3edf40 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -323,7 +323,7 @@ static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) { } FURI_LOG_D( WORKER_TAG, - "set id: %04X:%04X mfr:%s product:%s", + "set id: %04lX:%04lX mfr:%s product:%s", bad_usb->hid_cfg.vid, bad_usb->hid_cfg.pid, bad_usb->hid_cfg.manuf, @@ -388,7 +388,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return 0; } else if(delay_val < 0) { // Script error bad_usb->st.error_line = bad_usb->st.line_cur - 1; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur - 1); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); @@ -420,7 +420,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil delay_val = ducky_parse_line(bad_usb, bad_usb->line); if(delay_val < 0) { bad_usb->st.error_line = bad_usb->st.line_cur; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 4e025b99..b6310193 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -91,7 +91,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); canvas_set_font(canvas, FontSecondary); - furi_string_printf(disp_str, "delay %us", model->state.delay_remain); + furi_string_printf(disp_str, "delay %lus", model->state.delay_remain); canvas_draw_str_aligned( canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); diff --git a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp index 17e2ba83..f8adbf9d 100644 --- a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp +++ b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp @@ -31,7 +31,7 @@ bool elf_resolve_from_hashtable(const char* name, Elf32_Addr* address) { auto find_res = std::lower_bound(elf_api_table.cbegin(), elf_api_table.cend(), key); if((find_res == elf_api_table.cend() || (find_res->hash != gnu_sym_hash))) { - FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %x)!", name, gnu_sym_hash); + FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %lx)!", name, gnu_sym_hash); result = false; } else { result = true; diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index a647b158..f62db14c 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -92,14 +92,14 @@ static void infrared_find_vacant_remote_name(FuriString* name, const char* path) uint32_t i = 1; do { furi_string_printf( - path_temp, "%s%u%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); + path_temp, "%s%lu%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL); } while(status == FSE_OK); furi_string_free(path_temp); if(status == FSE_NOT_EXIST) { - furi_string_cat_printf(name, "%u", i); + furi_string_cat_printf(name, "%lu", i); } } diff --git a/applications/main/infrared/infrared_signal.c b/applications/main/infrared/infrared_signal.c index 30459d60..d399b958 100644 --- a/applications/main/infrared/infrared_signal.c +++ b/applications/main/infrared/infrared_signal.c @@ -61,7 +61,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) { FURI_LOG_E( TAG, - "Frequency is out of range (%lX - %lX): %lX", + "Frequency is out of range (%X - %X): %lX", INFRARED_MIN_FREQUENCY, INFRARED_MAX_FREQUENCY, raw->frequency); @@ -74,7 +74,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { } else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) { FURI_LOG_E( TAG, - "Timings amount is out of range (0 - %lX): %lX", + "Timings amount is out of range (0 - %X): %X", MAX_TIMINGS_AMOUNT, raw->timings_size); return false; diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c index 5649ea87..19d2f556 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c @@ -27,7 +27,7 @@ void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) { char* current_key = (char*)malloc(sizeof(char) * 13); strncpy(current_key, furi_string_get_cstr(temp_key), 12); MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); - FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); + FURI_LOG_D("ListKeys", "Key %ld: %s", index, current_key); submenu_add_item( submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c index c5b8cfa2..2ab0355c 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -28,11 +28,11 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - furi_string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { furi_string_push_back(temp_str, '+'); } - furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index bb7d58f7..8f33972e 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -59,11 +59,11 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { MifareDesfireData* data = &dev_data->mf_df_data; uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - furi_string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { furi_string_push_back(temp_str, '+'); } - furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 35abbddc..0341990d 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -149,7 +149,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { FURI_LOG_T( TAG, - "RSSI: avg %f, max %f at %u, min %f", + "RSSI: avg %f, max %f at %lu, min %f", (double)(rssi_avg / rssi_avg_samples), (double)frequency_rssi.rssi_coarse, frequency_rssi.frequency_coarse, @@ -180,7 +180,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { rssi = furi_hal_subghz_get_rssi(); - FURI_LOG_T(TAG, "#:%u:%f", frequency, (double)rssi); + FURI_LOG_T(TAG, "#:%lu:%f", frequency, (double)rssi); if(frequency_rssi.rssi_fine < rssi) { frequency_rssi.rssi_fine = rssi; @@ -193,7 +193,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { // Deliver results fine if(frequency_rssi.rssi_fine > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) { FURI_LOG_D( - TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); + TAG, "=:%lu:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); instance->sample_hold_counter = 20; rssi_temp = frequency_rssi.rssi_fine; @@ -217,7 +217,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { (instance->sample_hold_counter < 10)) { FURI_LOG_D( TAG, - "~:%u:%f", + "~:%lu:%f", frequency_rssi.frequency_coarse, (double)frequency_rssi.rssi_coarse); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 7fa0f454..a1474885 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -151,8 +151,8 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { "Protocol: Princeton\n" "Bit: 24\n" "Key: 00 00 00 00 00 %02X %02X %02X\n" - "TE: %d\n" - "Repeat: %d\n", + "TE: %ld\n" + "Repeat: %ld\n", (uint8_t)((key >> 16) & 0xFF), (uint8_t)((key >> 8) & 0xFF), (uint8_t)(key & 0xFF), @@ -794,7 +794,7 @@ static bool subghz_on_system_start_istream_decode_band( FURI_LOG_I( "SubGhzOnStart", - "Add allowed band: start %dHz, stop %dHz, power_limit %ddBm, duty_cycle %d%%", + "Add allowed band: start %ldHz, stop %ldHz, power_limit %ddBm, duty_cycle %d%%", band.start, band.end, band.power_limit, diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index f2658c0e..acf07bc1 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -60,7 +60,7 @@ void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, Furi subghz->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { - furi_string_printf(modulation, "%0.2s", furi_string_get_cstr(subghz->txrx->preset->name)); + furi_string_printf(modulation, "%2s", furi_string_get_cstr(subghz->txrx->preset->name)); } } diff --git a/applications/plugins/music_player/music_player_worker.c b/applications/plugins/music_player/music_player_worker.c index af09f053..99f0ce1e 100644 --- a/applications/plugins/music_player/music_player_worker.c +++ b/applications/plugins/music_player/music_player_worker.c @@ -258,7 +258,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(!is_valid) { FURI_LOG_E( TAG, - "Invalid note: %u%c%c%u.%u", + "Invalid note: %lu%c%c%lu.%lu", duration, note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, @@ -281,7 +281,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(music_player_worker_add_note(instance, semitone, duration, dots)) { FURI_LOG_D( TAG, - "Added note: %c%c%u.%u = %u %u", + "Added note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, @@ -291,7 +291,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c } else { FURI_LOG_E( TAG, - "Invalid note: %c%c%u.%u = %u %u", + "Invalid note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 2bb083f2..aeb2beec 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -77,7 +77,7 @@ static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { notification_message(bt->notification, &sequence_display_backlight_on); FuriString* pin_str; dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); - pin_str = furi_string_alloc_printf("Verify code\n%06d", pin); + pin_str = furi_string_alloc_printf("Verify code\n%06ld", pin); dialog_message_set_text( bt->dialog_message, furi_string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); dialog_message_set_buttons(bt->dialog_message, "Cancel", "OK", NULL); @@ -277,7 +277,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void* context) { furi_assert(context); Bt* bt = context; - FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); + FURI_LOG_I(TAG, "Changed addr start: %p, size changed: %d", addr, size); BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; furi_check( furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index 922d7dc8..0727fd6a 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -304,7 +304,7 @@ static bool animation_storage_load_frames( if(file_info.size > max_filesize) { FURI_LOG_E( TAG, - "Filesize %d, max: %d (width %d, height %d)", + "Filesize %lld, max: %d (width %d, height %d)", file_info.size, max_filesize, width, @@ -329,7 +329,7 @@ static bool animation_storage_load_frames( if(!frames_ok) { FURI_LOG_E( TAG, - "Load \'%s\' failed, %dx%d, size: %d", + "Load \'%s\' failed, %dx%d, size: %lld", furi_string_get_cstr(filename), width, height, diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 95e2f42f..10cb85c2 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -171,7 +171,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { FURI_LOG_D( TAG, - "icounter %d, butthurt %d", + "icounter %ld, butthurt %ld", dolphin_state->data.icounter, dolphin_state->data.butthurt); } diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index 6b4b9a0a..0535b32b 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -260,7 +260,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { "non-complementary input, discarding key: %s type: %s, sequence: %p", input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); return; } @@ -290,7 +290,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); view_port_input(gui->ongoing_input_view_port, input_event); } else { FURI_LOG_D( @@ -300,7 +300,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); } gui_unlock(gui); diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 319304f9..fdaf8273 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -291,7 +291,7 @@ static int32_t browser_worker(void* context) { browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Enter folder: %s items: %u idx: %d", + "Enter folder: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, file_idx); @@ -313,7 +313,7 @@ static int32_t browser_worker(void* context) { } FURI_LOG_D( TAG, - "Exit to: %s items: %u idx: %d", + "Exit to: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, file_idx); @@ -330,7 +330,7 @@ static int32_t browser_worker(void* context) { browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Refresh folder: %s items: %u idx: %d", + "Refresh folder: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, browser->item_sel_idx); @@ -340,7 +340,8 @@ static int32_t browser_worker(void* context) { } if(flags & WorkerEvtLoad) { - FURI_LOG_D(TAG, "Load offset: %u cnt: %u", browser->load_offset, browser->load_count); + FURI_LOG_D( + TAG, "Load offset: %lu cnt: %lu", browser->load_offset, browser->load_count); browser_folder_load(browser, path, browser->load_offset, browser->load_count); } diff --git a/applications/services/gui/view_dispatcher.c b/applications/services/gui/view_dispatcher.c index 307206c1..6e4ce836 100644 --- a/applications/services/gui/view_dispatcher.c +++ b/applications/services/gui/view_dispatcher.c @@ -246,7 +246,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e "non-complementary input, discarding key: %s, type: %s, sequence: %p", input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); return; } @@ -286,7 +286,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e view_dispatcher->current_view, input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); view_input(view_dispatcher->ongoing_input_view, event); } } diff --git a/applications/services/rpc/rpc_app.c b/applications/services/rpc/rpc_app.c index b8b34170..30105557 100644 --- a/applications/services/rpc/rpc_app.c +++ b/applications/services/rpc/rpc_app.c @@ -32,7 +32,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); - FURI_LOG_D(TAG, "StartProcess: id %d", request->command_id); + FURI_LOG_D(TAG, "StartProcess: id %ld", request->command_id); PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; @@ -63,7 +63,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_record_close(RECORD_LOADER); - FURI_LOG_D(TAG, "StartProcess: response id %d, result %d", request->command_id, result); + FURI_LOG_D(TAG, "StartProcess: response id %ld, result %d", request->command_id, result); rpc_send_and_release_empty(session, request->command_id, result); } @@ -108,7 +108,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "ExitRequest: id %d", request->command_id); + FURI_LOG_D(TAG, "ExitRequest: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -116,7 +116,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ExitRequest: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ExitRequest: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -132,7 +132,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "LoadFile: id %d", request->command_id); + FURI_LOG_D(TAG, "LoadFile: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -141,7 +141,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "LoadFile: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "LoadFile: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -166,7 +166,7 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonPress: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonPress: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -190,7 +190,7 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonRelease: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonRelease: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -243,7 +243,7 @@ void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool free(rpc_app->last_data); rpc_app->last_data = NULL; } - FURI_LOG_D(TAG, "AppConfirm: event %d last_id %d status %d", event, last_id, status); + FURI_LOG_D(TAG, "AppConfirm: event %d last_id %ld status %d", event, last_id, status); rpc_send_and_release_empty(session, last_id, status); break; default: diff --git a/applications/services/rpc/rpc_cli.c b/applications/services/rpc/rpc_cli.c index d03e2198..82023e31 100644 --- a/applications/services/rpc/rpc_cli.c +++ b/applications/services/rpc/rpc_cli.c @@ -44,7 +44,7 @@ void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) { Rpc* rpc = context; uint32_t mem_before = memmgr_get_free_heap(); - FURI_LOG_D(TAG, "Free memory %d", mem_before); + FURI_LOG_D(TAG, "Free memory %ld", mem_before); furi_hal_usb_lock(); RpcSession* rpc_session = rpc_session_open(rpc); diff --git a/applications/services/rpc/rpc_debug.c b/applications/services/rpc/rpc_debug.c index a060654d..8eb81dec 100644 --- a/applications/services/rpc/rpc_debug.c +++ b/applications/services/rpc/rpc_debug.c @@ -158,9 +158,9 @@ void rpc_debug_print_message(const PB_Main* message) { case PB_Main_storage_info_response_tag: { furi_string_cat_printf(str, "\tinfo_response {\r\n"); furi_string_cat_printf( - str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space); + str, "\t\ttotal_space: %llu\r\n", message->content.storage_info_response.total_space); furi_string_cat_printf( - str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space); + str, "\t\tfree_space: %llu\r\n", message->content.storage_info_response.free_space); break; } case PB_Main_storage_stat_request_tag: { diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index 379fc4ed..c0c730fb 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -119,7 +119,11 @@ bool storage_file_open( furi_event_flag_free(event); FURI_LOG_T( - TAG, "File %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "File %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -132,7 +136,11 @@ bool storage_file_close(File* file) { S_API_MESSAGE(StorageCommandFileClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "File %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "File %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; return S_RETURN_BOOL; @@ -291,7 +299,11 @@ bool storage_dir_open(File* file, const char* path) { furi_event_flag_free(event); FURI_LOG_T( - TAG, "Dir %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "Dir %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -303,7 +315,11 @@ bool storage_dir_close(File* file) { S_API_MESSAGE(StorageCommandDirClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "Dir %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "Dir %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; @@ -675,7 +691,7 @@ File* storage_file_alloc(Storage* storage) { file->type = FileTypeClosed; file->storage = storage; - FURI_LOG_T(TAG, "File/Dir %p alloc", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p alloc", (void*)((uint32_t)file - SRAM_BASE)); return file; } @@ -697,7 +713,7 @@ void storage_file_free(File* file) { } } - FURI_LOG_T(TAG, "File/Dir %p free", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p free", (void*)((uint32_t)file - SRAM_BASE)); free(file); } diff --git a/applications/services/storage/storages/storage_int.c b/applications/services/storage/storages/storage_int.c index ab025501..4fa5d130 100644 --- a/applications/services/storage/storages/storage_int.c +++ b/applications/services/storage/storages/storage_int.c @@ -77,12 +77,12 @@ static int storage_int_device_read( FURI_LOG_T( TAG, - "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device read: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); memcpy(buffer, (void*)address, size); @@ -100,12 +100,12 @@ static int storage_int_device_prog( FURI_LOG_T( TAG, - "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device prog: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); int ret = 0; while(size > 0) { @@ -122,7 +122,7 @@ static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t bloc LFSData* lfs_data = c->context; size_t page = lfs_data->start_page + block; - FURI_LOG_D(TAG, "Device erase: page %d, translated page: %x", block, page); + FURI_LOG_D(TAG, "Device erase: page %ld, translated page: %x", block, page); furi_hal_flash_erase(page); return 0; @@ -740,8 +740,8 @@ void storage_int_init(StorageData* storage) { LFSData* lfs_data = storage_int_lfs_data_alloc(); FURI_LOG_I( TAG, - "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d", - lfs_data->start_address, + "Config: start %p, read %ld, write %ld, page size: %ld, page count: %ld, cycles: %ld", + (void*)lfs_data->start_address, lfs_data->config.read_size, lfs_data->config.prog_size, lfs_data->config.block_size, diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index b235d001..7358a633 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -271,7 +271,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { match = false; FURI_LOG_E( TAG, - "OB MISMATCH: #%d: real %08X != %08X (exp.), full %08X", + "OB MISMATCH: #%d: real %08lX != %08lX (exp.), full %08lX", idx, device_ob_value_masked, ref_value, @@ -289,7 +289,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { (manifest->ob_reference.obs[idx].values.base & manifest->ob_write_mask.obs[idx].values.base); - FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08X", idx, patched_value); + FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08lX", idx, patched_value); ob_dirty = true; bool is_fixed = furi_hal_flash_ob_set_word(idx, patched_value) && @@ -301,7 +301,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { * reference value */ FURI_LOG_W( TAG, - "OB #%d is FUBAR (fixed&masked %08X, not %08X)", + "OB #%d is FUBAR (fixed&masked %08lX, not %08lX)", idx, patched_value, ref_value); @@ -310,7 +310,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { } else { FURI_LOG_D( TAG, - "OB MATCH: #%d: real %08X == %08X (exp.)", + "OB MATCH: #%d: real %08lX == %08lX (exp.)", idx, device_ob_value_masked, ref_value); diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 62db30fe..aa8cd2c9 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -184,7 +184,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { FURI_LOG_I(TAG, "Pass key request event. Pin: ******"); } else { - FURI_LOG_I(TAG, "Pass key request event. Pin: %06d", pin); + FURI_LOG_I(TAG, "Pass key request event. Pin: %06ld", pin); } GapEvent event = {.type = GapEventTypePinCodeShow, .data.pin_code = pin}; gap->on_event_cb(event, gap->context); @@ -227,7 +227,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0*)(blue_evt->data))->Numeric_Value; - FURI_LOG_I(TAG, "Verify numeric comparison: %06d", pin); + FURI_LOG_I(TAG, "Verify numeric comparison: %06ld", pin); GapEvent event = {.type = GapEventTypePinCodeVerify, .data.pin_code = pin}; bool result = gap->on_event_cb(event, gap->context); aci_gap_numeric_comparison_value_confirm_yesno(gap->service.connection_handle, result); diff --git a/firmware/targets/f7/ble_glue/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c index eb58ae0e..536557cc 100644 --- a/firmware/targets/f7/ble_glue/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -63,13 +63,13 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { .size = attribute_modified->Attr_Data_Length, }}; uint32_t buff_free_size = serial_svc->callback(event, serial_svc->context); - FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); + FURI_LOG_D(TAG, "Available buff size: %ld", buff_free_size); furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { - FURI_LOG_T(TAG, "Ack received", blecore_evt->ecode); + FURI_LOG_T(TAG, "Ack received"); if(serial_svc->callback) { SerialServiceEvent event = { .event = SerialServiceEventTypeDataSent, diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.h b/firmware/targets/f7/furi_hal/furi_hal_console.h index 104515ce..ce31a66b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.h +++ b/firmware/targets/f7/furi_hal/furi_hal_console.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size * @param format * @param ... */ -void furi_hal_console_printf(const char format[], ...); +void furi_hal_console_printf(const char format[], ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); void furi_hal_console_puts(const char* data); diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index f99cf8c3..e49cd5f2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -83,7 +83,7 @@ void furi_hal_flash_init() { // WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR); /* Actually, reset all error flags on start */ if(READ_BIT(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS)) { - FURI_LOG_E(TAG, "FLASH->SR 0x%08X", FLASH->SR); + FURI_LOG_E(TAG, "FLASH->SR 0x%08lX", FLASH->SR); WRITE_REG(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS); } } @@ -514,10 +514,10 @@ bool furi_hal_flash_ob_set_word(size_t word_idx, const uint32_t value) { FURI_LOG_W( TAG, - "Setting OB reg %d for word %d (addr 0x%08X) to 0x%08X", + "Setting OB reg %d for word %d (addr 0x%08lX) to 0x%08lX", reg_def->ob_reg, word_idx, - reg_def->ob_register_address, + (uint32_t)reg_def->ob_register_address, value); /* 1. Clear OPTLOCK option lock bit with the clearing sequence */ diff --git a/firmware/targets/f7/furi_hal/furi_hal_memory.c b/firmware/targets/f7/furi_hal/furi_hal_memory.c index 43dc56f1..9cf2c312 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_memory.c +++ b/firmware/targets/f7/furi_hal/furi_hal_memory.c @@ -55,9 +55,9 @@ void furi_hal_memory_init() { memory->region[SRAM_B].size = sram2b_unprotected_size; FURI_LOG_I( - TAG, "SRAM2A: 0x%p, %d", memory->region[SRAM_A].start, memory->region[SRAM_A].size); + TAG, "SRAM2A: 0x%p, %ld", memory->region[SRAM_A].start, memory->region[SRAM_A].size); FURI_LOG_I( - TAG, "SRAM2B: 0x%p, %d", memory->region[SRAM_B].start, memory->region[SRAM_B].size); + TAG, "SRAM2B: 0x%p, %ld", memory->region[SRAM_B].start, memory->region[SRAM_B].size); if((memory->region[SRAM_A].size > 0) || (memory->region[SRAM_B].size > 0)) { if((memory->region[SRAM_A].size > 0)) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index bc98f108..86505c57 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -569,13 +569,13 @@ void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { furi_string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); out("battery_health", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_remaining_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_remaining_capacity()); out("capacity_remain", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_full_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_full_capacity()); out("capacity_full", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_design_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_design_capacity()); out("capacity_design", furi_string_get_cstr(value), true, context); furi_string_free(value); diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index b73d074f..5eeb4e9a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -173,7 +173,7 @@ void furi_hal_subghz_load_custom_preset(uint8_t* preset_data) { i += 2; } for(uint8_t y = i; y < i + 10; y++) { - FURI_LOG_D(TAG, "PA[%lu]: %02X", y, preset_data[y]); + FURI_LOG_D(TAG, "PA[%u]: %02X", y, preset_data[y]); } } } diff --git a/furi/core/log.h b/furi/core/log.h index 30026fc4..cb8b3d9c 100644 --- a/furi/core/log.h +++ b/furi/core/log.h @@ -51,7 +51,8 @@ void furi_log_init(); * @param format * @param ... */ -void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...); +void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** Set log level * diff --git a/furi/core/string.h b/furi/core/string.h index b6700c9c..01b26cce 100644 --- a/furi/core/string.h +++ b/furi/core/string.h @@ -57,7 +57,8 @@ FuriString* furi_string_alloc_set_str(const char cstr_source[]); * @param ... * @return FuriString* */ -FuriString* furi_string_alloc_printf(const char format[], ...); +FuriString* furi_string_alloc_printf(const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 1, 2))); /** * @brief Allocate new FuriString and printf to it. @@ -214,7 +215,8 @@ void furi_string_set_n(FuriString* string, const FuriString* source, size_t offs * @param ... * @return int */ -int furi_string_printf(FuriString* string, const char format[], ...); +int furi_string_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * @brief Format in the string the given printf format @@ -259,7 +261,8 @@ void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); * @param ... * @return int */ -int furi_string_cat_printf(FuriString* string, const char format[], ...); +int furi_string_cat_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * @brief Append to the string the formatted string of the given printf format. diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index 9bab77db..1547d20f 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -338,7 +338,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { } if(data->ctx.overrun_count) { - FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count); + FURI_LOG_E(TAG_EMULATE, "overruns: %u", data->ctx.overrun_count); } furi_stream_buffer_free(data->ctx.stream); diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 460c23a3..4720d3a4 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -276,7 +276,7 @@ void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* res uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32); furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); - furi_string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id); + furi_string_cat_printf(result, "FC: %lu, C: %lu\r\n", fc, card_id); }; const ProtocolBase protocol_gallagher = { diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index 099fd168..f0a12863 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -218,7 +218,7 @@ void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { uint32_t fc = 0; uint32_t cn = 0; protocol_keri_descramble(&fc, &cn, &data); - furi_string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn); + furi_string_printf(result, "Internal ID: %lu\r\nFC: %lu, Card: %lu\r\n", internal_id, fc, cn); } bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index 6a8e33ba..7e029f1d 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -142,7 +142,7 @@ void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); furi_string_cat_printf(result, "Facility: %u\r\n", fc); - furi_string_cat_printf(result, "Card: %lu\r\n", card_id); + furi_string_cat_printf(result, "Card: %u\r\n", card_id); furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) { furi_string_cat_printf(result, "%02X", decoded_data[i]); diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index 54574458..974bb6da 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -243,7 +243,7 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - furi_string_cat_printf(result, "Format: 26\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8); diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c index 356f6f7c..a842ed92 100644 --- a/lib/nfc/helpers/mf_classic_dict.c +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -87,7 +87,7 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { stream_rewind(dict->stream); dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %d keys", dict->total_keys); + FURI_LOG_I(TAG, "Loaded dictionary with %ld keys", dict->total_keys); } while(false); if(!dict_loaded) { diff --git a/lib/nfc/helpers/mfkey32.c b/lib/nfc/helpers/mfkey32.c index fa5713f2..47e7e9f6 100644 --- a/lib/nfc/helpers/mfkey32.c +++ b/lib/nfc/helpers/mfkey32.c @@ -92,7 +92,7 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { FuriString* str = furi_string_alloc_printf( - "Sec %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", + "Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n", params->sector, params->key == MfClassicKeyA ? 'A' : 'B', params->cuid, diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index c61ad444..73245346 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -522,7 +522,8 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { return; } - FURI_LOG_D(TAG, "Start Dictionary attack, Key Count %d", mf_classic_dict_get_total_keys(dict)); + FURI_LOG_D( + TAG, "Start Dictionary attack, Key Count %ld", mf_classic_dict_get_total_keys(dict)); for(size_t i = 0; i < total_sectors; i++) { FURI_LOG_I(TAG, "Sector %d", i); nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); diff --git a/lib/nfc/parsers/all_in_one.c b/lib/nfc/parsers/all_in_one.c index f63fb7e6..05cfe576 100644 --- a/lib/nfc/parsers/all_in_one.c +++ b/lib/nfc/parsers/all_in_one.c @@ -108,6 +108,6 @@ bool all_in_one_parser_parse(NfcDeviceData* dev_data) { // Format string for rides count furi_string_printf( - dev_data->parsed_data, "\e#All-In-One\nNumber: %u\nRides left: %u", serial, ride_count); + dev_data->parsed_data, "\e#All-In-One\nNumber: %lu\nRides left: %u", serial, ride_count); return true; } \ No newline at end of file diff --git a/lib/nfc/parsers/plantain_4k_parser.c b/lib/nfc/parsers/plantain_4k_parser.c index eddebac2..348b5a64 100644 --- a/lib/nfc/parsers/plantain_4k_parser.c +++ b/lib/nfc/parsers/plantain_4k_parser.c @@ -132,7 +132,7 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", + "\e#Plantain\nN:%s\nBalance:%ld\n", furi_string_get_cstr(card_number_str), balance); furi_string_free(card_number_str); diff --git a/lib/nfc/parsers/plantain_parser.c b/lib/nfc/parsers/plantain_parser.c index ac7a90b2..5328b5c4 100644 --- a/lib/nfc/parsers/plantain_parser.c +++ b/lib/nfc/parsers/plantain_parser.c @@ -105,7 +105,7 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", + "\e#Plantain\nN:%s\nBalance:%ld\n", furi_string_get_cstr(card_number_str), balance); furi_string_free(card_number_str); diff --git a/lib/nfc/parsers/two_cities.c b/lib/nfc/parsers/two_cities.c index f5e31d51..2c6184a7 100644 --- a/lib/nfc/parsers/two_cities.c +++ b/lib/nfc/parsers/two_cities.c @@ -149,7 +149,7 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Troika+Plantain\nPN: %s\nPB: %d rur.\nTN: %d\nTB: %d rur.\n", + "\e#Troika+Plantain\nPN: %s\nPB: %ld rur.\nTN: %ld\nTB: %d rur.\n", furi_string_get_cstr(card_number_str), balance, troika_number, diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 3b534393..78320245 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -847,7 +847,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ FURI_LOG_D( TAG, - "%08x key%c block %d nt/nr/ar: %08x %08x %08x", + "%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx", emulator->cuid, access_key == MfClassicKeyA ? 'A' : 'B', sector_trailer_block, @@ -858,7 +858,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { - FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64)); + FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64)); // Don't send NACK, as the tag doesn't send it command_processed = true; break; diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index 9dd37f1e..b2247bf2 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -108,7 +108,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out) { } void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out) { - furi_string_cat_printf(out, "freeMem %d\n", free_mem->bytes); + furi_string_cat_printf(out, "freeMem %ld\n", free_mem->bytes); } void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out) { @@ -191,10 +191,10 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { case MifareDesfireFileTypeValue: size = 4; furi_string_cat_printf( - out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit); + out, "lo %ld hi %ld\n", file->settings.value.lo_limit, file->settings.value.hi_limit); furi_string_cat_printf( out, - "limit %d enabled %d\n", + "limit %ld enabled %d\n", file->settings.value.limited_credit_value, file->settings.value.limited_credit_enabled); break; @@ -203,7 +203,7 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { size = file->settings.record.size; num = file->settings.record.cur; furi_string_cat_printf(out, "size %d\n", size); - furi_string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max); + furi_string_cat_printf(out, "num %d max %ld\n", num, file->settings.record.max); break; } uint8_t* data = file->contents; diff --git a/lib/nfc/protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c index ffabe88a..a8d1f554 100644 --- a/lib/nfc/protocols/mifare_ultralight.c +++ b/lib/nfc/protocols/mifare_ultralight.c @@ -193,7 +193,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint *pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0]; } - FURI_LOG_I(TAG, "Auth success. Password: %08X. PACK: %04X", key, *pack); + FURI_LOG_I(TAG, "Auth success. Password: %08lX. PACK: %04X", key, *pack); authenticated = true; } while(false); @@ -1050,7 +1050,7 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* if(mirror_conf == MfUltralightMirrorUidCounter) furi_string_cat(str, uid_printed ? "x" : " "); - furi_string_cat_printf(str, "%06X", emulator->data.counter[2]); + furi_string_cat_printf(str, "%06lX", emulator->data.counter[2]); } } } diff --git a/lib/print/printf_tiny.h b/lib/print/printf_tiny.h index 8f292819..58f6a673 100644 --- a/lib/print/printf_tiny.h +++ b/lib/print/printf_tiny.h @@ -34,6 +34,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ void _putchar(char character); * \param format A string that specifies the format of the output * \return The number of characters that are written into the array, not counting the terminating null character */ -int printf_(const char* format, ...); +int printf_(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); /** * Tiny sprintf implementation @@ -63,7 +64,7 @@ int printf_(const char* format, ...); * \param format A string that specifies the format of the output * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ -int sprintf_(char* buffer, const char* format, ...); +int sprintf_(char* buffer, const char* format, ...) _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Tiny snprintf/vsnprintf implementation @@ -75,7 +76,8 @@ int sprintf_(char* buffer, const char* format, ...); * null character. A value equal or larger than count indicates truncation. Only when the returned value * is non-negative and less than count, the string has been completely written. */ -int snprintf_(char* buffer, size_t count, const char* format, ...); +int snprintf_(char* buffer, size_t count, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); /** @@ -94,7 +96,8 @@ int vprintf_(const char* format, va_list va); * \param format A string that specifies the format of the output * \return The number of characters that are sent to the output function, not counting the terminating null character */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); #ifdef __cplusplus } diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 1349d976..8c2a542c 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -338,7 +338,7 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* ou "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 65667be2..3d5029ec 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -457,7 +457,7 @@ void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* out output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c index eeab2576..5c340214 100644 --- a/lib/subghz/protocols/doitrand.c +++ b/lib/subghz/protocols/doitrand.c @@ -345,7 +345,7 @@ void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 75f8d4e9..b5443590 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -222,7 +222,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp "Key:%lX%08lX\r\n" "Fix:%08lX \r\n" "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", + "Sn:%07lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 73a50926..5cf3a871 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -325,7 +325,7 @@ void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* outpu output, "%s %dbit\r\n" "Key:%06lX\r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 326e79f8..3cd62698 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -385,7 +385,7 @@ void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* "Key:0x%lX%08lX\r\n" "Sn:0x%05lX\r\n" "DT:%s Al:%s\r\n" - "SK:%01lX R:%01lX LBat:%01lX\r\n", + "SK:%01X R:%01X LBat:%01X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index a0332f9e..6cc60bde 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -221,7 +221,7 @@ void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) { "Key:0x%lX%08lX\r\n" "Fix:%06lX \r\n" "Hop:%06lX \r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 2865309e..039d97a6 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -700,8 +700,8 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%01lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%01X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index aad26f16..d4683866 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -268,7 +268,7 @@ void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) { output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n", + "Sn:%07lX Btn:%X Cnt:%04lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/magellen.c b/lib/subghz/protocols/magellen.c index 0c801c08..160ec4a2 100644 --- a/lib/subghz/protocols/magellen.c +++ b/lib/subghz/protocols/magellen.c @@ -432,7 +432,7 @@ void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:0x%08lX\r\n" - "Sn:%03d%03d, Event:0x%02X\r\n" + "Sn:%03ld%03ld, Event:0x%02X\r\n" "Stat:", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index 1c3997b9..a72238a4 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -383,7 +383,7 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 40f22cfd..baa8188d 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -417,8 +417,8 @@ void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:0x%06lX\r\n" - "Sn:0x%04lX - %d\r\n" - "Facility:%X Btn:%X\r\n", + "Sn:0x%04lX - %ld\r\n" + "Facility:%lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)instance->generic.data, diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index ffd94811..d567ddf2 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -368,7 +368,7 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* o "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" "Sn:%05lX\r\n" - "Cnt:%04X Btn:%02lX\r\n", + "Cnt:%04lX Btn:%02X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/oregon2.c b/lib/subghz/protocols/oregon2.c index 48435502..561df819 100644 --- a/lib/subghz/protocols/oregon2.c +++ b/lib/subghz/protocols/oregon2.c @@ -253,7 +253,7 @@ static void val = ((var_data >> 4) & 0xF) * 10 + ((var_data >> 8) & 0xF); furi_string_cat_printf( output, - "Temp: %s%d.%d C\r\n", + "Temp: %s%ld.%ld C\r\n", (var_data & 0xF) ? "-" : "+", val, (uint32_t)(var_data >> 12) & 0xF); @@ -286,7 +286,7 @@ void subghz_protocol_decoder_oregon2_get_string(void* context, FuriString* outpu furi_string_cat_printf( output, "%s\r\n" - "ID: 0x%04lX, ch: %d%s, rc: 0x%02lX\r\n", + "ID: 0x%04lX, ch: %ld%s, rc: 0x%02lX\r\n", instance->generic.protocol_name, (uint32_t)sensor_id, (uint32_t)(instance->generic.data >> 12) & 0xF, diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index e97df9b6..019c3ec2 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -329,7 +329,7 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou "%s %dbit\r\n" "Key:%02lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index c981de1b..370f33fb 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -364,7 +364,7 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out "Key:0x%08lX\r\n" "Yek:0x%08lX\r\n" "Sn:0x%05lX Btn:%01X\r\n" - "Te:%dus\r\n", + "Te:%ldus\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 43078d2e..0987e0ad 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -94,7 +94,7 @@ void subghz_encoder_princeton_for_testing_print_log(void* context) { ((float)instance->time_high / (instance->time_high + instance->time_low)) * 100; FURI_LOG_I( TAG "Encoder", - "Radio tx_time=%dus ON=%dus, OFF=%dus, DutyCycle=%d,%d%%", + "Radio tx_time=%ldus ON=%ldus, OFF=%ldus, DutyCycle=%ld,%ld%%", instance->time_high + instance->time_low, instance->time_high, instance->time_low, diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 48c3ff4d..fd234502 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -115,7 +115,7 @@ bool subghz_protocol_raw_save_to_file_init( // Open file if(!flipper_format_file_open_always( instance->flipper_file, furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", temp_str); + FURI_LOG_E(TAG, "Unable to open file for write: %s", furi_string_get_cstr(temp_str)); break; } diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 617efbba..837dcf05 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -274,7 +274,7 @@ void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* ou output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n" + "Sn:%07lX Btn:%X Cnt:%04lX\r\n" "Pt: %s\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 885615b6..cfe6bdee 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -606,7 +606,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, @@ -625,7 +625,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 3c9b966a..73bb7802 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -821,7 +821,7 @@ void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* ou "Pk1:0x%lX%08lX\r\n" "Pk2:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index e1b75074..cf627ef3 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -437,7 +437,7 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* "%s %db\r\n" "%lX%08lX%06lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 1dfdf0c4..6e375bb3 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -374,7 +374,7 @@ void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* o "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index a8b0dad7..4b89bd2b 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -373,8 +373,8 @@ void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* out output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%02lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%02X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/toolbox/stream/stream.h b/lib/toolbox/stream/stream.h index 1ffb4044..fc385510 100644 --- a/lib/toolbox/stream/stream.h +++ b/lib/toolbox/stream/stream.h @@ -143,7 +143,8 @@ size_t stream_write_cstring(Stream* stream, const char* string); * @param ... * @return size_t how many bytes was written */ -size_t stream_write_format(Stream* stream, const char* format, ...); +size_t stream_write_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Write formatted string to the stream, va_list version @@ -200,7 +201,8 @@ bool stream_insert_cstring(Stream* stream, const char* string); * @return true if the operation was successful * @return false on error */ -bool stream_insert_format(Stream* stream, const char* format, ...); +bool stream_insert_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Insert formatted string to the stream, va_list version @@ -251,7 +253,8 @@ bool stream_delete_and_insert_cstring(Stream* stream, size_t delete_size, const * @return true if the operation was successful * @return false on error */ -bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...); +bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** * Delete N chars from the stream and insert formatted string to the stream, va_list version From 1a1f711897ad3080e903092d93e56d9cd63fa3d7 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Fri, 7 Oct 2022 16:58:36 +0300 Subject: [PATCH 23/49] Signal Generator app: UI update (#1829) * Signal Generator: UI update * icons renamed Co-authored-by: Aleksandr Kutuzov --- .../scenes/signal_gen_scene_mco.c | 19 +++++++++++++++--- .../scenes/signal_gen_scene_start.c | 4 ++-- .../signal_generator/views/signal_gen_pwm.c | 16 +++++++-------- assets/icons/Interface/SmallArrowDown_3x5.png | Bin 0 -> 3592 bytes assets/icons/Interface/SmallArrowUp_3x5.png | Bin 0 -> 7976 bytes firmware/targets/f7/api_symbols.csv | 4 +++- 6 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 assets/icons/Interface/SmallArrowDown_3x5.png create mode 100644 assets/icons/Interface/SmallArrowUp_3x5.png diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c index 632b08c7..0855cde0 100644 --- a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c @@ -1,12 +1,17 @@ #include "../signal_gen_app_i.h" typedef enum { + LineIndexPin, LineIndexSource, LineIndexDivision, } LineIndex; +static const char* const mco_pin_names[] = { + "13(Tx)", +}; + static const char* const mco_source_names[] = { - "32768", + "32768Hz", "64MHz", "~100K", "~200K", @@ -81,14 +86,22 @@ void signal_gen_scene_mco_on_enter(void* context) { VariableItem* item; + item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_pin_names[0]); + item = variable_item_list_add( - var_item_list, "Source", COUNT_OF(mco_source_names), mco_source_list_change_callback, app); + var_item_list, + "Frequency", + COUNT_OF(mco_source_names), + mco_source_list_change_callback, + app); variable_item_set_current_value_index(item, 0); variable_item_set_current_value_text(item, mco_source_names[0]); item = variable_item_list_add( var_item_list, - "Division", + "Freq. divider", COUNT_OF(mco_divisor_names), mco_divisor_list_change_callback, app); diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c index 91f6081d..3c7b9cc3 100644 --- a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c @@ -16,10 +16,10 @@ void signal_gen_scene_start_on_enter(void* context) { Submenu* submenu = app->submenu; submenu_add_item( - submenu, "PWM", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); + submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); submenu_add_item( submenu, - "Clock Output", + "Clock Generator", SubmenuIndexClockOutput, signal_gen_scene_start_submenu_callback, app); diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.c b/applications/plugins/signal_generator/views/signal_gen_pwm.c index 00b4ef26..4afed01a 100644 --- a/applications/plugins/signal_generator/views/signal_gen_pwm.c +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.c @@ -9,7 +9,7 @@ typedef enum { LineIndexTotalCount } LineIndex; -static const char* const pwm_ch_names[] = {"TIM1(2)", "LPTIM2(4)"}; +static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"}; struct SignalGenPwm { View* view; @@ -31,8 +31,8 @@ typedef struct { #define ITEM_H 64 / 3 #define ITEM_W 128 -#define VALUE_X 95 -#define VALUE_W 55 +#define VALUE_X 100 +#define VALUE_W 45 #define FREQ_VALUE_X 62 #define FREQ_MAX 1000000UL @@ -126,11 +126,11 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { for(uint8_t line = 0; line < LineIndexTotalCount; line++) { if(line == LineIndexChannel) { - line_label = "PWM Channel"; + line_label = "GPIO Pin"; } else if(line == LineIndexFrequency) { line_label = "Frequency"; } else if(line == LineIndexDuty) { - line_label = "Duty Cycle"; + line_label = "Pulse width"; } canvas_set_color(canvas, ColorBlack); @@ -162,9 +162,9 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontSecondary); if(model->edit_mode) { - uint8_t icon_x = (FREQ_VALUE_X - 1) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; - canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_4x7); - canvas_draw_icon(canvas, icon_x, text_y + 4, &I_SmallArrowDown_4x7); + uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; + canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_3x5); + canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_3x5); } } else if(line == LineIndexDuty) { snprintf(val_text, sizeof(val_text), "%d%%", model->duty); diff --git a/assets/icons/Interface/SmallArrowDown_3x5.png b/assets/icons/Interface/SmallArrowDown_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..1912e5d246268d75a20984bdc8b996d503f3d166 GIT binary patch literal 3592 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 BDRuw= literal 0 HcmV?d00001 diff --git a/assets/icons/Interface/SmallArrowUp_3x5.png b/assets/icons/Interface/SmallArrowUp_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..9c6242078d3bcc9a93eb55b6b5f358720ee6662c GIT binary patch literal 7976 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 Date: Sat, 8 Oct 2022 03:06:29 +1000 Subject: [PATCH 24/49] More correct elf loader (#1839) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ELF File: more robust section loader * ELF File: faster and smaller preinit, init and fini arrays handling * ELF File: load sections on preload stage * ELF File: naming * Furi: fix use after free in thread join Co-authored-by: あく --- applications/main/fap_loader/fap_loader_app.c | 2 + furi/core/thread.c | 8 +- lib/flipper_application/elf/elf_file.c | 212 ++++++++---------- lib/flipper_application/elf/elf_file_i.h | 8 +- 4 files changed, 100 insertions(+), 130 deletions(-) diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index fb0a300e..d2f6b1f4 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -70,6 +70,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { do { file_selected = true; loader->app = flipper_application_alloc(loader->storage, &hashtable_api_interface); + size_t start = furi_get_tick(); FURI_LOG_I(TAG, "FAP Loader is loading %s", furi_string_get_cstr(loader->fap_path)); @@ -99,6 +100,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { break; } + FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start)); FURI_LOG_I(TAG, "FAP Loader is staring app"); FuriThread* thread = flipper_application_spawn(loader->app, NULL); diff --git a/furi/core/thread.c b/furi/core/thread.c index 3ebca807..508146f6 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -103,6 +103,7 @@ static void furi_thread_body(void* context) { furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL); vTaskSetThreadLocalStoragePointer(NULL, 0, NULL); + thread->task_handle = NULL; vTaskDelete(NULL); furi_thread_catch(); } @@ -211,13 +212,8 @@ bool furi_thread_join(FuriThread* thread) { furi_check(furi_thread_get_current() != thread); - // Check if thread was started - if(thread->task_handle == NULL) { - return false; - } - // Wait for thread to stop - while(eTaskGetState(thread->task_handle) != eDeleted) { + while(thread->task_handle) { furi_delay_ms(10); } diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index b66e27d9..c70af067 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -57,8 +57,23 @@ static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) { return ELFSectionDict_get(elf->sections, name); } -static void elf_file_put_section(ELFFile* elf, const char* name, ELFSection* section) { - ELFSectionDict_set_at(elf->sections, strdup(name), *section); +static ELFSection* elf_file_get_or_put_section(ELFFile* elf, const char* name) { + ELFSection* section_p = elf_file_get_section(elf, name); + if(!section_p) { + ELFSectionDict_set_at( + elf->sections, + strdup(name), + (ELFSection){ + .data = NULL, + .sec_idx = 0, + .size = 0, + .rel_count = 0, + .rel_offset = 0, + }); + section_p = elf_file_get_section(elf, name); + } + + return section_p; } static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, FuriString* name) { @@ -320,12 +335,12 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3 return true; } -static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { +static bool elf_relocate(ELFFile* elf, ELFSection* s) { if(s->data) { Elf32_Rel rel; - size_t relEntries = h->sh_size / sizeof(rel); + size_t relEntries = s->rel_count; size_t relCount; - (void)storage_file_seek(elf->fd, h->sh_offset, true); + (void)storage_file_seek(elf->fd, s->rel_offset, true); FURI_LOG_D(TAG, " Offset Info Type Name"); int relocate_result = true; @@ -395,14 +410,6 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { return false; } -/**************************************************************************************************/ -/********************************************* MISC ***********************************************/ -/**************************************************************************************************/ - -static bool cstr_prefix(const char* prefix, const char* string) { - return strncmp(prefix, string, strlen(prefix)) == 0; -} - /**************************************************************************************************/ /************************************ Internal FAP interfaces *************************************/ /**************************************************************************************************/ @@ -445,6 +452,31 @@ static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) { section_header->sh_size; } +static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) { + if(section_header->sh_size == 0) { + FURI_LOG_D(TAG, "No data for section"); + return true; + } + + section->data = aligned_malloc(section_header->sh_size, section_header->sh_addralign); + section->size = section_header->sh_size; + + if(section_header->sh_type == SHT_NOBITS) { + // BSS section, no data to load + return true; + } + + if((!storage_file_seek(elf->fd, section_header->sh_offset, true)) || + (storage_file_read(elf->fd, section->data, section_header->sh_size) != + section_header->sh_size)) { + FURI_LOG_E(TAG, " seek/read fail"); + return false; + } + + FURI_LOG_D(TAG, "0x%X", section->data); + return true; +} + static SectionType elf_preload_section( ELFFile* elf, size_t section_idx, @@ -453,73 +485,63 @@ static SectionType elf_preload_section( FlipperApplicationManifest* manifest) { const char* name = furi_string_get_cstr(name_string); - const struct { - const char* prefix; - SectionType type; - } lookup_sections[] = { - {".text", SectionTypeData}, - {".rodata", SectionTypeData}, - {".data", SectionTypeData}, - {".bss", SectionTypeData}, - {".preinit_array", SectionTypeData}, - {".init_array", SectionTypeData}, - {".fini_array", SectionTypeData}, - {".rel.text", SectionTypeRelData}, - {".rel.rodata", SectionTypeRelData}, - {".rel.data", SectionTypeRelData}, - {".rel.preinit_array", SectionTypeRelData}, - {".rel.init_array", SectionTypeRelData}, - {".rel.fini_array", SectionTypeRelData}, - }; + // Load allocable section + if(section_header->sh_flags & SHF_ALLOC) { + ELFSection* section_p = elf_file_get_or_put_section(elf, name); + section_p->sec_idx = section_idx; - for(size_t i = 0; i < COUNT_OF(lookup_sections); i++) { - if(cstr_prefix(lookup_sections[i].prefix, name)) { - FURI_LOG_D(TAG, "Found section %s", lookup_sections[i].prefix); + if(section_header->sh_type == SHT_PREINIT_ARRAY) { + elf->preinit_array = section_p; + } else if(section_header->sh_type == SHT_INIT_ARRAY) { + elf->init_array = section_p; + } else if(section_header->sh_type == SHT_FINI_ARRAY) { + elf->fini_array = section_p; + } - if(lookup_sections[i].type == SectionTypeRelData) { - name = name + strlen(".rel"); - } - - ELFSection* section_p = elf_file_get_section(elf, name); - if(!section_p) { - ELFSection section = { - .data = NULL, - .sec_idx = 0, - .rel_sec_idx = 0, - .size = 0, - }; - - elf_file_put_section(elf, name, §ion); - section_p = elf_file_get_section(elf, name); - } - - if(lookup_sections[i].type == SectionTypeRelData) { - section_p->rel_sec_idx = section_idx; - } else { - section_p->sec_idx = section_idx; - } - - return lookup_sections[i].type; + if(!elf_load_section_data(elf, section_p, section_header)) { + FURI_LOG_E(TAG, "Error loading section '%s'", name); + return SectionTypeERROR; + } else { + return SectionTypeData; } } + // Load link info section + if(section_header->sh_flags & SHF_INFO_LINK) { + name = name + strlen(".rel"); + ELFSection* section_p = elf_file_get_or_put_section(elf, name); + section_p->rel_count = section_header->sh_size / sizeof(Elf32_Rel); + section_p->rel_offset = section_header->sh_offset; + return SectionTypeRelData; + } + + // Load symbol table if(strcmp(name, ".symtab") == 0) { FURI_LOG_D(TAG, "Found .symtab section"); elf->symbol_table = section_header->sh_offset; elf->symbol_count = section_header->sh_size / sizeof(Elf32_Sym); return SectionTypeSymTab; - } else if(strcmp(name, ".strtab") == 0) { + } + + // Load string table + if(strcmp(name, ".strtab") == 0) { FURI_LOG_D(TAG, "Found .strtab section"); elf->symbol_table_strings = section_header->sh_offset; return SectionTypeStrTab; - } else if(strcmp(name, ".fapmeta") == 0) { + } + + // Load manifest section + if(strcmp(name, ".fapmeta") == 0) { FURI_LOG_D(TAG, "Found .fapmeta section"); if(elf_load_metadata(elf, section_header, manifest)) { return SectionTypeManifest; } else { return SectionTypeERROR; } - } else if(strcmp(name, ".gnu_debuglink") == 0) { + } + + // Load debug link section + if(strcmp(name, ".gnu_debuglink") == 0) { FURI_LOG_D(TAG, "Found .gnu_debuglink section"); if(elf_load_debug_link(elf, section_header)) { return SectionTypeDebugLink; @@ -531,61 +553,17 @@ static SectionType elf_preload_section( return SectionTypeUnused; } -static bool elf_load_section_data(ELFFile* elf, ELFSection* section) { - Elf32_Shdr section_header; - if(section->sec_idx == 0) { - FURI_LOG_D(TAG, "Section is not present"); - return true; - } - - if(!elf_read_section_header(elf, section->sec_idx, §ion_header)) { - return false; - } - - if(section_header.sh_size == 0) { - FURI_LOG_D(TAG, "No data for section"); - return true; - } - - section->data = aligned_malloc(section_header.sh_size, section_header.sh_addralign); - section->size = section_header.sh_size; - - if(section_header.sh_type == SHT_NOBITS) { - /* section is empty (.bss?) */ - /* no need to memset - allocator already did that */ - return true; - } - - if((!storage_file_seek(elf->fd, section_header.sh_offset, true)) || - (storage_file_read(elf->fd, section->data, section_header.sh_size) != - section_header.sh_size)) { - FURI_LOG_E(TAG, " seek/read fail"); - return false; - } - - FURI_LOG_D(TAG, "0x%X", section->data); - return true; -} - static bool elf_relocate_section(ELFFile* elf, ELFSection* section) { - Elf32_Shdr section_header; - if(section->rel_sec_idx) { + if(section->rel_count) { FURI_LOG_D(TAG, "Relocating section"); - if(elf_read_section_header(elf, section->rel_sec_idx, §ion_header)) - return elf_relocate(elf, §ion_header, section); - else { - FURI_LOG_E(TAG, "Error reading section header"); - return false; - } + return elf_relocate(elf, section); } else { FURI_LOG_D(TAG, "No relocation index"); /* Not an error */ } return true; } -static void elf_file_call_section_list(ELFFile* elf, const char* name, bool reverse_order) { - ELFSection* section = elf_file_get_section(elf, name); - +static void elf_file_call_section_list(ELFSection* section, bool reverse_order) { if(section && section->size) { const uint32_t* start = section->data; const uint32_t* end = section->data + section->size; @@ -729,7 +707,6 @@ bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manif } furi_string_free(name); - FURI_LOG_D(TAG, "Load symbols done"); return IS_FLAGS_SET(loaded_sections, SectionTypeValid); } @@ -739,16 +716,6 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { ELFSectionDict_it_t it; AddressCache_init(elf->relocation_cache); - size_t start = furi_get_tick(); - - for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) { - ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it); - FURI_LOG_D(TAG, "Loading section '%s'", itref->key); - if(!elf_load_section_data(elf, &itref->value)) { - FURI_LOG_E(TAG, "Error loading section '%s'", itref->key); - status = ELFFileLoadStatusUnspecifiedError; - } - } if(status == ELFFileLoadStatusSuccess) { for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); @@ -777,14 +744,13 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { FURI_LOG_D(TAG, "Relocation cache size: %u", AddressCache_size(elf->relocation_cache)); FURI_LOG_D(TAG, "Trampoline cache size: %u", AddressCache_size(elf->trampoline_cache)); AddressCache_clear(elf->relocation_cache); - FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start)); return status; } void elf_file_pre_run(ELFFile* elf) { - elf_file_call_section_list(elf, ".preinit_array", false); - elf_file_call_section_list(elf, ".init_array", false); + elf_file_call_section_list(elf->preinit_array, false); + elf_file_call_section_list(elf->init_array, false); } int32_t elf_file_run(ELFFile* elf, void* args) { @@ -794,7 +760,7 @@ int32_t elf_file_run(ELFFile* elf, void* args) { } void elf_file_post_run(ELFFile* elf) { - elf_file_call_section_list(elf, ".fini_array", true); + elf_file_call_section_list(elf->fini_array, true); } const ElfApiInterface* elf_file_get_api_interface(ELFFile* elf_file) { diff --git a/lib/flipper_application/elf/elf_file_i.h b/lib/flipper_application/elf/elf_file_i.h index 1df075f0..9b38540b 100644 --- a/lib/flipper_application/elf/elf_file_i.h +++ b/lib/flipper_application/elf/elf_file_i.h @@ -16,8 +16,10 @@ typedef int32_t(entry_t)(void*); typedef struct { void* data; uint16_t sec_idx; - uint16_t rel_sec_idx; Elf32_Word size; + + size_t rel_count; + Elf32_Off rel_offset; } ELFSection; DICT_DEF2(ELFSectionDict, const char*, M_CSTR_OPLIST, ELFSection, M_POD_OPLIST) @@ -39,6 +41,10 @@ struct ELFFile { File* fd; const ElfApiInterface* api_interface; ELFDebugLinkInfo debug_link_info; + + ELFSection* preinit_array; + ELFSection* init_array; + ELFSection* fini_array; }; #ifdef __cplusplus From d10e16ca3c65288733723b330738ea3155734c94 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Sat, 8 Oct 2022 03:27:32 +1000 Subject: [PATCH 25/49] Snake game: nokia 6110-like sound (#1844) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Snake game: nokia 6110-like sound * Snake game: blocking sound notifications * SnakeGame: flush notification queue with backlight enforce block Co-authored-by: あく --- applications/plugins/snake_game/snake_game.c | 47 +++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/applications/plugins/snake_game/snake_game.c b/applications/plugins/snake_game/snake_game.c index b7aabb17..0b665a94 100644 --- a/applications/plugins/snake_game/snake_game.c +++ b/applications/plugins/snake_game/snake_game.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include typedef struct { // +-----x @@ -59,6 +61,35 @@ typedef struct { InputEvent input; } SnakeEvent; +const NotificationSequence sequence_fail = { + &message_vibro_on, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_eat = { + &message_note_c7, + &message_delay_50, + &message_sound_off, + NULL, +}; + static void snake_game_render_callback(Canvas* const canvas, void* ctx) { const SnakeState* snake_state = acquire_mutex((ValueMutex*)ctx, 25); if(snake_state == NULL) { @@ -230,7 +261,8 @@ static void snake_game_move_snake(SnakeState* const snake_state, Point const nex snake_state->points[0] = next_step; } -static void snake_game_process_game_step(SnakeState* const snake_state) { +static void + snake_game_process_game_step(SnakeState* const snake_state, NotificationApp* notification) { if(snake_state->state == GameStateGameOver) { return; } @@ -249,6 +281,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { return; } else if(snake_state->state == GameStateLastChance) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } else { @@ -260,6 +293,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { crush = snake_game_collision_with_tail(snake_state, next_step); if(crush) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } @@ -268,6 +302,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { snake_state->len++; if(snake_state->len >= MAX_SNAKE_LEN) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } @@ -276,6 +311,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { if(eatFruit) { snake_state->fruit = snake_game_get_new_fruit(snake_state); + notification_message(notification, &sequence_eat); } } @@ -306,6 +342,9 @@ int32_t snake_game_app(void* p) { // Open GUI and register view_port Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + notification_message_block(notification, &sequence_display_backlight_enforce_on); SnakeEvent event; for(bool processing = true; processing;) { @@ -341,7 +380,7 @@ int32_t snake_game_app(void* p) { } } } else if(event.type == EventTypeTick) { - snake_game_process_game_step(snake_state); + snake_game_process_game_step(snake_state, notification); } } else { // event timeout @@ -351,10 +390,14 @@ int32_t snake_game_app(void* p) { release_mutex(&state_mutex, snake_state); } + // Wait for all notifications to be played and return backlight to normal state + notification_message_block(notification, &sequence_display_backlight_enforce_auto); + furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); view_port_free(view_port); furi_message_queue_free(event_queue); delete_mutex(&state_mutex); From 88ca267466f8408d5b50492b4fb72bb938d936f1 Mon Sep 17 00:00:00 2001 From: Yukai Li Date: Sat, 8 Oct 2022 04:13:26 -0600 Subject: [PATCH 26/49] music_player: Return to browser instead of exiting on back button (#1846) * music_player: Return to browser instead of exiting on back button * music_player: Fix number and dots extraction --- applications/plugins/music_player/music_player.c | 16 ++++++++++++---- .../plugins/music_player/music_player_worker.c | 6 ++++++ .../plugins/music_player/music_player_worker.h | 2 ++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/applications/plugins/music_player/music_player.c b/applications/plugins/music_player/music_player.c index 6d3c4483..192500c2 100644 --- a/applications/plugins/music_player/music_player.c +++ b/applications/plugins/music_player/music_player.c @@ -248,12 +248,16 @@ static void music_player_worker_callback( view_port_update(music_player->view_port); } +void music_player_clear(MusicPlayer* instance) { + memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + music_player_worker_clear(instance->worker); +} + MusicPlayer* music_player_alloc() { MusicPlayer* instance = malloc(sizeof(MusicPlayer)); instance->model = malloc(sizeof(MusicPlayerModel)); - memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); - memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); instance->model->volume = 3; instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); @@ -265,6 +269,8 @@ MusicPlayer* music_player_alloc() { instance->worker, MUSIC_PLAYER_VOLUMES[instance->model->volume]); music_player_worker_set_callback(instance->worker, music_player_worker_callback, instance); + music_player_clear(instance); + instance->view_port = view_port_alloc(); view_port_draw_callback_set(instance->view_port, render_callback, instance); view_port_input_callback_set(instance->view_port, input_callback, instance); @@ -299,7 +305,7 @@ int32_t music_player_app(void* p) { do { if(p && strlen(p)) { - furi_string_cat(file_path, (const char*)p); + furi_string_set(file_path, (const char*)p); } else { furi_string_set(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); @@ -350,7 +356,9 @@ int32_t music_player_app(void* p) { } music_player_worker_stop(music_player->worker); - } while(0); + if(p && strlen(p)) break; // Exit instead of going to browser if launched with arg + music_player_clear(music_player); + } while(1); furi_string_free(file_path); music_player_free(music_player); diff --git a/applications/plugins/music_player/music_player_worker.c b/applications/plugins/music_player/music_player_worker.c index 99f0ce1e..3f1ac62f 100644 --- a/applications/plugins/music_player/music_player_worker.c +++ b/applications/plugins/music_player/music_player_worker.c @@ -108,6 +108,10 @@ MusicPlayerWorker* music_player_worker_alloc() { return instance; } +void music_player_worker_clear(MusicPlayerWorker* instance) { + NoteBlockArray_reset(instance->notes); +} + void music_player_worker_free(MusicPlayerWorker* instance) { furi_assert(instance); furi_thread_free(instance->thread); @@ -129,6 +133,7 @@ static bool is_space(const char c) { static size_t extract_number(const char* string, uint32_t* number) { size_t ret = 0; + *number = 0; while(is_digit(*string)) { *number *= 10; *number += (*string - '0'); @@ -140,6 +145,7 @@ static size_t extract_number(const char* string, uint32_t* number) { static size_t extract_dots(const char* string, uint32_t* number) { size_t ret = 0; + *number = 0; while(*string == '.') { *number += 1; string++; diff --git a/applications/plugins/music_player/music_player_worker.h b/applications/plugins/music_player/music_player_worker.h index 3aa99ea3..00320b11 100644 --- a/applications/plugins/music_player/music_player_worker.h +++ b/applications/plugins/music_player/music_player_worker.h @@ -14,6 +14,8 @@ typedef struct MusicPlayerWorker MusicPlayerWorker; MusicPlayerWorker* music_player_worker_alloc(); +void music_player_worker_clear(MusicPlayerWorker* instance); + void music_player_worker_free(MusicPlayerWorker* instance); bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path); From c13929330e8db619a28024479ffd8d408bdb9d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sat, 8 Oct 2022 19:57:53 +0900 Subject: [PATCH 27/49] Gui: fix memory leak in file browser module (#1848) --- applications/services/gui/modules/file_browser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index f15b09f6..762fe87d 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -57,7 +57,6 @@ static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) { furi_string_set(obj->path, src->path); furi_string_set(obj->display_name, src->display_name); if(src->custom_icon_data) { - obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE); memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE); } else { obj->custom_icon_data = NULL; @@ -379,6 +378,9 @@ static void }); furi_string_free(item.display_name); furi_string_free(item.path); + if(item.custom_icon_data) { + free(item.custom_icon_data); + } } else { with_view_model( browser->view, (FileBrowserModel * model) { From 981f7ff8b027fed55dfd92a0628e8bc7bd6b92f9 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Sun, 9 Oct 2022 01:51:51 +1000 Subject: [PATCH 28/49] Elf loader: do not load .ARM.* sections (#1850) * Elf loader: do not load .ARM sections * Fix section name --- lib/flipper_application/elf/elf_file.c | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index c70af067..3fe57162 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -452,6 +452,10 @@ static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) { section_header->sh_size; } +static bool str_prefix(const char* str, const char* prefix) { + return strncmp(prefix, str, strlen(prefix)) == 0; +} + static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) { if(section_header->sh_size == 0) { FURI_LOG_D(TAG, "No data for section"); @@ -485,6 +489,43 @@ static SectionType elf_preload_section( FlipperApplicationManifest* manifest) { const char* name = furi_string_get_cstr(name_string); +#ifdef ELF_DEBUG_LOG + // log section name, type and flags + FuriString* flags_string = furi_string_alloc(); + if(section_header->sh_flags & SHF_WRITE) furi_string_cat(flags_string, "W"); + if(section_header->sh_flags & SHF_ALLOC) furi_string_cat(flags_string, "A"); + if(section_header->sh_flags & SHF_EXECINSTR) furi_string_cat(flags_string, "X"); + if(section_header->sh_flags & SHF_MERGE) furi_string_cat(flags_string, "M"); + if(section_header->sh_flags & SHF_STRINGS) furi_string_cat(flags_string, "S"); + if(section_header->sh_flags & SHF_INFO_LINK) furi_string_cat(flags_string, "I"); + if(section_header->sh_flags & SHF_LINK_ORDER) furi_string_cat(flags_string, "L"); + if(section_header->sh_flags & SHF_OS_NONCONFORMING) furi_string_cat(flags_string, "O"); + if(section_header->sh_flags & SHF_GROUP) furi_string_cat(flags_string, "G"); + if(section_header->sh_flags & SHF_TLS) furi_string_cat(flags_string, "T"); + if(section_header->sh_flags & SHF_COMPRESSED) furi_string_cat(flags_string, "T"); + if(section_header->sh_flags & SHF_MASKOS) furi_string_cat(flags_string, "o"); + if(section_header->sh_flags & SHF_MASKPROC) furi_string_cat(flags_string, "p"); + if(section_header->sh_flags & SHF_ORDERED) furi_string_cat(flags_string, "R"); + if(section_header->sh_flags & SHF_EXCLUDE) furi_string_cat(flags_string, "E"); + + FURI_LOG_I( + TAG, + "Section %s: type: %ld, flags: %s", + name, + section_header->sh_type, + furi_string_get_cstr(flags_string)); + furi_string_free(flags_string); +#endif + + // ignore .ARM and .rel.ARM sections + // TODO: how to do it not by name? + // .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER + // .rel.ARM: type 0x9, flags SHT_REL + if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.")) { + FURI_LOG_D(TAG, "Ignoring ARM section"); + return SectionTypeUnused; + } + // Load allocable section if(section_header->sh_flags & SHF_ALLOC) { ELFSection* section_p = elf_file_get_or_put_section(elf, name); From 31c0346adc19f7bf7584c991fc4ba2722b37559f Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Sun, 9 Oct 2022 03:38:29 +1000 Subject: [PATCH 29/49] [FL-976] Removing lambdas (#1849) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removing lambdas... * Wake the fk up, Gordon! We have a citadel to burn! * Here comes the Nihilanth * Lambda documentation Co-authored-by: あく --- .../debug/bt_debug_app/views/bt_test.c | 87 +++++---- .../debug/display_test/view_display_test.c | 13 +- .../views/lfrfid_debug_view_tune.c | 71 +++---- applications/debug/uart_echo/uart_echo.c | 29 +-- .../main/archive/helpers/archive_browser.c | 165 ++++++++-------- .../main/archive/views/archive_browser_view.c | 49 ++--- .../main/bad_usb/views/bad_usb_view.c | 24 ++- applications/main/gpio/views/gpio_test.c | 32 ++-- applications/main/gpio/views/gpio_usb_uart.c | 16 +- .../main/lfrfid/views/lfrfid_view_read.c | 31 ++- applications/main/nfc/views/detect_reader.c | 34 ++-- applications/main/nfc/views/dict_attack.c | 98 +++++----- applications/main/subghz/views/receiver.c | 126 +++++++------ .../subghz/views/subghz_frequency_analyzer.c | 34 ++-- .../main/subghz/views/subghz_read_raw.c | 146 +++++++++------ .../main/subghz/views/subghz_test_carrier.c | 26 +-- .../main/subghz/views/subghz_test_packet.c | 33 ++-- .../main/subghz/views/subghz_test_static.c | 18 +- applications/main/subghz/views/transmitter.c | 40 ++-- applications/main/u2f/views/u2f_view.c | 13 +- .../bt_hid_app/views/bt_hid_keyboard.c | 13 +- .../plugins/bt_hid_app/views/bt_hid_keynote.c | 13 +- .../plugins/bt_hid_app/views/bt_hid_media.c | 21 ++- .../plugins/bt_hid_app/views/bt_hid_mouse.c | 13 +- .../signal_generator/views/signal_gen_pwm.c | 32 ++-- .../desktop/views/desktop_view_debug.c | 22 +-- .../desktop/views/desktop_view_lock_menu.c | 35 ++-- .../services/gui/modules/button_menu.c | 69 ++++--- .../services/gui/modules/button_panel.c | 177 ++++++++++-------- .../services/gui/modules/byte_input.c | 57 +++--- applications/services/gui/modules/dialog_ex.c | 64 ++++--- .../services/gui/modules/file_browser.c | 95 +++++----- applications/services/gui/modules/menu.c | 78 +++++--- applications/services/gui/modules/popup.c | 40 ++-- applications/services/gui/modules/submenu.c | 67 ++++--- applications/services/gui/modules/text_box.c | 55 +++--- .../services/gui/modules/text_input.c | 69 +++---- .../services/gui/modules/variable_item_list.c | 89 +++++---- applications/services/gui/modules/widget.c | 34 ++-- applications/services/gui/view.h | 22 +-- .../power/power_service/views/power_off.c | 10 +- .../power_settings_app/views/battery_info.c | 8 +- .../system/updater/views/updater_main.c | 32 ++-- 43 files changed, 1193 insertions(+), 1007 deletions(-) diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index 9f2830d3..9588b667 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -154,7 +154,9 @@ static bool bt_test_input_callback(InputEvent* event, void* context) { void bt_test_process_up(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { uint8_t params_on_screen = 3; if(model->position > 0) { model->position--; @@ -168,13 +170,15 @@ void bt_test_process_up(BtTest* bt_test) { model->window_position = model->position - (params_on_screen - 1); } } - return true; - }); + }, + true); } void bt_test_process_down(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { uint8_t params_on_screen = 3; if(model->position < (BtTestParamArray_size(model->params) - 1)) { model->position++; @@ -187,8 +191,8 @@ void bt_test_process_down(BtTest* bt_test) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } BtTestParam* bt_test_get_selected_param(BtTestModel* model) { @@ -213,7 +217,9 @@ BtTestParam* bt_test_get_selected_param(BtTestModel* model) { void bt_test_process_left(BtTest* bt_test) { BtTestParam* param; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = bt_test_get_selected_param(model); if(param->current_value_index > 0) { param->current_value_index--; @@ -225,8 +231,8 @@ void bt_test_process_left(BtTest* bt_test) { model->packets_num_tx = 0; } } - return true; - }); + }, + true); if(param->change_callback) { param->change_callback(param); } @@ -235,7 +241,9 @@ void bt_test_process_left(BtTest* bt_test) { void bt_test_process_right(BtTest* bt_test) { BtTestParam* param; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = bt_test_get_selected_param(model); if(param->current_value_index < (param->values_count - 1)) { param->current_value_index++; @@ -247,8 +255,8 @@ void bt_test_process_right(BtTest* bt_test) { model->packets_num_tx = 0; } } - return true; - }); + }, + true); if(param->change_callback) { param->change_callback(param); } @@ -257,7 +265,9 @@ void bt_test_process_right(BtTest* bt_test) { void bt_test_process_ok(BtTest* bt_test) { BtTestState state; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { if(model->state == BtTestStateStarted) { model->state = BtTestStateStopped; model->message = BT_TEST_START_MESSAGE; @@ -269,8 +279,8 @@ void bt_test_process_ok(BtTest* bt_test) { model->message = BT_TEST_STOP_MESSAGE; } state = model->state; - return true; - }); + }, + true); if(bt_test->change_state_callback) { bt_test->change_state_callback(state, bt_test->context); } @@ -278,13 +288,15 @@ void bt_test_process_ok(BtTest* bt_test) { void bt_test_process_back(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { model->state = BtTestStateStopped; model->rssi = 0.0f; model->packets_num_rx = 0; model->packets_num_tx = 0; - return false; - }); + }, + false); if(bt_test->back_callback) { bt_test->back_callback(bt_test->context); } @@ -299,7 +311,9 @@ BtTest* bt_test_alloc() { view_set_input_callback(bt_test->view, bt_test_input_callback); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { model->state = BtTestStateStopped; model->message = "Ok - Start"; BtTestParamArray_init(model->params); @@ -308,8 +322,8 @@ BtTest* bt_test_alloc() { model->rssi = 0.0f; model->packets_num_tx = 0; model->packets_num_rx = 0; - return true; - }); + }, + true); return bt_test; } @@ -318,15 +332,17 @@ void bt_test_free(BtTest* bt_test) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { BtTestParamArray_it_t it; for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); BtTestParamArray_next(it)) { furi_string_free(BtTestParamArray_ref(it)->current_value_text); } BtTestParamArray_clear(model->params); - return false; - }); + }, + false); view_free(bt_test->view); free(bt_test); } @@ -347,7 +363,9 @@ BtTestParam* bt_test_param_add( furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = BtTestParamArray_push_new(model->params); param->label = label; param->values_count = values_count; @@ -355,8 +373,8 @@ BtTestParam* bt_test_param_add( param->context = context; param->current_value_index = 0; param->current_value_text = furi_string_alloc(); - return true; - }); + }, + true); return param; } @@ -364,28 +382,19 @@ BtTestParam* bt_test_param_add( void bt_test_set_rssi(BtTest* bt_test, float rssi) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->rssi = rssi; - return true; - }); + bt_test->view, BtTestModel * model, { model->rssi = rssi; }, true); } void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->packets_num_tx = packets_num; - return true; - }); + bt_test->view, BtTestModel * model, { model->packets_num_tx = packets_num; }, true); } void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->packets_num_rx = packets_num; - return true; - }); + bt_test->view, BtTestModel * model, { model->packets_num_rx = packets_num; }, true); } void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback) { diff --git a/applications/debug/display_test/view_display_test.c b/applications/debug/display_test/view_display_test.c index f00fe009..b47c74c6 100644 --- a/applications/debug/display_test/view_display_test.c +++ b/applications/debug/display_test/view_display_test.c @@ -110,7 +110,9 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { bool consumed = false; if(event->type == InputTypeShort || event->type == InputTypeRepeat) { with_view_model( - instance->view, (ViewDisplayTestModel * model) { + instance->view, + ViewDisplayTestModel * model, + { if(event->key == InputKeyLeft && model->test > 0) { model->test--; consumed = true; @@ -129,8 +131,8 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { model->flip_flop = !model->flip_flop; consumed = true; } - return consumed; - }); + }, + consumed); } return consumed; @@ -149,10 +151,7 @@ static void view_display_test_exit(void* context) { static void view_display_test_timer_callback(void* context) { ViewDisplayTest* instance = context; with_view_model( - instance->view, (ViewDisplayTestModel * model) { - model->counter++; - return true; - }); + instance->view, ViewDisplayTestModel * model, { model->counter++; }, true); } ViewDisplayTest* view_display_test_alloc() { diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c index 38fe3603..fd221c4e 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -52,23 +52,29 @@ static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) { static void lfrfid_debug_view_tune_button_up(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos > 0) model->pos--; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_down(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos < 1) model->pos++; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos == 0) { if(model->fine) { model->ARR -= 1; @@ -84,13 +90,15 @@ static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) { } model->dirty = true; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos == 0) { if(model->fine) { model->ARR += 1; @@ -106,16 +114,13 @@ static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) { } model->dirty = true; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_ok(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - model->fine = !model->fine; - return true; - }); + tune_view->view, LfRfidTuneViewModel * model, { model->fine = !model->fine; }, true); } static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* context) { @@ -158,14 +163,16 @@ LfRfidTuneView* lfrfid_debug_view_tune_alloc() { view_allocate_model(tune_view->view, ViewModelTypeLocking, sizeof(LfRfidTuneViewModel)); with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { model->dirty = true; model->fine = false; model->ARR = 511; model->CCR = 255; model->pos = 0; - return true; - }); + }, + true); view_set_draw_callback(tune_view->view, lfrfid_debug_view_tune_draw_callback); view_set_input_callback(tune_view->view, lfrfid_debug_view_tune_input_callback); @@ -184,24 +191,28 @@ View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view) { void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { model->dirty = true; model->fine = false; model->ARR = 511; model->CCR = 255; model->pos = 0; - return true; - }); + }, + true); } bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) { bool result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { result = model->dirty; model->dirty = false; - return false; - }); + }, + false); return result; } @@ -209,10 +220,7 @@ bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) { uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) { uint32_t result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - result = model->ARR; - return false; - }); + tune_view->view, LfRfidTuneViewModel * model, { result = model->ARR; }, false); return result; } @@ -220,10 +228,7 @@ uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) { uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view) { uint32_t result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - result = model->CCR; - return false; - }); + tune_view->view, LfRfidTuneViewModel * model, { result = model->CCR; }, false); return result; } diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 122862dd..701e5325 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -159,21 +159,20 @@ static int32_t uart_echo_worker(void* context) { if(length > 0) { furi_hal_uart_tx(FuriHalUartIdUSART1, data, length); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < length; i++) { uart_echo_push_to_list(model, data[i]); } - return false; - }); + }, + false); } } while(length > 0); notification_message(app->notification, &sequence_notification); with_view_model( - app->view, (UartDumpModel * model) { - UNUSED(model); - return true; - }); + app->view, UartDumpModel * model, { UNUSED(model); }, true); } } @@ -200,15 +199,17 @@ static UartEchoApp* uart_echo_app_alloc() { view_set_input_callback(app->view, uart_echo_view_input_callback); view_allocate_model(app->view, ViewModelTypeLocking, sizeof(UartDumpModel)); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < LINES_ON_SCREEN; i++) { model->line = 0; model->escape = false; model->list[i] = malloc(sizeof(ListElement)); model->list[i]->text = furi_string_alloc(); } - return true; - }); + }, + true); view_set_previous_callback(app->view, uart_echo_exit); view_dispatcher_add_view(app->view_dispatcher, 0, app->view); @@ -242,13 +243,15 @@ static void uart_echo_app_free(UartEchoApp* app) { view_dispatcher_remove_view(app->view_dispatcher, 0); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < LINES_ON_SCREEN; i++) { furi_string_free(model->list[i]->text); free(model->list[i]); } - return true; - }); + }, + true); view_free(app->view); view_dispatcher_free(app->view_dispatcher); diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index f6603070..9689454b 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -21,7 +21,9 @@ static void archive_switch_tab(browser, browser->last_tab_switch_dir); } else if(!furi_string_start_with_str(browser->path, "/app:")) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); model->item_cnt = item_cnt; model->item_idx = (file_idx > 0) ? file_idx : 0; @@ -31,8 +33,8 @@ static void model->list_offset = 0; model->list_loading = true; model->folder_loading = false; - return false; - }); + }, + false); archive_update_offset(browser); file_browser_worker_load(browser->worker, load_offset, FILE_LIST_BUF_LEN); @@ -44,11 +46,13 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) { ArchiveBrowserView* browser = (ArchiveBrowserView*)context; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); model->array_offset = list_load_offset; - return false; - }); + }, + false); } static void @@ -60,10 +64,7 @@ static void archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->list_loading = false; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true); } } @@ -72,10 +73,7 @@ static void archive_long_load_cb(void* context) { ArchiveBrowserView* browser = (ArchiveBrowserView*)context; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->folder_loading = true; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->folder_loading = true; }, true); } static void archive_file_browser_set_path( @@ -113,7 +111,9 @@ void archive_update_offset(ArchiveBrowserView* browser) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt; if((model->item_cnt > 3u) && (model->item_idx >= ((int32_t)model->item_cnt - 1))) { @@ -125,9 +125,8 @@ void archive_update_offset(ArchiveBrowserView* browser) { model->list_offset = CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0); } - - return true; - }); + }, + true); } void archive_update_focus(ArchiveBrowserView* browser, const char* target) { @@ -140,7 +139,9 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) { archive_switch_tab(browser, TAB_RIGHT); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { uint16_t idx = 0; while(idx < files_array_size(model->files)) { ArchiveFile_t* current = files_array_get(model->files, idx); @@ -150,8 +151,8 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) { } ++idx; } - return false; - }); + }, + false); archive_update_offset(browser); } @@ -162,10 +163,10 @@ size_t archive_file_get_array_size(ArchiveBrowserView* browser) { uint16_t size = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - size = files_array_size(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { size = files_array_size(model->files); }, + false); return size; } @@ -173,11 +174,13 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { model->item_cnt = count; model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); - return false; - }); + }, + false); archive_update_offset(browser); } @@ -186,7 +189,9 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { uint32_t items_cnt = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_remove_v( model->files, model->item_idx - model->array_offset, @@ -194,8 +199,8 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { model->item_cnt--; model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); items_cnt = model->item_cnt; - return false; - }); + }, + false); if((items_cnt == 0) && (archive_is_home(browser))) { archive_switch_tab(browser, TAB_RIGHT); @@ -208,7 +213,9 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { ArchiveFile_t temp; size_t array_size = files_array_size(model->files) - 1; uint8_t swap_idx = CLAMP((size_t)(model->item_idx + dir), array_size, 0u); @@ -226,18 +233,18 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { } else { files_array_swap_at(model->files, model->item_idx, swap_idx); } - return false; - }); + }, + false); } void archive_file_array_rm_all(ArchiveBrowserView* browser) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_reset(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); }, + false); } void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { @@ -246,7 +253,9 @@ void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { int32_t offset_new = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(model->item_cnt > FILE_LIST_BUF_LEN) { if(dir < 0) { offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 3; @@ -262,8 +271,8 @@ void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { offset_new = 0; } } - return false; - }); + }, + false); file_browser_worker_load(browser->worker, offset_new, FILE_LIST_BUF_LEN); } @@ -273,12 +282,14 @@ ArchiveFile_t* archive_get_current_file(ArchiveBrowserView* browser) { ArchiveFile_t* selected = NULL; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { selected = files_array_size(model->files) ? files_array_get(model->files, model->item_idx - model->array_offset) : NULL; - return false; - }); + }, + false); return selected; } @@ -288,11 +299,13 @@ ArchiveFile_t* archive_get_file_at(ArchiveBrowserView* browser, size_t idx) { ArchiveFile_t* selected = NULL; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0u); selected = files_array_size(model->files) ? files_array_get(model->files, idx) : NULL; - return false; - }); + }, + false); return selected; } @@ -301,10 +314,7 @@ ArchiveTabEnum archive_get_tab(ArchiveBrowserView* browser) { ArchiveTabEnum tab_id = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - tab_id = model->tab_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { tab_id = model->tab_idx; }, false); return tab_id; } @@ -328,10 +338,7 @@ void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->tab_idx = tab; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { model->tab_idx = tab; }, false); } void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { @@ -344,11 +351,13 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { archive_set_file_type(&item, name, false, true); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_push_back(model->files, item); model->item_cnt = files_array_size(model->files); - return false; - }); + }, + false); ArchiveFile_t_clear(&item); } @@ -379,17 +388,19 @@ void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const ch } } with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_push_back(model->files, item); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_push_back(model->files, item); }, + false); ArchiveFile_t_clear(&item); } void archive_show_file_menu(ArchiveBrowserView* browser, bool show) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(show) { if(archive_is_item_in_array(model, model->item_idx)) { model->menu = true; @@ -403,19 +414,15 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) { model->menu = false; model->menu_idx = 0; } - - return true; - }); + }, + true); } void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->move_fav = active; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->move_fav = active; }, true); } static bool archive_is_dir_exists(FuriString* path) { @@ -476,11 +483,13 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { archive_switch_tab(browser, key); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { model->item_idx = 0; model->array_offset = 0; - return false; - }); + }, + false); archive_get_items(browser, furi_string_get_cstr(browser->path)); archive_update_offset(browser); } @@ -493,10 +502,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, FuriString* path) { int32_t idx_temp = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx_temp = model->item_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { idx_temp = model->item_idx; }, false); furi_string_set(browser->path, path); file_browser_worker_folder_enter(browser->worker, path, idx_temp); @@ -514,9 +520,6 @@ void archive_refresh_dir(ArchiveBrowserView* browser) { int32_t idx_temp = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx_temp = model->item_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { idx_temp = model->item_idx; }, false); file_browser_worker_folder_refresh(browser->worker, idx_temp); } diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index f13094a1..a2e219b9 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -263,33 +263,37 @@ static bool archive_view_input(InputEvent* event, void* context) { bool in_menu; bool move_fav_mode; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { in_menu = model->menu; move_fav_mode = model->move_fav; - return false; - }); + }, + false); if(in_menu) { if(event->type == InputTypeShort) { if(event->key == InputKeyUp || event->key == InputKeyDown) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(event->key == InputKeyUp) { model->menu_idx = ((model->menu_idx - 1) + MENU_ITEMS) % MENU_ITEMS; } else if(event->key == InputKeyDown) { model->menu_idx = (model->menu_idx + 1) % MENU_ITEMS; } - return true; - }); + }, + true); } if(event->key == InputKeyOk) { uint8_t idx; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx = model->menu_idx; - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { idx = model->menu_idx; }, + false); browser->callback(file_menu_actions[idx], browser->context); } else if(event->key == InputKeyBack) { browser->callback(ArchiveBrowserEventFileMenuClose, browser->context); @@ -313,7 +317,9 @@ static bool archive_view_input(InputEvent* event, void* context) { if((event->key == InputKeyUp || event->key == InputKeyDown) && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(event->key == InputKeyUp) { model->item_idx = ((model->item_idx - 1) + model->item_cnt) % model->item_cnt; @@ -334,9 +340,8 @@ static bool archive_view_input(InputEvent* event, void* context) { browser->callback(ArchiveBrowserEventFavMoveDown, browser->context); } } - - return true; - }); + }, + true); archive_update_offset(browser); } @@ -384,11 +389,13 @@ ArchiveBrowserView* browser_alloc() { browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT)); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_init(model->files); model->tab_idx = TAB_DEFAULT; - return true; - }); + }, + true); return browser; } @@ -401,10 +408,10 @@ void browser_free(ArchiveBrowserView* browser) { } with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_clear(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_clear(model->files); }, + false); furi_string_free(browser->path); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index b6310193..db10d01e 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -145,29 +145,33 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c furi_assert(bad_usb); furi_assert(callback); with_view_model( - bad_usb->view, (BadUsbModel * model) { + bad_usb->view, + BadUsbModel * model, + { UNUSED(model); bad_usb->callback = callback; bad_usb->context = context; - return true; - }); + }, + true); } void bad_usb_set_file_name(BadUsb* bad_usb, const char* name) { furi_assert(name); with_view_model( - bad_usb->view, (BadUsbModel * model) { - strlcpy(model->file_name, name, MAX_NAME_LEN); - return true; - }); + bad_usb->view, + BadUsbModel * model, + { strlcpy(model->file_name, name, MAX_NAME_LEN); }, + true); } void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) { furi_assert(st); with_view_model( - bad_usb->view, (BadUsbModel * model) { + bad_usb->view, + BadUsbModel * model, + { memcpy(&(model->state), st, sizeof(BadUsbState)); model->anim_frame ^= 1; - return true; - }); + }, + true); } diff --git a/applications/main/gpio/views/gpio_test.c b/applications/main/gpio/views/gpio_test.c index 89c09f86..69dc0f67 100644 --- a/applications/main/gpio/views/gpio_test.c +++ b/applications/main/gpio/views/gpio_test.c @@ -48,23 +48,27 @@ static bool gpio_test_input_callback(InputEvent* event, void* context) { static bool gpio_test_process_left(GpioTest* gpio_test) { with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(model->pin_idx) { model->pin_idx--; } - return true; - }); + }, + true); return true; } static bool gpio_test_process_right(GpioTest* gpio_test) { with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(model->pin_idx < GPIO_ITEM_COUNT) { model->pin_idx++; } - return true; - }); + }, + true); return true; } @@ -72,7 +76,9 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) { bool consumed = false; with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(event->type == InputTypePress) { if(model->pin_idx < GPIO_ITEM_COUNT) { gpio_item_set_pin(model->pin_idx, true); @@ -89,8 +95,8 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) { consumed = true; } gpio_test->callback(event->type, gpio_test->context); - return true; - }); + }, + true); return consumed; } @@ -122,10 +128,12 @@ void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback, furi_assert(gpio_test); furi_assert(callback); with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { UNUSED(model); gpio_test->callback = callback; gpio_test->context = context; - return false; - }); + }, + false); } diff --git a/applications/main/gpio/views/gpio_usb_uart.c b/applications/main/gpio/views/gpio_usb_uart.c index d190ecab..c7406d29 100644 --- a/applications/main/gpio/views/gpio_usb_uart.c +++ b/applications/main/gpio/views/gpio_usb_uart.c @@ -129,12 +129,14 @@ void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callb furi_assert(callback); with_view_model( - usb_uart->view, (GpioUsbUartModel * model) { + usb_uart->view, + GpioUsbUartModel * model, + { UNUSED(model); usb_uart->callback = callback; usb_uart->context = context; - return false; - }); + }, + false); } void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUartState* st) { @@ -143,7 +145,9 @@ void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUa furi_assert(st); with_view_model( - instance->view, (GpioUsbUartModel * model) { + instance->view, + GpioUsbUartModel * model, + { model->baudrate = st->baudrate_cur; model->vcp_port = cfg->vcp_ch; model->tx_pin = (cfg->uart_ch == 0) ? (13) : (15); @@ -152,6 +156,6 @@ void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUa model->rx_active = (model->rx_cnt != st->rx_cnt); model->tx_cnt = st->tx_cnt; model->rx_cnt = st->rx_cnt; - return true; - }); + }, + true); } diff --git a/applications/main/lfrfid/views/lfrfid_view_read.c b/applications/main/lfrfid/views/lfrfid_view_read.c index 66caf8df..0d4db617 100644 --- a/applications/main/lfrfid/views/lfrfid_view_read.c +++ b/applications/main/lfrfid/views/lfrfid_view_read.c @@ -56,19 +56,13 @@ static void lfrfid_view_read_draw_callback(Canvas* canvas, void* _model) { void lfrfid_view_read_enter(void* context) { LfRfidReadView* read_view = context; with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_start(model->icon); - return true; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_start(model->icon); }, true); } void lfrfid_view_read_exit(void* context) { LfRfidReadView* read_view = context; with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_stop(model->icon); - return false; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_stop(model->icon); }, false); } LfRfidReadView* lfrfid_view_read_alloc() { @@ -78,11 +72,13 @@ LfRfidReadView* lfrfid_view_read_alloc() { view_allocate_model(read_view->view, ViewModelTypeLocking, sizeof(LfRfidReadViewModel)); with_view_model( - read_view->view, (LfRfidReadViewModel * model) { + read_view->view, + LfRfidReadViewModel * model, + { model->icon = icon_animation_alloc(&A_Round_loader_8x8); view_tie_icon_animation(read_view->view, model->icon); - return false; - }); + }, + false); view_set_draw_callback(read_view->view, lfrfid_view_read_draw_callback); view_set_enter_callback(read_view->view, lfrfid_view_read_enter); @@ -93,10 +89,7 @@ LfRfidReadView* lfrfid_view_read_alloc() { void lfrfid_view_read_free(LfRfidReadView* read_view) { with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_free(model->icon); - return false; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_free(model->icon); }, false); view_free(read_view->view); free(read_view); @@ -108,10 +101,12 @@ View* lfrfid_view_read_get_view(LfRfidReadView* read_view) { void lfrfid_view_read_set_read_mode(LfRfidReadView* read_view, LfRfidReadViewMode mode) { with_view_model( - read_view->view, (LfRfidReadViewModel * model) { + read_view->view, + LfRfidReadViewModel * model, + { icon_animation_stop(model->icon); icon_animation_start(model->icon); model->read_mode = mode; - return true; - }); + }, + true); } diff --git a/applications/main/nfc/views/detect_reader.c b/applications/main/nfc/views/detect_reader.c index 9a077043..2dbb4338 100644 --- a/applications/main/nfc/views/detect_reader.c +++ b/applications/main/nfc/views/detect_reader.c @@ -64,10 +64,7 @@ static bool detect_reader_input_callback(InputEvent* event, void* context) { uint8_t nonces = 0; with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - nonces = model->nonces; - return false; - }); + detect_reader->view, DetectReaderViewModel * model, { nonces = model->nonces; }, false); if(event->type == InputTypeShort) { if(event->key == InputKeyOk) { @@ -103,12 +100,14 @@ void detect_reader_reset(DetectReader* detect_reader) { furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces = 0; model->nonces_max = 0; model->state = DetectReaderStateStart; - return false; - }); + }, + false); } View* detect_reader_get_view(DetectReader* detect_reader) { @@ -132,27 +131,24 @@ void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_m furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - model->nonces_max = nonces_max; - return false; - }); + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces_max = nonces_max; }, + false); } void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected) { furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - model->nonces = nonces_collected; - return false; - }); + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces = nonces_collected; }, + false); } void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state) { furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - model->state = state; - return true; - }); + detect_reader->view, DetectReaderViewModel * model, { model->state = state; }, true); } diff --git a/applications/main/nfc/views/dict_attack.c b/applications/main/nfc/views/dict_attack.c index cbafbf69..c5f55ae7 100644 --- a/applications/main/nfc/views/dict_attack.c +++ b/applications/main/nfc/views/dict_attack.c @@ -80,20 +80,20 @@ DictAttack* dict_attack_alloc() { view_set_input_callback(dict_attack->view, dict_attack_input_callback); view_set_context(dict_attack->view, dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->header = furi_string_alloc(); - return false; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->header = furi_string_alloc(); }, + false); return dict_attack; } void dict_attack_free(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - furi_string_free(model->header); - return false; - }); + dict_attack->view, + DictAttackViewModel * model, + { furi_string_free(model->header); }, + false); view_free(dict_attack->view); free(dict_attack); } @@ -101,7 +101,9 @@ void dict_attack_free(DictAttack* dict_attack) { void dict_attack_reset(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateRead; model->type = MfClassicType1k; model->sectors_total = 0; @@ -112,8 +114,8 @@ void dict_attack_reset(DictAttack* dict_attack) { model->dict_keys_total = 0; model->dict_keys_current = 0; furi_string_reset(model->header); - return false; - }); + }, + false); } View* dict_attack_get_view(DictAttack* dict_attack) { @@ -133,99 +135,103 @@ void dict_attack_set_header(DictAttack* dict_attack, const char* header) { furi_assert(header); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - furi_string_set(model->header, header); - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { furi_string_set(model->header, header); }, + true); } void dict_attack_set_card_detected(DictAttack* dict_attack, MfClassicType type) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateRead; model->sectors_total = mf_classic_get_total_sectors_num(type); model->keys_total = model->sectors_total * 2; - return true; - }); + }, + true); } void dict_attack_set_card_removed(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->state = DictAttackStateCardRemoved; - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateCardRemoved; }, + true); } void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->sectors_read = sec_read; - return true; - }); + dict_attack->view, DictAttackViewModel * model, { model->sectors_read = sec_read; }, true); } void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->keys_found = keys_found; - return true; - }); + dict_attack->view, DictAttackViewModel * model, { model->keys_found = keys_found; }, true); } void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->sector_current = curr_sec; model->dict_keys_current = 0; - return true; - }); + }, + true); } void dict_attack_inc_current_sector(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->sector_current < model->sectors_total) { model->sector_current++; model->dict_keys_current = 0; } - return true; - }); + }, + true); } void dict_attack_inc_keys_found(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->keys_found < model->keys_total) { model->keys_found++; } - return true; - }); + }, + true); } void dict_attack_set_total_dict_keys(DictAttack* dict_attack, uint16_t dict_keys_total) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->dict_keys_total = dict_keys_total; - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->dict_keys_total = dict_keys_total; }, + true); } void dict_attack_inc_current_dict_key(DictAttack* dict_attack, uint16_t keys_tried) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->dict_keys_current + keys_tried < model->dict_keys_total) { model->dict_keys_current += keys_tried; } - return true; - }); + }, + true); } diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 6ec12e78..cdebc632 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -67,17 +67,17 @@ void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLo if(lock == SubGhzLockOn) { subghz_receiver->lock = lock; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowLock; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowLock; }, + true); furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } else { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowDefault; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowDefault; }, + true); } } @@ -95,7 +95,9 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { size_t history_item = model->history_item; uint16_t bounds = history_item > 3 ? 2 : history_item; @@ -107,8 +109,8 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv } else if(model->list_offset > model->idx - bounds) { model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); } - return true; - }); + }, + true); } void subghz_view_receiver_add_item_to_menu( @@ -117,7 +119,9 @@ void subghz_view_receiver_add_item_to_menu( uint8_t type) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { SubGhzReceiverMenuItem* item_menu = SubGhzReceiverMenuItemArray_push_raw(model->history->data); item_menu->item_str = furi_string_alloc_set(name); @@ -128,9 +132,8 @@ void subghz_view_receiver_add_item_to_menu( } else { model->history_item++; } - - return true; - }); + }, + true); subghz_view_receiver_update_offset(subghz_receiver); } @@ -141,12 +144,14 @@ void subghz_view_receiver_add_data_statusbar( const char* history_stat_str) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { furi_string_set(model->frequency_str, frequency_str); furi_string_set(model->preset_str, preset_str); furi_string_set(model->history_stat_str, history_stat_str); - return true; - }); + }, + true); } static void subghz_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { @@ -240,10 +245,10 @@ static void subghz_view_receiver_timer_callback(void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowDefault; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowDefault; }, + true); if(subghz_receiver->lock_count < UNLOCK_CNT) { subghz_receiver->callback( SubGhzCustomEventViewReceiverOffDisplay, subghz_receiver->context); @@ -260,10 +265,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { if(subghz_receiver->lock == SubGhzLockOn) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowToUnlockPress; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowToUnlockPress; }, + true); if(subghz_receiver->lock_count == 0) { furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } @@ -274,10 +279,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { // subghz_receiver->callback( // SubGhzCustomEventViewReceiverUnlock, subghz_receiver->context); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowUnlock; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowUnlock; }, + true); //subghz_receiver->lock = SubGhzLockOff; furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(650)); } @@ -291,29 +296,35 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { event->key == InputKeyUp && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->idx != 0) model->idx--; - return true; - }); + }, + true); } else if( event->key == InputKeyDown && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->idx != model->history_item - 1) model->idx++; - return true; - }); + }, + true); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { subghz_receiver->callback(SubGhzCustomEventViewReceiverConfig, subghz_receiver->context); } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->history_item != 0) { subghz_receiver->callback( SubGhzCustomEventViewReceiverOK, subghz_receiver->context); } - return false; - }); + }, + false); } subghz_view_receiver_update_offset(subghz_receiver); @@ -329,7 +340,9 @@ void subghz_view_receiver_exit(void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { furi_string_reset(model->frequency_str); furi_string_reset(model->preset_str); furi_string_reset(model->history_stat_str); @@ -342,8 +355,8 @@ void subghz_view_receiver_exit(void* context) { model->idx = 0; model->list_offset = 0; model->history_item = 0; - return false; - }); + }, + false); furi_timer_stop(subghz_receiver->timer); } @@ -364,15 +377,17 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { view_set_exit_callback(subghz_receiver->view, subghz_view_receiver_exit); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->frequency_str = furi_string_alloc(); model->preset_str = furi_string_alloc(); model->history_stat_str = furi_string_alloc(); model->bar_show = SubGhzViewReceiverBarShowDefault; model->history = malloc(sizeof(SubGhzReceiverHistory)); SubGhzReceiverMenuItemArray_init(model->history->data); - return true; - }); + }, + true); subghz_receiver->timer = furi_timer_alloc(subghz_view_receiver_timer_callback, FuriTimerTypeOnce, subghz_receiver); return subghz_receiver; @@ -382,7 +397,9 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { furi_string_free(model->frequency_str); furi_string_free(model->preset_str); furi_string_free(model->history_stat_str); @@ -393,8 +410,8 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { } SubGhzReceiverMenuItemArray_clear(model->history->data); free(model->history); - return false; - }); + }, + false); furi_timer_free(subghz_receiver->timer); view_free(subghz_receiver->view); free(subghz_receiver); @@ -409,20 +426,19 @@ uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver) furi_assert(subghz_receiver); uint32_t idx = 0; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - idx = model->idx; - return false; - }); + subghz_receiver->view, SubGhzViewReceiverModel * model, { idx = model->idx; }, false); return idx; } void subghz_view_receiver_set_idx_menu(SubGhzViewReceiver* subghz_receiver, uint16_t idx) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->idx = idx; if(model->idx > 2) model->list_offset = idx - 2; - return true; - }); + }, + true); subghz_view_receiver_update_offset(subghz_receiver); } diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 608cf586..c169f361 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -132,12 +132,14 @@ void subghz_frequency_analyzer_pair_callback( } //update history with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->history_frequency[2] = model->history_frequency[1]; model->history_frequency[1] = model->history_frequency[0]; model->history_frequency[0] = model->frequency; - return false; - }); + }, + false); } else if((rssi != 0.f) && (!instance->locked)) { if(instance->callback) { instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context); @@ -146,12 +148,14 @@ void subghz_frequency_analyzer_pair_callback( instance->locked = (rssi != 0.f); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->rssi = rssi; model->frequency = frequency; model->signal = signal; - return true; - }); + }, + true); } void subghz_frequency_analyzer_enter(void* context) { @@ -169,14 +173,16 @@ void subghz_frequency_analyzer_enter(void* context) { subghz_frequency_analyzer_worker_start(instance->worker); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->rssi = 0; model->frequency = 0; model->history_frequency[2] = 0; model->history_frequency[1] = 0; model->history_frequency[0] = 0; - return true; - }); + }, + true); } void subghz_frequency_analyzer_exit(void* context) { @@ -190,10 +196,7 @@ void subghz_frequency_analyzer_exit(void* context) { subghz_frequency_analyzer_worker_free(instance->worker); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { - model->rssi = 0; - return true; - }); + instance->view, SubGhzFrequencyAnalyzerModel * model, { model->rssi = 0; }, true); } SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() { @@ -210,10 +213,7 @@ SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() { view_set_exit_callback(instance->view, subghz_frequency_analyzer_exit); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { - model->rssi = 0; - return true; - }); + instance->view, SubGhzFrequencyAnalyzerModel * model, { model->rssi = 0; }, true); return instance; } diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index 0b4305b7..2d951b11 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -45,11 +45,13 @@ void subghz_read_raw_add_data_statusbar( const char* preset_str) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { furi_string_set(model->frequency_str, frequency_str); furi_string_set(model->preset_str, preset_str); - return true; - }); + }, + true); } void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi) { @@ -63,31 +65,35 @@ void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi) { } with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->rssi_history[model->ind_write++] = u_rssi; if(model->ind_write > SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE) { model->rssi_history_end = true; model->ind_write = 0; } - return true; - }); + }, + true); } void subghz_read_raw_update_sample_write(SubGhzReadRAW* instance, size_t sample) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - furi_string_printf(model->sample_write, "%d spl.", sample); - return false; - }); + instance->view, + SubGhzReadRAWModel * model, + { furi_string_printf(model->sample_write, "%d spl.", sample); }, + false); } void subghz_read_raw_stop_send(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusTXRepeat: case SubGhzReadRAWStatusLoadKeyTXRepeat: @@ -105,19 +111,21 @@ void subghz_read_raw_stop_send(SubGhzReadRAW* instance) { model->status = SubGhzReadRAWStatusIDLE; break; } - return true; - }); + }, + true); } void subghz_read_raw_update_sin(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->ind_sin++ > 62) { model->ind_sin = 0; } - return true; - }); + }, + true); } static int8_t subghz_read_raw_tab_sin(uint8_t x) { @@ -286,9 +294,11 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { //further check of events is not needed, we exit return false; } else if(event->key == InputKeyOk && event->type == InputTypePress) { + uint8_t ret = false; with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - uint8_t ret = false; + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusIDLE: // Start TX @@ -314,11 +324,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { default: break; } - return ret; - }); + }, + ret); } else if(event->key == InputKeyOk && event->type == InputTypeRelease) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusTXRepeat) { // Stop repeat TX model->status = SubGhzReadRAWStatusTX; @@ -326,11 +338,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { // Stop repeat TX model->status = SubGhzReadRAWStatusLoadKeyTX; } - return false; - }); + }, + false); } else if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusREC: //Stop REC @@ -357,11 +371,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { instance->callback(SubGhzCustomEventViewReadRAWBack, instance->context); break; } - return true; - }); + }, + true); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusStart) { //Config instance->callback(SubGhzCustomEventViewReadRAWConfig, instance->context); @@ -376,11 +392,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { furi_string_reset(model->file_name); instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context); } - return true; - }); + }, + true); } else if(event->key == InputKeyRight && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusIDLE) { //Save instance->callback(SubGhzCustomEventViewReadRAWSave, instance->context); @@ -388,11 +406,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { //More instance->callback(SubGhzCustomEventViewReadRAWMore, instance->context); } - return true; - }); + }, + true); } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusStart) { //Record instance->callback(SubGhzCustomEventViewReadRAWREC, instance->context); @@ -404,8 +424,8 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); model->status = SubGhzReadRAWStatusIDLE; } - return true; - }); + }, + true); } return true; } @@ -419,36 +439,42 @@ void subghz_read_raw_set_status( switch(status) { case SubGhzReadRAWStatusStart: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; furi_string_reset(model->file_name); furi_string_set(model->sample_write, "0 spl."); - return true; - }); + }, + true); break; case SubGhzReadRAWStatusIDLE: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - model->status = SubGhzReadRAWStatusIDLE; - return true; - }); + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusIDLE; }, + true); break; case SubGhzReadRAWStatusLoadKeyTX: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; furi_string_set(model->file_name, file_name); furi_string_set(model->sample_write, "RAW"); - return true; - }); + }, + true); break; case SubGhzReadRAWStatusSaveKey: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusLoadKeyIDLE; if(!model->ind_write) { furi_string_set(model->file_name, file_name); @@ -456,8 +482,8 @@ void subghz_read_raw_set_status( } else { furi_string_reset(model->file_name); } - return true; - }); + }, + true); break; default: @@ -476,15 +502,17 @@ void subghz_read_raw_exit(void* context) { SubGhzReadRAW* instance = context; with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status != SubGhzReadRAWStatusIDLE && model->status != SubGhzReadRAWStatusStart && model->status != SubGhzReadRAWStatusLoadKeyIDLE) { instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); model->status = SubGhzReadRAWStatusStart; } - return true; - }); + }, + true); } SubGhzReadRAW* subghz_read_raw_alloc() { @@ -500,14 +528,16 @@ SubGhzReadRAW* subghz_read_raw_alloc() { view_set_exit_callback(instance->view, subghz_read_raw_exit); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->frequency_str = furi_string_alloc(); model->preset_str = furi_string_alloc(); model->sample_write = furi_string_alloc(); model->file_name = furi_string_alloc(); model->rssi_history = malloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); - return true; - }); + }, + true); return instance; } @@ -516,14 +546,16 @@ void subghz_read_raw_free(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { furi_string_free(model->frequency_str); furi_string_free(model->preset_str); furi_string_free(model->sample_write); furi_string_free(model->file_name); free(model->rssi_history); - return true; - }); + }, + true); view_free(instance->view); free(instance); } diff --git a/applications/main/subghz/views/subghz_test_carrier.c b/applications/main/subghz/views/subghz_test_carrier.c index 6729eaad..e533a6aa 100644 --- a/applications/main/subghz/views/subghz_test_carrier.c +++ b/applications/main/subghz/views/subghz_test_carrier.c @@ -89,7 +89,9 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { } with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { furi_hal_subghz_idle(); if(event->key == InputKeyLeft) { @@ -125,9 +127,8 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { SubGhzTestCarrierEventOnlyRx, subghz_test_carrier->context); } } - - return true; - }); + }, + true); return true; } @@ -142,15 +143,17 @@ void subghz_test_carrier_enter(void* context) { furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { model->frequency = subghz_frequencies_433_92_testing; // 433 model->real_frequency = furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]); model->path = FuriHalSubGhzPathIsolate; // isolate model->rssi = 0.0f; model->status = SubGhzTestCarrierModelStatusRx; - return true; - }); + }, + true); furi_hal_subghz_rx(); @@ -172,13 +175,14 @@ void subghz_test_carrier_rssi_timer_callback(void* context) { SubGhzTestCarrier* subghz_test_carrier = context; with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { if(model->status == SubGhzTestCarrierModelStatusRx) { model->rssi = furi_hal_subghz_get_rssi(); - return true; } - return false; - }); + }, + false); } SubGhzTestCarrier* subghz_test_carrier_alloc() { diff --git a/applications/main/subghz/views/subghz_test_packet.c b/applications/main/subghz/views/subghz_test_packet.c index c83aebec..a42898f7 100644 --- a/applications/main/subghz/views/subghz_test_packet.c +++ b/applications/main/subghz/views/subghz_test_packet.c @@ -68,7 +68,9 @@ static void subghz_test_packet_rssi_timer_callback(void* context) { SubGhzTestPacket* instance = context; with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { model->rssi = furi_hal_subghz_get_rssi(); model->packets = instance->packet_rx; @@ -77,8 +79,8 @@ static void subghz_test_packet_rssi_timer_callback(void* context) { SUBGHZ_TEST_PACKET_COUNT - subghz_encoder_princeton_for_testing_get_repeat_left(instance->encoder); } - return true; - }); + }, + true); } static void subghz_test_packet_draw(Canvas* canvas, SubGhzTestPacketModel* model) { @@ -137,7 +139,9 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { } with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { @@ -179,9 +183,8 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { instance->callback(SubGhzTestPacketEventOnlyRx, instance->context); } } - - return true; - }); + }, + true); return true; } @@ -194,15 +197,17 @@ void subghz_test_packet_enter(void* context) { furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { model->frequency = subghz_frequencies_433_92_testing; model->real_frequency = furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]); model->path = FuriHalSubGhzPathIsolate; // isolate model->rssi = 0.0f; model->status = SubGhzTestPacketModelStatusRx; - return true; - }); + }, + true); furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); @@ -217,15 +222,17 @@ void subghz_test_packet_exit(void* context) { // Reinitialize IC to default state with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick()); furi_hal_subghz_stop_async_tx(); } - return true; - }); + }, + true); furi_hal_subghz_sleep(); } diff --git a/applications/main/subghz/views/subghz_test_static.c b/applications/main/subghz/views/subghz_test_static.c index 7af54c3c..6abefda7 100644 --- a/applications/main/subghz/views/subghz_test_static.c +++ b/applications/main/subghz/views/subghz_test_static.c @@ -77,7 +77,9 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } with_view_model( - instance->view, (SubGhzTestStaticModel * model) { + instance->view, + SubGhzTestStaticModel * model, + { if(event->type == InputTypeShort) { if(event->key == InputKeyLeft) { if(model->frequency > 0) model->frequency--; @@ -128,9 +130,8 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } furi_record_close(RECORD_NOTIFICATION); } - - return true; - }); + }, + true); return true; } @@ -147,13 +148,14 @@ void subghz_test_static_enter(void* context) { instance->status_tx = SubGhzTestStaticStatusIDLE; with_view_model( - instance->view, (SubGhzTestStaticModel * model) { + instance->view, + SubGhzTestStaticModel * model, + { model->frequency = subghz_frequencies_433_92_testing; model->real_frequency = subghz_frequencies_testing[model->frequency]; model->button = 0; - - return true; - }); + }, + true); } void subghz_test_static_exit(void* context) { diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index 1094c5c5..833805cc 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -35,13 +35,15 @@ void subghz_view_transmitter_add_data_to_show( uint8_t show_button) { furi_assert(subghz_transmitter); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { furi_string_set(model->key_str, key_str); furi_string_set(model->frequency_str, frequency_str); furi_string_set(model->preset_str, preset_str); model->show_button = show_button; - return true; - }); + }, + true); } static void subghz_view_transmitter_button_right(Canvas* canvas, const char* str) { @@ -95,23 +97,27 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { furi_string_reset(model->frequency_str); furi_string_reset(model->preset_str); furi_string_reset(model->key_str); model->show_button = 0; - return false; - }); + }, + false); return false; } with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { if(model->show_button) { can_be_sent = true; } - return true; - }); + }, + true); if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { subghz_transmitter->callback( @@ -149,12 +155,14 @@ SubGhzViewTransmitter* subghz_view_transmitter_alloc() { view_set_exit_callback(subghz_transmitter->view, subghz_view_transmitter_exit); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { model->frequency_str = furi_string_alloc(); model->preset_str = furi_string_alloc(); model->key_str = furi_string_alloc(); - return true; - }); + }, + true); return subghz_transmitter; } @@ -162,12 +170,14 @@ void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter) { furi_assert(subghz_transmitter); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { furi_string_free(model->frequency_str); furi_string_free(model->preset_str); furi_string_free(model->key_str); - return true; - }); + }, + true); view_free(subghz_transmitter->view); free(subghz_transmitter); } diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c index 11e2c9b0..fa3d6cc2 100644 --- a/applications/main/u2f/views/u2f_view.c +++ b/applications/main/u2f/views/u2f_view.c @@ -85,18 +85,17 @@ void u2f_view_set_ok_callback(U2fView* u2f, U2fOkCallback callback, void* contex furi_assert(u2f); furi_assert(callback); with_view_model( - u2f->view, (U2fModel * model) { + u2f->view, + U2fModel * model, + { UNUSED(model); u2f->callback = callback; u2f->context = context; - return false; - }); + }, + false); } void u2f_view_set_state(U2fView* u2f, U2fViewMsg msg) { with_view_model( - u2f->view, (U2fModel * model) { - model->display_msg = msg; - return true; - }); + u2f->view, U2fModel * model, { model->display_msg = msg; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c index 8b9ae593..2c65f6ab 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c @@ -277,7 +277,9 @@ static void bt_hid_keyboard_get_select_key(BtHidKeyboardModel* model, BtHidKeybo static void bt_hid_keyboard_process(BtHidKeyboard* bt_hid_keyboard, InputEvent* event) { with_view_model( - bt_hid_keyboard->view, (BtHidKeyboardModel * model) { + bt_hid_keyboard->view, + BtHidKeyboardModel * model, + { if(event->key == InputKeyOk) { if(event->type == InputTypePress) { model->ok_pressed = true; @@ -338,8 +340,8 @@ static void bt_hid_keyboard_process(BtHidKeyboard* bt_hid_keyboard, InputEvent* bt_hid_keyboard_get_select_key(model, (BtHidKeyboardPoint){.x = 1, .y = 0}); } } - return true; - }); + }, + true); } static bool bt_hid_keyboard_input_callback(InputEvent* event, void* context) { @@ -382,8 +384,5 @@ View* bt_hid_keyboard_get_view(BtHidKeyboard* bt_hid_keyboard) { void bt_hid_keyboard_set_connected_status(BtHidKeyboard* bt_hid_keyboard, bool connected) { furi_assert(bt_hid_keyboard); with_view_model( - bt_hid_keyboard->view, (BtHidKeyboardModel * model) { - model->connected = connected; - return true; - }); + bt_hid_keyboard->view, BtHidKeyboardModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c index ea4ee16f..db88b800 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c @@ -106,7 +106,9 @@ static void bt_hid_keynote_draw_callback(Canvas* canvas, void* context) { static void bt_hid_keynote_process(BtHidKeynote* bt_hid_keynote, InputEvent* event) { with_view_model( - bt_hid_keynote->view, (BtHidKeynoteModel * model) { + bt_hid_keynote->view, + BtHidKeynoteModel * model, + { if(event->type == InputTypePress) { if(event->key == InputKeyUp) { model->up_pressed = true; @@ -153,8 +155,8 @@ static void bt_hid_keynote_process(BtHidKeynote* bt_hid_keynote, InputEvent* eve furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_AC_BACK); } } - return true; - }); + }, + true); } static bool bt_hid_keynote_input_callback(InputEvent* event, void* context) { @@ -197,8 +199,5 @@ View* bt_hid_keynote_get_view(BtHidKeynote* bt_hid_keynote) { void bt_hid_keynote_set_connected_status(BtHidKeynote* bt_hid_keynote, bool connected) { furi_assert(bt_hid_keynote); with_view_model( - bt_hid_keynote->view, (BtHidKeynoteModel * model) { - model->connected = connected; - return true; - }); + bt_hid_keynote->view, BtHidKeynoteModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_media.c b/applications/plugins/bt_hid_app/views/bt_hid_media.c index 258ea0a4..181cd347 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_media.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_media.c @@ -107,7 +107,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) { static void bt_hid_media_process_press(BtHidMedia* bt_hid_media, InputEvent* event) { with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { + bt_hid_media->view, + BtHidMediaModel * model, + { if(event->key == InputKeyUp) { model->up_pressed = true; furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); @@ -124,13 +126,15 @@ static void bt_hid_media_process_press(BtHidMedia* bt_hid_media, InputEvent* eve model->ok_pressed = true; furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_PLAY_PAUSE); } - return true; - }); + }, + true); } static void bt_hid_media_process_release(BtHidMedia* bt_hid_media, InputEvent* event) { with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { + bt_hid_media->view, + BtHidMediaModel * model, + { if(event->key == InputKeyUp) { model->up_pressed = false; furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); @@ -147,8 +151,8 @@ static void bt_hid_media_process_release(BtHidMedia* bt_hid_media, InputEvent* e model->ok_pressed = false; furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_PLAY_PAUSE); } - return true; - }); + }, + true); } static bool bt_hid_media_input_callback(InputEvent* event, void* context) { @@ -196,8 +200,5 @@ View* bt_hid_media_get_view(BtHidMedia* bt_hid_media) { void bt_hid_media_set_connected_status(BtHidMedia* bt_hid_media, bool connected) { furi_assert(bt_hid_media); with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { - model->connected = connected; - return true; - }); + bt_hid_media->view, BtHidMediaModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c index 395cb52c..098adb73 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c @@ -103,7 +103,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) { static void bt_hid_mouse_process(BtHidMouse* bt_hid_mouse, InputEvent* event) { with_view_model( - bt_hid_mouse->view, (BtHidMouseModel * model) { + bt_hid_mouse->view, + BtHidMouseModel * model, + { if(event->key == InputKeyBack) { if(event->type == InputTypeShort) { furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_RIGHT); @@ -167,8 +169,8 @@ static void bt_hid_mouse_process(BtHidMouse* bt_hid_mouse, InputEvent* event) { model->up_pressed = false; } } - return true; - }); + }, + true); } static bool bt_hid_mouse_input_callback(InputEvent* event, void* context) { @@ -211,8 +213,5 @@ View* bt_hid_mouse_get_view(BtHidMouse* bt_hid_mouse) { void bt_hid_mouse_set_connected_status(BtHidMouse* bt_hid_mouse, bool connected) { furi_assert(bt_hid_mouse); with_view_model( - bt_hid_mouse->view, (BtHidMouseModel * model) { - model->connected = connected; - return true; - }); + bt_hid_mouse->view, BtHidMouseModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.c b/applications/plugins/signal_generator/views/signal_gen_pwm.c index 4afed01a..6d1a3c1b 100644 --- a/applications/plugins/signal_generator/views/signal_gen_pwm.c +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.c @@ -44,12 +44,14 @@ static void pwm_set_config(SignalGenPwm* pwm) { uint8_t duty; with_view_model( - pwm->view, (SignalGenPwmViewModel * model) { + pwm->view, + SignalGenPwmViewModel * model, + { channel = model->channel_id; freq = model->freq; duty = model->duty; - return false; - }); + }, + false); furi_assert(pwm->callback); pwm->callback(channel, freq, duty, pwm->context); @@ -188,7 +190,9 @@ static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { bool need_update = false; with_view_model( - pwm->view, (SignalGenPwmViewModel * model) { + pwm->view, + SignalGenPwmViewModel * model, + { if(model->edit_mode == false) { if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { if(event->key == InputKeyUp) { @@ -238,8 +242,8 @@ static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { } } } - return true; - }); + }, + true); if(need_update) { pwm_set_config(pwm); @@ -279,22 +283,26 @@ void signal_gen_pwm_set_callback( furi_assert(callback); with_view_model( - pwm->view, (SignalGenPwmViewModel * model) { + pwm->view, + SignalGenPwmViewModel * model, + { UNUSED(model); pwm->callback = callback; pwm->context = context; - return false; - }); + }, + false); } void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty) { with_view_model( - pwm->view, (SignalGenPwmViewModel * model) { + pwm->view, + SignalGenPwmViewModel * model, + { model->channel_id = channel_id; model->freq = freq; model->duty = duty; - return true; - }); + }, + true); furi_assert(pwm->callback); pwm->callback(channel_id, freq, duty, pwm->context); diff --git a/applications/services/desktop/views/desktop_view_debug.c b/applications/services/desktop/views/desktop_view_debug.c index c965432f..f9c8aedc 100644 --- a/applications/services/desktop/views/desktop_view_debug.c +++ b/applications/services/desktop/views/desktop_view_debug.c @@ -124,16 +124,17 @@ bool desktop_debug_input(InputEvent* event, void* context) { DesktopViewStatsScreens current = 0; with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { - + debug_view->view, + DesktopDebugViewModel * model, + { #ifdef SRV_DOLPHIN_STATE_DEBUG if((event->key == InputKeyDown) || (event->key == InputKeyUp)) { model->screen = !model->screen; } #endif current = model->screen; - return true; - }); + }, + true); size_t count = (event->type == InputTypeRepeat) ? 10 : 1; if(current == DesktopViewStatsMeta) { @@ -181,20 +182,19 @@ void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { + debug_view->view, + DesktopDebugViewModel * model, + { model->icounter = stats.icounter; model->butthurt = stats.butthurt; model->timestamp = stats.timestamp; - return true; - }); + }, + true); furi_record_close(RECORD_DOLPHIN); } void desktop_debug_reset_screen_idx(DesktopDebugView* debug_view) { with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { - model->screen = 0; - return true; - }); + debug_view->view, DesktopDebugViewModel * model, { model->screen = 0; }, true); } diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 294191bf..8cb8a7a1 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -24,27 +24,24 @@ void desktop_lock_menu_set_callback( void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set) { with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->pin_is_set = pin_is_set; - return true; - }); + lock_menu->view, + DesktopLockMenuViewModel * model, + { model->pin_is_set = pin_is_set; }, + true); } void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool dummy_mode) { with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->dummy_mode = dummy_mode; - return true; - }); + lock_menu->view, + DesktopLockMenuViewModel * model, + { model->dummy_mode = dummy_mode; }, + true); } void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) { furi_assert(idx < DesktopLockMenuIndexTotalCount); with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->idx = idx; - return true; - }); + lock_menu->view, DesktopLockMenuViewModel * model, { model->idx = idx; }, true); } void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) { @@ -95,10 +92,12 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { uint8_t idx = 0; bool consumed = false; bool dummy_mode = false; + bool update = false; with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - bool ret = false; + lock_menu->view, + DesktopLockMenuViewModel * model, + { if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { if(event->key == InputKeyUp) { if(model->idx == 0) { @@ -106,7 +105,7 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } else { model->idx = CLAMP(model->idx - 1, DesktopLockMenuIndexTotalCount - 1, 0); } - ret = true; + update = true; consumed = true; } else if(event->key == InputKeyDown) { if(model->idx == DesktopLockMenuIndexTotalCount - 1) { @@ -114,14 +113,14 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } else { model->idx = CLAMP(model->idx + 1, DesktopLockMenuIndexTotalCount - 1, 0); } - ret = true; + update = true; consumed = true; } } idx = model->idx; dummy_mode = model->dummy_mode; - return ret; - }); + }, + update); if(event->key == InputKeyOk) { if((idx == DesktopLockMenuIndexLock) && (event->type == InputTypeShort)) { diff --git a/applications/services/gui/modules/button_menu.c b/applications/services/gui/modules/button_menu.c index 1dce014d..37a04326 100644 --- a/applications/services/gui/modules/button_menu.c +++ b/applications/services/gui/modules/button_menu.c @@ -148,28 +148,32 @@ static void button_menu_process_up(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position > 0) { model->position--; } else { model->position = ButtonMenuItemArray_size(model->items) - 1; } - return true; - }); + }, + true); } static void button_menu_process_down(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position < (ButtonMenuItemArray_size(model->items) - 1)) { model->position++; } else { model->position = 0; } - return true; - }); + }, + true); } static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) { @@ -178,12 +182,14 @@ static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) { ButtonMenuItem* item = NULL; with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position < (ButtonMenuItemArray_size(model->items))) { item = ButtonMenuItemArray_get(model->items, model->position); } - return false; - }); + }, + false); if(item) { if(item->type == ButtonMenuItemTypeControl) { @@ -248,22 +254,21 @@ void button_menu_reset(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_reset(model->items); model->position = 0; model->header = NULL; - return true; - }); + }, + true); } void button_menu_set_header(ButtonMenu* button_menu, const char* header) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { - model->header = header; - return true; - }); + button_menu->view, ButtonMenuModel * model, { model->header = header; }, true); } ButtonMenuItem* button_menu_add_item( @@ -278,15 +283,17 @@ ButtonMenuItem* button_menu_add_item( furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { item = ButtonMenuItemArray_push_new(model->items); item->label = label; item->index = index; item->type = type; item->callback = callback; item->callback_context = callback_context; - return true; - }); + }, + true); return item; } @@ -301,12 +308,14 @@ ButtonMenu* button_menu_alloc(void) { view_set_input_callback(button_menu->view, button_menu_view_input_callback); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_init(model->items); model->position = 0; model->header = NULL; - return true; - }); + }, + true); button_menu->freeze_input = false; return button_menu; @@ -316,10 +325,10 @@ void button_menu_free(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { - ButtonMenuItemArray_clear(model->items); - return true; - }); + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_clear(model->items); }, + true); view_free(button_menu->view); free(button_menu); } @@ -328,7 +337,9 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { uint8_t item_position = 0; ButtonMenuItemArray_it_t it; for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it); @@ -338,6 +349,6 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) { break; } } - return true; - }); + }, + true); } diff --git a/applications/services/gui/modules/button_panel.c b/applications/services/gui/modules/button_panel.c index c823e4b1..47b6ed48 100644 --- a/applications/services/gui/modules/button_panel.c +++ b/applications/services/gui/modules/button_panel.c @@ -70,15 +70,17 @@ ButtonPanel* button_panel_alloc() { view_set_input_callback(button_panel->view, button_panel_view_input_callback); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { model->reserve_x = 0; model->reserve_y = 0; model->selected_item_x = 0; model->selected_item_y = 0; ButtonMatrix_init(model->button_matrix); LabelList_init(model->labels); - return true; - }); + }, + true); return button_panel; } @@ -88,7 +90,9 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re furi_check(reserve_y > 0); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { model->reserve_x = reserve_x; model->reserve_y = reserve_y; ButtonMatrix_reserve(model->button_matrix, model->reserve_y); @@ -99,8 +103,8 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re // TODO: do we need to clear allocated memory of ptr-s to ButtonItem ?? } LabelList_init(model->labels); - return true; - }); + }, + true); } void button_panel_free(ButtonPanel* button_panel) { @@ -109,11 +113,13 @@ void button_panel_free(ButtonPanel* button_panel) { button_panel_reset(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { LabelList_clear(model->labels); ButtonMatrix_clear(model->button_matrix); - return true; - }); + }, + true); view_free(button_panel->view); free(button_panel); @@ -123,7 +129,9 @@ void button_panel_reset(ButtonPanel* button_panel) { furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { for(size_t x = 0; x < model->reserve_x; ++x) { for(size_t y = 0; y < model->reserve_y; ++y) { ButtonItem** button_item = button_panel_get_item(model, x, y); @@ -137,8 +145,8 @@ void button_panel_reset(ButtonPanel* button_panel) { model->selected_item_y = 0; LabelList_reset(model->labels); ButtonMatrix_reset(model->button_matrix); - return true; - }); + }, + true); } static ButtonItem** button_panel_get_item(ButtonPanelModel* model, size_t x, size_t y) { @@ -165,7 +173,9 @@ void button_panel_add_item( furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { ButtonItem** button_item_ptr = button_panel_get_item(model, matrix_place_x, matrix_place_y); furi_check(*button_item_ptr == NULL); @@ -178,8 +188,8 @@ void button_panel_add_item( button_item->icon.name = icon_name; button_item->icon.name_selected = icon_name_selected; button_item->index = index; - return true; - }); + }, + true); } View* button_panel_get_view(ButtonPanel* button_panel) { @@ -216,114 +226,123 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) { static void button_panel_process_down(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { uint16_t new_selected_item_x = model->selected_item_x; uint16_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_y >= (model->reserve_y - 1)) return false; + if(new_selected_item_y < (model->reserve_y - 1)) { + ++new_selected_item_y; - ++new_selected_item_y; - - for(i = 0; i < model->reserve_x; ++i) { - new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_x; ++i) { + new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_x) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_x) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - - return true; - }); + }, + true); } static void button_panel_process_up(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { size_t new_selected_item_x = model->selected_item_x; size_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_y <= 0) return false; + if(new_selected_item_y > 0) { + --new_selected_item_y; - --new_selected_item_y; - - for(i = 0; i < model->reserve_x; ++i) { - new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_x; ++i) { + new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_x) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_x) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } static void button_panel_process_left(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { size_t new_selected_item_x = model->selected_item_x; size_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_x <= 0) return false; + if(new_selected_item_x > 0) { + --new_selected_item_x; - --new_selected_item_x; - - for(i = 0; i < model->reserve_y; ++i) { - new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_y; ++i) { + new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_y) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_y) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } static void button_panel_process_right(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { uint16_t new_selected_item_x = model->selected_item_x; uint16_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_x >= (model->reserve_x - 1)) return false; + if(new_selected_item_x < (model->reserve_x - 1)) { + ++new_selected_item_x; - ++new_selected_item_x; - - for(i = 0; i < model->reserve_y; ++i) { - new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_y; ++i) { + new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_y) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_y) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } void button_panel_process_ok(ButtonPanel* button_panel) { ButtonItem* button_item = NULL; with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { button_item = *button_panel_get_item(model, model->selected_item_x, model->selected_item_y); - return true; - }); + }, + true); if(button_item && button_item->callback) { button_item->callback(button_item->callback_context, button_item->index); @@ -374,12 +393,14 @@ void button_panel_add_label( furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { LabelElement* label = LabelList_push_raw(model->labels); label->x = x; label->y = y; label->font = font; label->str = label_str; - return true; - }); + }, + true); } diff --git a/applications/services/gui/modules/byte_input.c b/applications/services/gui/modules/byte_input.c index bb18a107..8d7e7fd4 100644 --- a/applications/services/gui/modules/byte_input.c +++ b/applications/services/gui/modules/byte_input.c @@ -618,42 +618,30 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { switch(event->key) { case InputKeyLeft: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_left(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_left(model); }, true); consumed = true; break; case InputKeyRight: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_right(model); - return true; - }); + byte_input->view, + ByteInputModel * model, + { byte_input_handle_right(model); }, + true); consumed = true; break; case InputKeyUp: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_up(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_up(model); }, true); consumed = true; break; case InputKeyDown: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_down(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_down(model); }, true); consumed = true; break; case InputKeyOk: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_ok(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_ok(model); }, true); consumed = true; break; default: @@ -664,10 +652,10 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { if((event->type == InputTypeLong || event->type == InputTypeRepeat) && event->key == InputKeyBack) { with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_clear_selected_byte(model); - return true; - }); + byte_input->view, + ByteInputModel * model, + { byte_input_clear_selected_byte(model); }, + true); consumed = true; } @@ -703,14 +691,16 @@ ByteInput* byte_input_alloc() { view_set_input_callback(byte_input->view, byte_input_view_input_callback); with_view_model( - byte_input->view, (ByteInputModel * model) { + byte_input->view, + ByteInputModel * model, + { model->header = ""; model->input_callback = NULL; model->changed_callback = NULL; model->callback_context = NULL; byte_input_reset_model_input_data(model); - return true; - }); + }, + true); return byte_input; } @@ -755,15 +745,17 @@ void byte_input_set_result_callback( uint8_t* bytes, uint8_t bytes_count) { with_view_model( - byte_input->view, (ByteInputModel * model) { + byte_input->view, + ByteInputModel * model, + { byte_input_reset_model_input_data(model); model->input_callback = input_callback; model->changed_callback = changed_callback; model->callback_context = callback_context; model->bytes = bytes; model->bytes_count = bytes_count; - return true; - }); + }, + true); } /** @@ -774,8 +766,5 @@ void byte_input_set_result_callback( */ void byte_input_set_header_text(ByteInput* byte_input, const char* text) { with_view_model( - byte_input->view, (ByteInputModel * model) { - model->header = text; - return true; - }); + byte_input->view, ByteInputModel * model, { model->header = text; }, true); } diff --git a/applications/services/gui/modules/dialog_ex.c b/applications/services/gui/modules/dialog_ex.c index dee2a097..1cb46723 100644 --- a/applications/services/gui/modules/dialog_ex.c +++ b/applications/services/gui/modules/dialog_ex.c @@ -90,12 +90,14 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) { const char* right_text = NULL; with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { left_text = model->left_text; center_text = model->center_text; right_text = model->right_text; - return true; - }); + }, + true); if(dialog_ex->callback) { if(event->type == InputTypeShort) { @@ -149,7 +151,9 @@ DialogEx* dialog_ex_alloc() { view_set_draw_callback(dialog_ex->view, dialog_ex_view_draw_callback); view_set_input_callback(dialog_ex->view, dialog_ex_view_input_callback); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header.text = NULL; model->header.x = 0; model->header.y = 0; @@ -169,9 +173,8 @@ DialogEx* dialog_ex_alloc() { model->left_text = NULL; model->center_text = NULL; model->right_text = NULL; - - return true; - }); + }, + true); dialog_ex->enable_extended_events = false; return dialog_ex; } @@ -206,14 +209,16 @@ void dialog_ex_set_header( Align vertical) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header.text = text; model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; model->header.vertical = vertical; - return true; - }); + }, + true); } void dialog_ex_set_text( @@ -225,52 +230,47 @@ void dialog_ex_set_text( Align vertical) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->text.text = text; model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; model->text.vertical = vertical; - return true; - }); + }, + true); } void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->icon.x = x; model->icon.y = y; model->icon.icon = icon; - return true; - }); + }, + true); } void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->left_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->left_text = text; }, true); } void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->center_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->center_text = text; }, true); } void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->right_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->right_text = text; }, true); } void dialog_ex_reset(DialogEx* dialog_ex) { @@ -279,15 +279,17 @@ void dialog_ex_reset(DialogEx* dialog_ex) { .text = NULL, .x = 0, .y = 0, .horizontal = AlignLeft, .vertical = AlignLeft}; IconElement clean_icon_el = {.icon = NULL, .x = 0, .y = 0}; with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header = clean_text_el; model->text = clean_text_el; model->icon = clean_icon_el; model->left_text = NULL; model->center_text = NULL; model->right_text = NULL; - return true; - }); + }, + true); dialog_ex->context = NULL; dialog_ex->callback = NULL; } diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index 762fe87d..60e78b01 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -139,10 +139,7 @@ FileBrowser* file_browser_alloc(FuriString* result_path) { browser->result_path = result_path; with_view_model( - browser->view, (FileBrowserModel * model) { - items_array_init(model->items); - return false; - }); + browser->view, FileBrowserModel * model, { items_array_init(model->items); }, false); return browser; } @@ -151,10 +148,7 @@ void file_browser_free(FileBrowser* browser) { furi_assert(browser); with_view_model( - browser->view, (FileBrowserModel * model) { - items_array_clear(model->items); - return false; - }); + browser->view, FileBrowserModel * model, { items_array_clear(model->items); }, false); view_free(browser->view); free(browser); @@ -178,11 +172,13 @@ void file_browser_configure( browser->hide_ext = hide_ext; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { model->file_icon = file_icon; model->hide_ext = hide_ext; - return false; - }); + }, + false); } void file_browser_start(FileBrowser* browser, FuriString* path) { @@ -199,14 +195,16 @@ void file_browser_stop(FileBrowser* browser) { furi_assert(browser); file_browser_worker_free(browser->worker); with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); model->item_cnt = 0; model->item_idx = 0; model->array_offset = 0; model->list_offset = 0; - return false; - }); + }, + false); } void file_browser_set_callback(FileBrowser* browser, FileBrowserCallback callback, void* context) { @@ -257,7 +255,9 @@ static void browser_update_offset(FileBrowser* browser) { furi_assert(browser); with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { uint16_t bounds = model->item_cnt > (LIST_ITEMS - 1) ? 2 : model->item_cnt; if((model->item_cnt > (LIST_ITEMS - 1)) && @@ -272,9 +272,8 @@ static void browser_update_offset(FileBrowser* browser) { model->list_offset = CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0); } - - return false; - }); + }, + false); } static void @@ -285,7 +284,9 @@ static void int32_t load_offset = 0; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); if(is_root) { model->item_cnt = item_cnt; @@ -303,8 +304,8 @@ static void model->is_root = is_root; model->list_loading = true; model->folder_loading = false; - return true; - }); + }, + true); browser_update_offset(browser); file_browser_worker_load(browser->worker, load_offset, ITEM_LIST_LEN_MAX); @@ -319,7 +320,9 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { back_item.type = BrowserItemTypeBack; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); model->array_offset = list_load_offset; if(!model->is_root) { @@ -329,8 +332,8 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { model->array_offset += 1; } } - return false; - }); + }, + true); BrowserItem_t_clear(&back_item); } @@ -371,11 +374,13 @@ static void } with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_push_back(model->items, item); // TODO: calculate if element is visible - return true; - }); + }, + true); furi_string_free(item.display_name); furi_string_free(item.path); if(item.custom_icon_data) { @@ -383,10 +388,7 @@ static void } } else { with_view_model( - browser->view, (FileBrowserModel * model) { - model->list_loading = false; - return true; - }); + browser->view, FileBrowserModel * model, { model->list_loading = false; }, true); } } @@ -395,10 +397,7 @@ static void browser_long_load_cb(void* context) { FileBrowser* browser = (FileBrowser*)context; with_view_model( - browser->view, (FileBrowserModel * model) { - model->folder_loading = true; - return true; - }); + browser->view, FileBrowserModel * model, { model->folder_loading = true; }, true); } static void browser_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { @@ -508,17 +507,16 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { bool is_loading = false; with_view_model( - browser->view, (FileBrowserModel * model) { - is_loading = model->folder_loading; - return false; - }); + browser->view, FileBrowserModel * model, { is_loading = model->folder_loading; }, false); if(is_loading) { return false; } else if(event->key == InputKeyUp || event->key == InputKeyDown) { if(event->type == InputTypeShort || event->type == InputTypeRepeat) { with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { if(event->key == InputKeyUp) { model->item_idx = ((model->item_idx - 1) + model->item_cnt) % model->item_cnt; @@ -543,8 +541,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { browser->worker, load_offset, ITEM_LIST_LEN_MAX); } } - return true; - }); + }, + true); browser_update_offset(browser); consumed = true; } @@ -553,7 +551,9 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { BrowserItem_t* selected_item = NULL; int32_t select_index = 0; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { if(browser_is_item_in_array(model, model->item_idx)) { selected_item = items_array_get(model->items, model->item_idx - model->array_offset); @@ -562,8 +562,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { select_index -= 1; } } - return false; - }); + }, + false); if(selected_item) { if(selected_item->type == BrowserItemTypeBack) { @@ -584,10 +584,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { if(event->type == InputTypeShort) { bool is_root = false; with_view_model( - browser->view, (FileBrowserModel * model) { - is_root = model->is_root; - return false; - }); + browser->view, FileBrowserModel * model, { is_root = model->is_root; }, false); if(!is_root) { file_browser_worker_folder_exit(browser->worker); } diff --git a/applications/services/gui/modules/menu.c b/applications/services/gui/modules/menu.c index 67d46d5f..db0717f7 100644 --- a/applications/services/gui/modules/menu.c +++ b/applications/services/gui/modules/menu.c @@ -103,25 +103,29 @@ static bool menu_input_callback(InputEvent* event, void* context) { static void menu_enter(void* context) { Menu* menu = context; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_start(item->icon); } - return false; - }); + }, + false); } static void menu_exit(void* context) { Menu* menu = context; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); } - return false; - }); + }, + false); } Menu* menu_alloc() { @@ -135,11 +139,13 @@ Menu* menu_alloc() { view_set_exit_callback(menu->view, menu_exit); with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItemArray_init(model->items); model->position = 0; - return true; - }); + }, + true); return menu; } @@ -168,7 +174,9 @@ void menu_add_item( MenuItem* item = NULL; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { item = MenuItemArray_push_new(model->items); item->label = label; item->icon = icon ? icon_animation_alloc(icon) : icon_animation_alloc(&A_Plugins_14); @@ -176,14 +184,16 @@ void menu_add_item( item->index = index; item->callback = callback; item->callback_context = context; - return true; - }); + }, + true); } void menu_reset(Menu* menu) { furi_assert(menu); with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { for M_EACH(item, model->items, MenuItemArray_t) { icon_animation_stop(item->icon); @@ -192,25 +202,27 @@ void menu_reset(Menu* menu) { MenuItemArray_reset(model->items); model->position = 0; - return true; - }); + }, + true); } void menu_set_selected_item(Menu* menu, uint32_t index) { with_view_model( - menu->view, (MenuModel * model) { - if(index >= MenuItemArray_size(model->items)) { - return false; + menu->view, + MenuModel * model, + { + if(index < MenuItemArray_size(model->items)) { + model->position = index; } - - model->position = index; - return true; - }); + }, + true); } static void menu_process_up(Menu* menu) { with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); @@ -226,13 +238,15 @@ static void menu_process_up(Menu* menu) { if(item && item->icon) { icon_animation_start(item->icon); } - return true; - }); + }, + true); } static void menu_process_down(Menu* menu) { with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); @@ -248,19 +262,21 @@ static void menu_process_down(Menu* menu) { if(item && item->icon) { icon_animation_start(item->icon); } - return true; - }); + }, + true); } static void menu_process_ok(Menu* menu) { MenuItem* item = NULL; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { if(model->position < MenuItemArray_size(model->items)) { item = MenuItemArray_get(model->items, model->position); } - return true; - }); + }, + true); if(item && item->callback) { item->callback(item->callback_context, item->index); } diff --git a/applications/services/gui/modules/popup.c b/applications/services/gui/modules/popup.c index b3cb5e53..08e8d8c2 100644 --- a/applications/services/gui/modules/popup.c +++ b/applications/services/gui/modules/popup.c @@ -124,7 +124,9 @@ Popup* popup_alloc() { view_set_exit_callback(popup->view, popup_stop_timer); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->header.text = NULL; model->header.x = 0; model->header.y = 0; @@ -140,8 +142,8 @@ Popup* popup_alloc() { model->icon.x = 0; model->icon.y = 0; model->icon.icon = NULL; - return true; - }); + }, + true); return popup; } @@ -176,14 +178,16 @@ void popup_set_header( Align vertical) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->header.text = text; model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; model->header.vertical = vertical; - return true; - }); + }, + true); } void popup_set_text( @@ -195,25 +199,29 @@ void popup_set_text( Align vertical) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->text.text = text; model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; model->text.vertical = vertical; - return true; - }); + }, + true); } void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, const Icon* icon) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->icon.x = x; model->icon.y = y; model->icon.icon = icon; - return true; - }); + }, + true); } void popup_set_timeout(Popup* popup, uint32_t timeout_in_ms) { @@ -233,12 +241,14 @@ void popup_reset(Popup* popup) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { memset(&model->header, 0, sizeof(model->header)); memset(&model->text, 0, sizeof(model->text)); memset(&model->icon, 0, sizeof(model->icon)); - return false; - }); + }, + false); popup->callback = NULL; popup->context = NULL; popup->timer_enabled = false; diff --git a/applications/services/gui/modules/submenu.c b/applications/services/gui/modules/submenu.c index 8d40d97b..94959877 100644 --- a/applications/services/gui/modules/submenu.c +++ b/applications/services/gui/modules/submenu.c @@ -128,13 +128,15 @@ Submenu* submenu_alloc() { view_set_input_callback(submenu->view, submenu_view_input_callback); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { SubmenuItemArray_init(model->items); model->position = 0; model->window_position = 0; model->header = NULL; - return true; - }); + }, + true); return submenu; } @@ -143,10 +145,7 @@ void submenu_free(Submenu* submenu) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { - SubmenuItemArray_clear(model->items); - return true; - }); + submenu->view, SubmenuModel * model, { SubmenuItemArray_clear(model->items); }, true); view_free(submenu->view); free(submenu); } @@ -167,32 +166,38 @@ void submenu_add_item( furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { item = SubmenuItemArray_push_new(model->items); item->label = label; item->index = index; item->callback = callback; item->callback_context = callback_context; - return true; - }); + }, + true); } void submenu_reset(Submenu* submenu) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { SubmenuItemArray_reset(model->items); model->position = 0; model->window_position = 0; model->header = NULL; - return true; - }); + }, + true); } void submenu_set_selected_item(Submenu* submenu, uint32_t index) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint32_t position = 0; SubmenuItemArray_it_t it; for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it); @@ -225,14 +230,15 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) { (SubmenuItemArray_size(model->items) - items_on_screen); } } - - return true; - }); + }, + true); } void submenu_process_up(Submenu* submenu) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint8_t items_on_screen = model->header ? 3 : 4; if(model->position > 0) { model->position--; @@ -246,13 +252,15 @@ void submenu_process_up(Submenu* submenu) { model->window_position = model->position - (items_on_screen - 1); } } - return true; - }); + }, + true); } void submenu_process_down(Submenu* submenu) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint8_t items_on_screen = model->header ? 3 : 4; if(model->position < (SubmenuItemArray_size(model->items) - 1)) { model->position++; @@ -265,20 +273,22 @@ void submenu_process_down(Submenu* submenu) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } void submenu_process_ok(Submenu* submenu) { SubmenuItem* item = NULL; with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { if(model->position < (SubmenuItemArray_size(model->items))) { item = SubmenuItemArray_get(model->items, model->position); } - return true; - }); + }, + true); if(item && item->callback) { item->callback(item->callback_context, item->index); @@ -289,8 +299,5 @@ void submenu_set_header(Submenu* submenu, const char* header) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { - model->header = header; - return true; - }); + submenu->view, SubmenuModel * model, { model->header = header; }, true); } diff --git a/applications/services/gui/modules/text_box.c b/applications/services/gui/modules/text_box.c index 65ee2830..99d7d04f 100644 --- a/applications/services/gui/modules/text_box.c +++ b/applications/services/gui/modules/text_box.c @@ -21,20 +21,24 @@ typedef struct { static void text_box_process_down(TextBox* text_box) { with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { if(model->scroll_pos < model->scroll_num - 1) { model->scroll_pos++; // Search next line start while(*model->text_pos++ != '\n') ; } - return true; - }); + }, + true); } static void text_box_process_up(TextBox* text_box) { with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { if(model->scroll_pos > 0) { model->scroll_pos--; // Reach last symbol of previous line @@ -46,8 +50,8 @@ static void text_box_process_up(TextBox* text_box) { model->text_pos++; } } - return true; - }); + }, + true); } static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { @@ -137,13 +141,15 @@ TextBox* text_box_alloc() { view_set_input_callback(text_box->view, text_box_view_input_callback); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = NULL; model->text_formatted = furi_string_alloc_set(""); model->formatted = false; model->font = TextBoxFontText; - return true; - }); + }, + true); return text_box; } @@ -152,10 +158,7 @@ void text_box_free(TextBox* text_box) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - furi_string_free(model->text_formatted); - return true; - }); + text_box->view, TextBoxModel * model, { furi_string_free(model->text_formatted); }, true); view_free(text_box->view); free(text_box); } @@ -169,13 +172,15 @@ void text_box_reset(TextBox* text_box) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = NULL; furi_string_set(model->text_formatted, ""); model->font = TextBoxFontText; model->focus = TextBoxFocusStart; - return true; - }); + }, + true); } void text_box_set_text(TextBox* text_box, const char* text) { @@ -183,31 +188,27 @@ void text_box_set_text(TextBox* text_box, const char* text) { furi_assert(text); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = text; furi_string_reset(model->text_formatted); furi_string_reserve(model->text_formatted, strlen(text)); model->formatted = false; - return true; - }); + }, + true); } void text_box_set_font(TextBox* text_box, TextBoxFont font) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - model->font = font; - return true; - }); + text_box->view, TextBoxModel * model, { model->font = font; }, true); } void text_box_set_focus(TextBox* text_box, TextBoxFocus focus) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - model->focus = focus; - return true; - }); + text_box->view, TextBoxModel * model, { model->focus = focus; }, true); } diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index d7e00940..79fa8772 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -429,10 +429,10 @@ void text_input_timer_callback(void* context) { TextInput* text_input = context; with_view_model( - text_input->view, (TextInputModel * model) { - model->valadator_message_visible = false; - return true; - }); + text_input->view, + TextInputModel * model, + { model->valadator_message_visible = false; }, + true); } TextInput* text_input_alloc() { @@ -446,10 +446,10 @@ TextInput* text_input_alloc() { text_input->timer = furi_timer_alloc(text_input_timer_callback, FuriTimerTypeOnce, text_input); with_view_model( - text_input->view, (TextInputModel * model) { - model->validator_text = furi_string_alloc(); - return false; - }); + text_input->view, + TextInputModel * model, + { model->validator_text = furi_string_alloc(); }, + false); text_input_reset(text_input); @@ -459,10 +459,10 @@ TextInput* text_input_alloc() { void text_input_free(TextInput* text_input) { furi_assert(text_input); with_view_model( - text_input->view, (TextInputModel * model) { - furi_string_free(model->validator_text); - return false; - }); + text_input->view, + TextInputModel * model, + { furi_string_free(model->validator_text); }, + false); // Send stop command furi_timer_stop(text_input->timer); @@ -477,7 +477,9 @@ void text_input_free(TextInput* text_input) { void text_input_reset(TextInput* text_input) { furi_assert(text_input); with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->text_buffer_size = 0; model->header = ""; model->selected_row = 0; @@ -491,8 +493,8 @@ void text_input_reset(TextInput* text_input) { model->validator_callback_context = NULL; furi_string_reset(model->validator_text); model->valadator_message_visible = false; - return true; - }); + }, + true); } View* text_input_get_view(TextInput* text_input) { @@ -508,7 +510,9 @@ void text_input_set_result_callback( size_t text_buffer_size, bool clear_default_text) { with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->callback = callback; model->callback_context = callback_context; model->text_buffer = text_buffer; @@ -519,8 +523,8 @@ void text_input_set_result_callback( model->selected_row = 2; model->selected_column = 8; } - return true; - }); + }, + true); } void text_input_set_validator( @@ -528,37 +532,36 @@ void text_input_set_validator( TextInputValidatorCallback callback, void* callback_context) { with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->validator_callback = callback; model->validator_callback_context = callback_context; - return true; - }); + }, + true); } TextInputValidatorCallback text_input_get_validator_callback(TextInput* text_input) { TextInputValidatorCallback validator_callback = NULL; with_view_model( - text_input->view, (TextInputModel * model) { - validator_callback = model->validator_callback; - return false; - }); + text_input->view, + TextInputModel * model, + { validator_callback = model->validator_callback; }, + false); return validator_callback; } void* text_input_get_validator_callback_context(TextInput* text_input) { void* validator_callback_context = NULL; with_view_model( - text_input->view, (TextInputModel * model) { - validator_callback_context = model->validator_callback_context; - return false; - }); + text_input->view, + TextInputModel * model, + { validator_callback_context = model->validator_callback_context; }, + false); return validator_callback_context; } void text_input_set_header_text(TextInput* text_input, const char* text) { with_view_model( - text_input->view, (TextInputModel * model) { - model->header = text; - return true; - }); + text_input->view, TextInputModel * model, { model->header = text; }, true); } diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index ec8fd3d2..acd46ee4 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -92,7 +92,9 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { void variable_item_list_set_selected_item(VariableItemList* variable_item_list, uint8_t index) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t position = index; if(position >= VariableItemArray_size(model->items)) { position = 0; @@ -112,9 +114,8 @@ void variable_item_list_set_selected_item(VariableItemList* variable_item_list, model->window_position = (VariableItemArray_size(model->items) - 4); } } - - return true; - }); + }, + true); } uint8_t variable_item_list_get_selected_item_index(VariableItemList* variable_item_list) { @@ -181,7 +182,9 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) void variable_item_list_process_up(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t items_on_screen = 4; if(model->position > 0) { model->position--; @@ -195,13 +198,15 @@ void variable_item_list_process_up(VariableItemList* variable_item_list) { model->window_position = model->position - (items_on_screen - 1); } } - return true; - }); + }, + true); } void variable_item_list_process_down(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t items_on_screen = 4; if(model->position < (VariableItemArray_size(model->items) - 1)) { model->position++; @@ -214,8 +219,8 @@ void variable_item_list_process_down(VariableItemList* variable_item_list) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model) { @@ -239,7 +244,9 @@ VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model) void variable_item_list_process_left(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItem* item = variable_item_list_get_selected_item(model); if(item->current_value_index > 0) { item->current_value_index--; @@ -247,13 +254,15 @@ void variable_item_list_process_left(VariableItemList* variable_item_list) { item->change_callback(item); } } - return true; - }); + }, + true); } void variable_item_list_process_right(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItem* item = variable_item_list_get_selected_item(model); if(item->current_value_index < (item->values_count - 1)) { item->current_value_index++; @@ -261,18 +270,20 @@ void variable_item_list_process_right(VariableItemList* variable_item_list) { item->change_callback(item); } } - return true; - }); + }, + true); } void variable_item_list_process_ok(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { if(variable_item_list->callback) { variable_item_list->callback(variable_item_list->context, model->position); } - return false; - }); + }, + false); } VariableItemList* variable_item_list_alloc() { @@ -285,12 +296,14 @@ VariableItemList* variable_item_list_alloc() { view_set_input_callback(variable_item_list->view, variable_item_list_input_callback); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_init(model->items); model->position = 0; model->window_position = 0; - return true; - }); + }, + true); return variable_item_list; } @@ -299,15 +312,17 @@ void variable_item_list_free(VariableItemList* variable_item_list) { furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_clear(model->items); - return false; - }); + }, + false); view_free(variable_item_list->view); free(variable_item_list); } @@ -316,15 +331,17 @@ void variable_item_list_reset(VariableItemList* variable_item_list) { furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_reset(model->items); - return false; - }); + }, + false); } View* variable_item_list_get_view(VariableItemList* variable_item_list) { @@ -343,7 +360,9 @@ VariableItem* variable_item_list_add( furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { item = VariableItemArray_push_new(model->items); item->label = label; item->values_count = values_count; @@ -351,8 +370,8 @@ VariableItem* variable_item_list_add( item->context = context; item->current_value_index = 0; item->current_value_text = furi_string_alloc(); - return true; - }); + }, + true); return item; } @@ -363,12 +382,14 @@ void variable_item_list_set_enter_callback( void* context) { furi_assert(callback); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { UNUSED(model); variable_item_list->callback = callback; variable_item_list->context = context; - return false; - }); + }, + false); } void variable_item_set_current_value_index(VariableItem* item, uint8_t current_value_index) { diff --git a/applications/services/gui/modules/widget.c b/applications/services/gui/modules/widget.c index 802f76e2..6153b425 100644 --- a/applications/services/gui/modules/widget.c +++ b/applications/services/gui/modules/widget.c @@ -36,7 +36,9 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) { // Call all Widget Elements input handlers with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { ElementArray_it_t it; ElementArray_it(it, model->element); while(!ElementArray_end_p(it)) { @@ -46,8 +48,8 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) { } ElementArray_next(it); } - return true; - }); + }, + true); return consumed; } @@ -61,10 +63,7 @@ Widget* widget_alloc() { view_set_input_callback(widget->view, gui_widget_view_input_callback); with_view_model( - widget->view, (GuiWidgetModel * model) { - ElementArray_init(model->element); - return true; - }); + widget->view, GuiWidgetModel * model, { ElementArray_init(model->element); }, true); return widget; } @@ -73,7 +72,9 @@ void widget_reset(Widget* widget) { furi_assert(widget); with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { ElementArray_it_t it; ElementArray_it(it, model->element); while(!ElementArray_end_p(it)) { @@ -83,8 +84,8 @@ void widget_reset(Widget* widget) { ElementArray_next(it); } ElementArray_reset(model->element); - return true; - }); + }, + true); } void widget_free(Widget* widget) { @@ -93,10 +94,7 @@ void widget_free(Widget* widget) { widget_reset(widget); // Free elements container with_view_model( - widget->view, (GuiWidgetModel * model) { - ElementArray_clear(model->element); - return true; - }); + widget->view, GuiWidgetModel * model, { ElementArray_clear(model->element); }, true); view_free(widget->view); free(widget); @@ -112,11 +110,13 @@ static void widget_add_element(Widget* widget, WidgetElement* element) { furi_assert(element); with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { element->parent = widget; ElementArray_push_back(model->element, element); - return true; - }); + }, + true); } void widget_add_string_multiline_element( diff --git a/applications/services/gui/view.h b/applications/services/gui/view.h index 5b4bf360..b40f8ded 100644 --- a/applications/services/gui/view.h +++ b/applications/services/gui/view.h @@ -211,25 +211,25 @@ void view_commit_model(View* view, bool update); #endif #ifdef __cplusplus -#define with_view_model_cpp(view, type, var, function_body) \ +#define with_view_model_cpp(view, type, var, code, update) \ { \ - type* p = static_cast(view_get_model(view)); \ - bool update = [&](type * var) function_body(p); \ + type var = static_cast(view_get_model(view)); \ + {code}; \ view_commit_model(view, update); \ } #else /** With clause for view model * * @param view View instance pointer - * @param function_body a (){} lambda declaration, executed within you - * parent function context + * @param type View model type + * @param code Code block that will be executed between model lock and unlock + * @param update Bool flag, if true, view will be updated after code block. Can be variable, so code block can decide if update is needed. * - * @return true if you want to emit view update, false otherwise */ -#define with_view_model(view, function_body) \ - { \ - void* p = view_get_model(view); \ - bool update = ({ bool __fn__ function_body __fn__; })(p); \ - view_commit_model(view, update); \ +#define with_view_model(view, type, code, update) \ + { \ + type = view_get_model(view); \ + {code}; \ + view_commit_model(view, update); \ } #endif diff --git a/applications/services/power/power_service/views/power_off.c b/applications/services/power/power_service/views/power_off.c index 398ebe4a..b0046325 100644 --- a/applications/services/power/power_service/views/power_off.c +++ b/applications/services/power/power_service/views/power_off.c @@ -87,19 +87,13 @@ View* power_off_get_view(PowerOff* power_off) { void power_off_set_time_left(PowerOff* power_off, uint8_t time_left) { furi_assert(power_off); with_view_model( - power_off->view, (PowerOffModel * model) { - model->time_left_sec = time_left; - return true; - }); + power_off->view, PowerOffModel * model, { model->time_left_sec = time_left; }, true); } PowerOffResponse power_off_get_response(PowerOff* power_off) { furi_assert(power_off); PowerOffResponse response; with_view_model( - power_off->view, (PowerOffModel * model) { - response = model->response; - return false; - }); + power_off->view, PowerOffModel * model, { response = model->response; }, false); return response; } diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index aa3a1e96..1a8bc71e 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -119,8 +119,8 @@ void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data) { furi_assert(battery_info); furi_assert(data); with_view_model( - battery_info->view, (BatteryInfoModel * model) { - memcpy(model, data, sizeof(BatteryInfoModel)); - return true; - }); + battery_info->view, + BatteryInfoModel * model, + { memcpy(model, data, sizeof(BatteryInfoModel)); }, + true); } diff --git a/applications/system/updater/views/updater_main.c b/applications/system/updater/views/updater_main.c index 8d6694d8..5ed3c70a 100644 --- a/applications/system/updater/views/updater_main.c +++ b/applications/system/updater/views/updater_main.c @@ -28,22 +28,25 @@ void updater_main_model_set_state( const char* message, uint8_t progress, bool failed) { + bool update = false; with_view_model( - main_view->view, (UpdaterProgressModel * model) { + main_view->view, + UpdaterProgressModel * model, + { model->failed = failed; model->progress = progress; if(furi_string_cmp_str(model->status, message)) { furi_string_set(model->status, message); model->rendered_progress = progress; - return true; - } - if((model->rendered_progress > progress) || - ((progress - model->rendered_progress) > PROGRESS_RENDER_STEP)) { + update = true; + } else if( + (model->rendered_progress > progress) || + ((progress - model->rendered_progress) > PROGRESS_RENDER_STEP)) { model->rendered_progress = progress; - return true; + update = true; } - return false; - }); + }, + update); } View* updater_main_get_view(UpdaterMainView* main_view) { @@ -104,10 +107,10 @@ UpdaterMainView* updater_main_alloc() { view_allocate_model(main_view->view, ViewModelTypeLocking, sizeof(UpdaterProgressModel)); with_view_model( - main_view->view, (UpdaterProgressModel * model) { - model->status = furi_string_alloc_set("Waiting for SD card"); - return true; - }); + main_view->view, + UpdaterProgressModel * model, + { model->status = furi_string_alloc_set("Waiting for SD card"); }, + true); view_set_context(main_view->view, main_view); view_set_input_callback(main_view->view, updater_main_input); @@ -119,10 +122,7 @@ UpdaterMainView* updater_main_alloc() { void updater_main_free(UpdaterMainView* main_view) { furi_assert(main_view); with_view_model( - main_view->view, (UpdaterProgressModel * model) { - furi_string_free(model->status); - return false; - }); + main_view->view, UpdaterProgressModel * model, { furi_string_free(model->status); }, false); view_free(main_view->view); free(main_view); } From a1ede0a2fcbbf237a9d239e24001874476fd5c41 Mon Sep 17 00:00:00 2001 From: Roland Kammerer Date: Sat, 8 Oct 2022 19:56:56 +0200 Subject: [PATCH 30/49] BadUSB: add SYSRQ keys (#1460) This allows sending of SysRq keys[1]. This then for example allows sending the well known 'reisub' commands to safely reboot a otherwise frozen Linux box. Or obviously any of the other magic keys. The advantage compared to sending it to /proc/sysrq-trigger is that one does not need a shell and depending on how broken the system is, one might not even be able to get a new shell. The SysRq keys still work. The cost is adding a new/"non-standard" keyword, IMO it is worth it. Example: DEFAULTDELAY 200 DELAY 1000 SYSRQ r SYSRQ e SYSRQ i SYSRQ s SYSRQ u SYSRQ b If one really wants to test it, I suggest h(elp) or w(ait). [1] https://en.wikipedia.org/wiki/Magic_SysRq_key Co-authored-by: Aleksandr Kutuzov --- applications/main/bad_usb/bad_usb_script.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 1e3edf40..78aba88e 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -109,6 +109,7 @@ static const char ducky_cmd_string[] = {"STRING "}; static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "}; static const char ducky_cmd_defdelay_2[] = {"DEFAULTDELAY "}; static const char ducky_cmd_repeat[] = {"REPEAT "}; +static const char ducky_cmd_sysrq[] = {"SYSRQ "}; static const char ducky_cmd_altchar[] = {"ALTCHAR "}; static const char ducky_cmd_altstr_1[] = {"ALTSTRING "}; @@ -292,6 +293,14 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt); return (state) ? (0) : SCRIPT_STATE_ERROR; + } else if(strncmp(line_tmp, ducky_cmd_sysrq, strlen(ducky_cmd_sysrq)) == 0) { + // SYSRQ + line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; + uint16_t key = ducky_get_keycode(line_tmp, true); + furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); + furi_hal_hid_kb_press(key); + furi_hal_hid_kb_release_all(); + return (0); } else { // Special keys + modifiers uint16_t key = ducky_get_keycode(line_tmp, false); From 3fd30a913231ab33c3005b164b1fdae3772bc195 Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sat, 8 Oct 2022 23:20:15 -0700 Subject: [PATCH 31/49] docs: update on FAP build process (#1852) --- documentation/AppsOnSDCard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/AppsOnSDCard.md b/documentation/AppsOnSDCard.md index 552be13e..aff8314d 100644 --- a/documentation/AppsOnSDCard.md +++ b/documentation/AppsOnSDCard.md @@ -13,7 +13,7 @@ FAPs are created and developed the same way as internal applications that are pa To build your application as a FAP, just create a folder with your app's source code in `applications_user`, then write its code the way you'd do when creating a regular built-in application. Then configure its `application.fam` manifest — and set its *apptype* to FlipperAppType.EXTERNAL. See [Application Manifests](./AppManifests.md#application-definition) for more details. - * To build your application, run `./fbt firmware_{APPID}`, where APPID is your application's ID in its manifest. + * To build your application, run `./fbt fap_{APPID}`, where APPID is your application's ID in its manifest. * To build your app, then upload it over USB & run it on Flipper, use `./fbt launch_app APPSRC=applications/path/to/app`. This command is configured in default [VSCode profile](../.vscode/ReadMe.md) as "Launch App on Flipper" build action (Ctrl+Shift+B menu). * To build all FAPs, run `./fbt plugin_dist`. From 906124b09192947db9c3ad52a1c7911af0d3b347 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Mon, 10 Oct 2022 08:43:15 +0400 Subject: [PATCH 32/49] [FL-2886] SubGhz: fix text overlap in read (#1853) --- applications/main/subghz/subghz_i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index acf07bc1..ac1036d0 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -60,7 +60,7 @@ void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, Furi subghz->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { - furi_string_printf(modulation, "%2s", furi_string_get_cstr(subghz->txrx->preset->name)); + furi_string_printf(modulation, "%.2s", furi_string_get_cstr(subghz->txrx->preset->name)); } } From 04f5ad83f89bfd9c2ecbb29a12399ad9b8f64183 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Tue, 11 Oct 2022 19:54:35 +0300 Subject: [PATCH 33/49] [FL-2828] Dolphin score points update #1809 --- .../main/gpio/scenes/gpio_scene_start.c | 2 ++ .../common/infrared_scene_universal_common.c | 2 +- .../main/nfc/scenes/nfc_scene_detect_reader.c | 2 +- .../nfc/scenes/nfc_scene_mf_classic_menu.c | 3 ++ ...nfc_scene_mf_ultralight_read_auth_result.c | 4 ++- .../main/nfc/scenes/nfc_scene_set_uid.c | 2 +- applications/plugins/bt_hid_app/bt_hid.c | 3 ++ applications/plugins/snake_game/snake_game.c | 3 ++ .../services/dolphin/helpers/dolphin_deed.c | 28 +++++++++++++------ .../services/dolphin/helpers/dolphin_deed.h | 14 ++++++++-- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/applications/main/gpio/scenes/gpio_scene_start.c b/applications/main/gpio/scenes/gpio_scene_start.c index 41b74523..72992294 100644 --- a/applications/main/gpio/scenes/gpio_scene_start.c +++ b/applications/main/gpio/scenes/gpio_scene_start.c @@ -1,6 +1,7 @@ #include "../gpio_app_i.h" #include "furi_hal_power.h" #include "furi_hal_usb.h" +#include enum GpioItem { GpioItemUsbUart, @@ -88,6 +89,7 @@ bool gpio_scene_start_on_event(void* context, SceneManagerEvent event) { } else if(event.event == GpioStartEventUsbUart) { scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemUsbUart); if(!furi_hal_usb_is_locked()) { + DOLPHIN_DEED(DolphinDeedGpioUartBridge); scene_manager_next_scene(app->scene_manager, GpioSceneUsbUart); } else { scene_manager_next_scene(app->scene_manager, GpioSceneUsbUartCloseRpc); diff --git a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c index f823ca93..d55d8d0a 100644 --- a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c +++ b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c @@ -70,7 +70,7 @@ bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent e uint32_t record_count; if(infrared_brute_force_start( brute_force, infrared_custom_event_get_value(event.event), &record_count)) { - DOLPHIN_DEED(DolphinDeedIrBruteForce); + DOLPHIN_DEED(DolphinDeedIrSend); infrared_scene_universal_common_show_popup(infrared, record_count); } else { scene_manager_next_scene(scene_manager, InfraredSceneErrorDatabases); diff --git a/applications/main/nfc/scenes/nfc_scene_detect_reader.c b/applications/main/nfc/scenes/nfc_scene_detect_reader.c index e8c2b5ee..f0177f9c 100644 --- a/applications/main/nfc/scenes/nfc_scene_detect_reader.c +++ b/applications/main/nfc/scenes/nfc_scene_detect_reader.c @@ -26,7 +26,7 @@ void nfc_scene_detect_reader_callback(void* context) { void nfc_scene_detect_reader_on_enter(void* context) { Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcEmulate); + DOLPHIN_DEED(DolphinDeedNfcDetectReader); detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc); detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c index 76d02e01..2cba0433 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c @@ -1,4 +1,5 @@ #include "../nfc_i.h" +#include enum SubmenuIndex { SubmenuIndexSave, @@ -35,6 +36,8 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { + DOLPHIN_DEED(DolphinDeedNfcMfcAdd); + scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave); nfc->dev->format = NfcDeviceSaveFormatMifareClassic; diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c index f0c53c9b..5a690a21 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c @@ -14,7 +14,6 @@ void nfc_scene_mf_ultralight_read_auth_result_widget_callback( void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Setup dialog view FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; @@ -38,6 +37,7 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { widget_add_string_element( widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); if(mf_ul_data->auth_success) { + DOLPHIN_DEED(DolphinDeedNfcReadSuccess); furi_string_printf( temp_str, "Password: %02X %02X %02X %02X", @@ -54,6 +54,8 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { config_pages->auth_data.pack.raw[1]); widget_add_string_element( widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + } else { + DOLPHIN_DEED(DolphinDeedNfcMfulError); } furi_string_printf( temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4); diff --git a/applications/main/nfc/scenes/nfc_scene_set_uid.c b/applications/main/nfc/scenes/nfc_scene_set_uid.c index 0ff28971..9622ba21 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_set_uid.c @@ -30,7 +30,7 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventByteInputDone) { - DOLPHIN_DEED(DolphinDeedNfcAdd); + DOLPHIN_DEED(DolphinDeedNfcAddSave); if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { nfc->dev->dev_data.nfc_data = nfc->dev_edit_data; if(nfc_device_save(nfc->dev, nfc->dev->dev_name)) { diff --git a/applications/plugins/bt_hid_app/bt_hid.c b/applications/plugins/bt_hid_app/bt_hid.c index b653fb37..a470f7bc 100644 --- a/applications/plugins/bt_hid_app/bt_hid.c +++ b/applications/plugins/bt_hid_app/bt_hid.c @@ -1,6 +1,7 @@ #include "bt_hid.h" #include #include +#include #define TAG "BtHidApp" @@ -185,6 +186,8 @@ int32_t bt_hid_app(void* p) { } furi_hal_bt_start_advertising(); + DOLPHIN_DEED(DolphinDeedPluginStart); + view_dispatcher_run(app->view_dispatcher); bt_set_status_changed_callback(app->bt, NULL, NULL); diff --git a/applications/plugins/snake_game/snake_game.c b/applications/plugins/snake_game/snake_game.c index 0b665a94..283d017e 100644 --- a/applications/plugins/snake_game/snake_game.c +++ b/applications/plugins/snake_game/snake_game.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -346,6 +347,8 @@ int32_t snake_game_app(void* p) { notification_message_block(notification, &sequence_display_backlight_enforce_on); + DOLPHIN_DEED(DolphinDeedPluginGameStart); + SnakeEvent event; for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); diff --git a/applications/services/dolphin/helpers/dolphin_deed.c b/applications/services/dolphin/helpers/dolphin_deed.c index b112d82a..d3c40298 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.c +++ b/applications/services/dolphin/helpers/dolphin_deed.c @@ -18,13 +18,15 @@ static const DolphinDeedWeight dolphin_deed_weights[] = { {1, DolphinAppNfc}, // DolphinDeedNfcRead {3, DolphinAppNfc}, // DolphinDeedNfcReadSuccess {3, DolphinAppNfc}, // DolphinDeedNfcSave + {1, DolphinAppNfc}, // DolphinDeedNfcDetectReader {2, DolphinAppNfc}, // DolphinDeedNfcEmulate - {2, DolphinAppNfc}, // DolphinDeedNfcAdd + {2, DolphinAppNfc}, // DolphinDeedNfcMfcAdd + {1, DolphinAppNfc}, // DolphinDeedNfcMfulError + {1, DolphinAppNfc}, // DolphinDeedNfcAddSave {1, DolphinAppIr}, // DolphinDeedIrSend {3, DolphinAppIr}, // DolphinDeedIrLearnSuccess {3, DolphinAppIr}, // DolphinDeedIrSave - {2, DolphinAppIr}, // DolphinDeedIrBruteForce {1, DolphinAppIbutton}, // DolphinDeedIbuttonRead {3, DolphinAppIbutton}, // DolphinDeedIbuttonReadSuccess @@ -34,16 +36,24 @@ static const DolphinDeedWeight dolphin_deed_weights[] = { {3, DolphinAppBadusb}, // DolphinDeedBadUsbPlayScript {3, DolphinAppU2f}, // DolphinDeedU2fAuthorized + + {1, DolphinAppGpio}, // DolphinDeedGpioUartBridge + + {1, DolphinAppPlugin}, // DolphinDeedPluginStart + {1, DolphinAppPlugin}, // DolphinDeedPluginGameStart + {10, DolphinAppPlugin}, // DolphinDeedPluginGameWin }; static uint8_t dolphin_deed_limits[] = { - 15, // DolphinAppSubGhz - 15, // DolphinAppRfid - 15, // DolphinAppNfc - 15, // DolphinAppIr - 15, // DolphinAppIbutton - 15, // DolphinAppBadusb - 15, // DolphinAppU2f + 20, // DolphinAppSubGhz + 20, // DolphinAppRfid + 20, // DolphinAppNfc + 20, // DolphinAppIr + 20, // DolphinAppIbutton + 20, // DolphinAppBadusb + 20, // DolphinAppU2f + 20, // DolphinAppGpio + 20, // DolphinAppPlugin }; _Static_assert(COUNT_OF(dolphin_deed_weights) == DolphinDeedMAX, "dolphin_deed_weights size error"); diff --git a/applications/services/dolphin/helpers/dolphin_deed.h b/applications/services/dolphin/helpers/dolphin_deed.h index 1f63db3f..969f0d5c 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.h +++ b/applications/services/dolphin/helpers/dolphin_deed.h @@ -14,6 +14,8 @@ typedef enum { DolphinAppIbutton, DolphinAppBadusb, DolphinAppU2f, + DolphinAppGpio, + DolphinAppPlugin, DolphinAppMAX, } DolphinApp; @@ -34,13 +36,15 @@ typedef enum { DolphinDeedNfcRead, DolphinDeedNfcReadSuccess, DolphinDeedNfcSave, + DolphinDeedNfcDetectReader, DolphinDeedNfcEmulate, - DolphinDeedNfcAdd, + DolphinDeedNfcMfcAdd, + DolphinDeedNfcMfulError, + DolphinDeedNfcAddSave, DolphinDeedIrSend, DolphinDeedIrLearnSuccess, DolphinDeedIrSave, - DolphinDeedIrBruteForce, DolphinDeedIbuttonRead, DolphinDeedIbuttonReadSuccess, @@ -52,6 +56,12 @@ typedef enum { DolphinDeedU2fAuthorized, + DolphinDeedGpioUartBridge, + + DolphinDeedPluginStart, + DolphinDeedPluginGameStart, + DolphinDeedPluginGameWin, + DolphinDeedMAX, DolphinDeedTestLeft, From 2552278a3d968d02fb264698fc9c3bd1d4bdfa66 Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 11 Oct 2022 22:13:12 +0500 Subject: [PATCH 34/49] [FL-2883] NFC: bank card rework reading (#1858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: remove bank card save option * nfc: remove bank card save from nfc device * nfc: remove unused function in emv * nfc: try several times to start emv application * nfc: add AID display fallback for bank cards Co-authored-by: あく --- .../main/nfc/scenes/nfc_scene_emv_menu.c | 10 +-- .../nfc/scenes/nfc_scene_emv_read_success.c | 31 ++++++++-- lib/nfc/nfc_device.c | 34 +--------- lib/nfc/nfc_worker.c | 62 ++++++++++++------- lib/nfc/protocols/emv.c | 18 ++---- lib/nfc/protocols/emv.h | 10 +-- 6 files changed, 76 insertions(+), 89 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_emv_menu.c b/applications/main/nfc/scenes/nfc_scene_emv_menu.c index 1da630fc..eb1e1004 100644 --- a/applications/main/nfc/scenes/nfc_scene_emv_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_emv_menu.c @@ -1,7 +1,6 @@ #include "../nfc_i.h" enum SubmenuIndex { - SubmenuIndexSave, SubmenuIndexInfo, }; @@ -15,7 +14,6 @@ void nfc_scene_emv_menu_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; - submenu_add_item(submenu, "Save", SubmenuIndexSave, nfc_scene_emv_menu_submenu_callback, nfc); submenu_add_item(submenu, "Info", SubmenuIndexInfo, nfc_scene_emv_menu_submenu_callback, nfc); submenu_set_selected_item( nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmvMenu)); @@ -28,13 +26,7 @@ bool nfc_scene_emv_menu_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSave) { - nfc->dev->format = NfcDeviceSaveFormatBankCard; - // Clear device name - nfc_device_set_name(nfc->dev, ""); - scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - consumed = true; - } else if(event.event == SubmenuIndexInfo) { + if(event.event == SubmenuIndexInfo) { scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo); consumed = true; } diff --git a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c index 8b6ab160..6a0b32fa 100644 --- a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c @@ -24,12 +24,33 @@ void nfc_scene_emv_read_success_on_enter(void* context) { nfc->widget, GuiButtonTypeRight, "More", nfc_scene_emv_read_success_widget_callback, nfc); FuriString* temp_str; - temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name); - for(uint8_t i = 0; i < emv_data->number_len; i += 2) { - furi_string_cat_printf( - temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + if(emv_data->name[0] != '\0') { + temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name); + } else { + temp_str = furi_string_alloc_printf("\e#Unknown Bank Card\n"); + } + if(emv_data->number_len) { + for(uint8_t i = 0; i < emv_data->number_len; i += 2) { + furi_string_cat_printf( + temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + } + furi_string_trim(temp_str); + } else if(emv_data->aid_len) { + furi_string_cat_printf(temp_str, "Can't parse data from app\n"); + // Parse AID name + FuriString* aid_name; + aid_name = furi_string_alloc(); + if(nfc_emv_parser_get_aid_name( + nfc->dev->storage, emv_data->aid, emv_data->aid_len, aid_name)) { + furi_string_cat_printf(temp_str, "AID: %s", furi_string_get_cstr(aid_name)); + } else { + furi_string_cat_printf(temp_str, "AID: "); + for(uint8_t i = 0; i < emv_data->aid_len; i++) { + furi_string_cat_printf(temp_str, "%02X", emv_data->aid[i]); + } + } + furi_string_free(aid_name); } - furi_string_trim(temp_str); // Add expiration date if(emv_data->exp_mon) { diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index f28d4d5b..06d57a0c 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -636,35 +636,7 @@ bool nfc_device_load_mifare_df_data(FlipperFormat* file, NfcDevice* dev) { return parsed; } -static bool nfc_device_save_bank_card_data(FlipperFormat* file, NfcDevice* dev) { - bool saved = false; - EmvData* data = &dev->dev_data.emv_data; - uint32_t data_temp = 0; - - do { - // Write Bank card specific data - if(!flipper_format_write_comment_cstr(file, "Bank card specific data")) break; - if(!flipper_format_write_hex(file, "AID", data->aid, data->aid_len)) break; - if(!flipper_format_write_string_cstr(file, "Name", data->name)) break; - if(!flipper_format_write_hex(file, "Number", data->number, data->number_len)) break; - if(data->exp_mon) { - uint8_t exp_data[2] = {data->exp_mon, data->exp_year}; - if(!flipper_format_write_hex(file, "Exp data", exp_data, sizeof(exp_data))) break; - } - if(data->country_code) { - data_temp = data->country_code; - if(!flipper_format_write_uint32(file, "Country code", &data_temp, 1)) break; - } - if(data->currency_code) { - data_temp = data->currency_code; - if(!flipper_format_write_uint32(file, "Currency code", &data_temp, 1)) break; - } - saved = true; - } while(false); - - return saved; -} - +// Leave for backward compatibility bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; EmvData* data = &dev->dev_data.emv_data; @@ -1068,7 +1040,7 @@ static bool nfc_device_save_file( if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break; // Write nfc device type if(!flipper_format_write_comment_cstr( - file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic, Bank card")) + file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic")) break; nfc_device_prepare_format_string(dev, temp_str); if(!flipper_format_write_string(file, "Device type", temp_str)) break; @@ -1083,8 +1055,6 @@ static bool nfc_device_save_file( if(!nfc_device_save_mifare_ul_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { if(!nfc_device_save_mifare_df_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatBankCard) { - if(!nfc_device_save_bank_card_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { // Save data if(!nfc_device_save_mifare_classic_data(file, dev)) break; diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 73245346..55d67c65 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -233,31 +233,51 @@ static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxConte reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); } - do { - // Read card + // Bank cards require strong field to start application. If we find AID, try at least several + // times to start EMV application + uint8_t start_application_attempts = 0; + while(start_application_attempts < 3) { + if(nfc_worker->state != NfcWorkerStateRead) break; + start_application_attempts++; if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; - if(!emv_read_bank_card(tx_rx, &emv_app)) break; - // Copy data - // TODO Set EmvData to reader or like in mifare ultralight! - result->number_len = emv_app.card_number_len; - memcpy(result->number, emv_app.card_number, result->number_len); + if(emv_read_bank_card(tx_rx, &emv_app)) { + FURI_LOG_D(TAG, "Bank card number read from %d attempt", start_application_attempts); + break; + } else if(emv_app.aid_len && !emv_app.app_started) { + FURI_LOG_D( + TAG, + "AID found but failed to start EMV app from %d attempt", + start_application_attempts); + furi_hal_nfc_sleep(); + continue; + } else { + FURI_LOG_D(TAG, "Failed to find AID"); + break; + } + } + // Copy data + if(emv_app.aid_len) { result->aid_len = emv_app.aid_len; memcpy(result->aid, emv_app.aid, result->aid_len); - if(emv_app.name_found) { - memcpy(result->name, emv_app.name, sizeof(emv_app.name)); - } - if(emv_app.exp_month) { - result->exp_mon = emv_app.exp_month; - result->exp_year = emv_app.exp_year; - } - if(emv_app.country_code) { - result->country_code = emv_app.country_code; - } - if(emv_app.currency_code) { - result->currency_code = emv_app.currency_code; - } read_success = true; - } while(false); + } + if(emv_app.card_number_len) { + result->number_len = emv_app.card_number_len; + memcpy(result->number, emv_app.card_number, result->number_len); + } + if(emv_app.name_found) { + memcpy(result->name, emv_app.name, sizeof(emv_app.name)); + } + if(emv_app.exp_month) { + result->exp_mon = emv_app.exp_month; + result->exp_year = emv_app.exp_year; + } + if(emv_app.country_code) { + result->country_code = emv_app.country_code; + } + if(emv_app.currency_code) { + result->currency_code = emv_app.currency_code; + } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { reader_analyzer_stop(nfc_worker->reader_analyzer); diff --git a/lib/nfc/protocols/emv.c b/lib/nfc/protocols/emv.c index 935c9f63..e00d09e7 100644 --- a/lib/nfc/protocols/emv.c +++ b/lib/nfc/protocols/emv.c @@ -182,7 +182,7 @@ static bool emv_decode_response(uint8_t* buff, uint16_t len, EmvApplication* app return success; } -bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { +static bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { bool app_aid_found = false; const uint8_t emv_select_ppse_cmd[] = { 0x00, 0xA4, // SELECT ppse @@ -212,8 +212,8 @@ bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { return app_aid_found; } -bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { - bool select_app_success = false; +static bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { + app->app_started = false; const uint8_t emv_select_header[] = { 0x00, 0xA4, // SELECT application @@ -236,7 +236,7 @@ bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { if(furi_hal_nfc_tx_rx(tx_rx, 300)) { emv_trace(tx_rx, "Start application answer:"); if(emv_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) { - select_app_success = true; + app->app_started = true; } else { FURI_LOG_E(TAG, "Failed to read PAN or PDOL"); } @@ -244,7 +244,7 @@ bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { FURI_LOG_E(TAG, "Failed to start application"); } - return select_app_success; + return app->app_started; } static uint16_t emv_prepare_pdol(APDU* dest, APDU* src) { @@ -367,14 +367,6 @@ static bool emv_read_files(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { return card_num_read; } -bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) { - furi_assert(tx_rx); - furi_assert(emv_app); - memset(emv_app, 0, sizeof(EmvApplication)); - - return emv_select_ppse(tx_rx, emv_app); -} - bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) { furi_assert(tx_rx); furi_assert(emv_app); diff --git a/lib/nfc/protocols/emv.h b/lib/nfc/protocols/emv.h index b5a0c574..0ccf7c3e 100644 --- a/lib/nfc/protocols/emv.h +++ b/lib/nfc/protocols/emv.h @@ -45,6 +45,7 @@ typedef struct { uint8_t priority; uint8_t aid[16]; uint8_t aid_len; + bool app_started; char name[32]; bool name_found; uint8_t card_number[10]; @@ -68,15 +69,6 @@ typedef struct { */ bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app); -/** Search for EMV Application - * - * @param tx_rx FuriHalNfcTxRxContext instance - * @param emv_app EmvApplication instance - * - * @return true on success - */ -bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app); - /** Emulate bank card * @note Answer to application selection and PDOL * From b3d95233224f61778413faf6d6455b96b7cac4ed Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Wed, 12 Oct 2022 19:31:25 +0400 Subject: [PATCH 35/49] Github actions on kubernetes runners (#1861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change toolchain path and runner tag * fix check_submdules.yml * try to fix errors * create .ssh directory * fix toolchain path * add empty line for test * testing 3 k8s nodes speed * Test speed again * change tag, move reindex job * bring reindex.yml back * fix build.yml * fix reindex.yml Co-authored-by: あく --- .github/workflows/amap_analyse.yml | 3 +++ .github/workflows/build.yml | 8 +++++--- .github/workflows/check_submodules.yml | 1 + .github/workflows/lint_c.yml | 2 +- .github/workflows/lint_python.yml | 2 +- .github/workflows/pvs_studio.yml | 6 ++++-- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/amap_analyse.yml b/.github/workflows/amap_analyse.yml index 6be99c9d..a50c5436 100644 --- a/.github/workflows/amap_analyse.yml +++ b/.github/workflows/amap_analyse.yml @@ -62,6 +62,8 @@ jobs: - name: 'Download build artifacts' run: | + mkdir -p ~/.ssh + ssh-keyscan -p ${{ secrets.RSYNC_DEPLOY_PORT }} -H ${{ secrets.RSYNC_DEPLOY_HOST }} > ~/.ssh/known_hosts echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key; chmod 600 ./deploy_key; rsync -avzP \ @@ -97,3 +99,4 @@ jobs: ${{ secrets.AMAP_MARIADB_PORT }} \ ${{ secrets.AMAP_MARIADB_DATABASE }} \ artifacts/flipper-z-f7-firmware-$SUFFIX.elf.map.all + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15b3966a..1304c5d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,7 +62,7 @@ jobs: run: | set -e for TARGET in ${TARGETS}; do - FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW="$(echo "${TARGET}" | sed 's/f//')" \ + FBT_TOOLCHAIN_PATH=/runner/_work ./fbt TARGET_HW="$(echo "${TARGET}" | sed 's/f//')" \ updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} done @@ -97,7 +97,7 @@ jobs: - name: 'Bundle core2 firmware' if: ${{ !github.event.pull_request.head.repo.fork }} run: | - FBT_TOOLCHAIN_PATH=/opt ./fbt copro_dist + FBT_TOOLCHAIN_PATH=/runner/_work ./fbt copro_dist tar czpf "artifacts/flipper-z-any-core2_firmware-${SUFFIX}.tgz" -C assets core2_firmware - name: 'Copy .map file' @@ -107,6 +107,8 @@ jobs: - name: 'Upload artifacts to update server' if: ${{ !github.event.pull_request.head.repo.fork }} run: | + mkdir -p ~/.ssh + ssh-keyscan -p ${{ secrets.RSYNC_DEPLOY_PORT }} -H ${{ secrets.RSYNC_DEPLOY_HOST }} > ~/.ssh/known_hosts echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key; chmod 600 ./deploy_key; rsync -avzP --delete --mkpath \ @@ -174,6 +176,6 @@ jobs: run: | set -e for TARGET in ${TARGETS}; do - FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW="$(echo "${TARGET}" | sed 's/f//')" \ + FBT_TOOLCHAIN_PATH=/runner/_work ./fbt TARGET_HW="$(echo "${TARGET}" | sed 's/f//')" \ updater_package DEBUG=0 COMPACT=1 done diff --git a/.github/workflows/check_submodules.yml b/.github/workflows/check_submodules.yml index e4178c3c..eba4affc 100644 --- a/.github/workflows/check_submodules.yml +++ b/.github/workflows/check_submodules.yml @@ -27,6 +27,7 @@ jobs: - name: 'Check protobuf branch' run: | + git submodule update --init SUB_PATH="assets/protobuf"; SUB_BRANCH="dev"; SUB_COMMITS_MIN=40; diff --git a/.github/workflows/lint_c.yml b/.github/workflows/lint_c.yml index becafcab..23dc6c69 100644 --- a/.github/workflows/lint_c.yml +++ b/.github/workflows/lint_c.yml @@ -30,7 +30,7 @@ jobs: - name: 'Check code formatting' id: syntax_check - run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint + run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/runner/_work ./fbt lint - name: Report code formatting errors if: failure() && steps.syntax_check.outputs.errors && github.event.pull_request diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index d5ff834e..c2f09211 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -26,4 +26,4 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: 'Check code formatting' - run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint_py + run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/runner/_work ./fbt lint_py diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 98157555..e3d5fc13 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -57,11 +57,11 @@ jobs: - name: 'Generate compile_comands.json' run: | - FBT_TOOLCHAIN_PATH=/opt ./fbt COMPACT=1 version_json proto_ver icons firmware_cdb dolphin_internal dolphin_blocking + FBT_TOOLCHAIN_PATH=/runner/_work ./fbt COMPACT=1 version_json proto_ver icons firmware_cdb dolphin_internal dolphin_blocking - name: 'Static code analysis' run: | - FBT_TOOLCHAIN_PATH=/opt source scripts/toolchain/fbtenv.sh + FBT_TOOLCHAIN_PATH=/runner/_work source scripts/toolchain/fbtenv.sh pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} pvs-studio-analyzer analyze \ @.pvsoptions \ @@ -76,6 +76,8 @@ jobs: - name: 'Upload artifacts to update server' if: ${{ !github.event.pull_request.head.repo.fork }} run: | + mkdir -p ~/.ssh + ssh-keyscan -p ${{ secrets.RSYNC_DEPLOY_PORT }} -H ${{ secrets.RSYNC_DEPLOY_HOST }} > ~/.ssh/known_hosts echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key; chmod 600 ./deploy_key; rsync -avrzP --mkpath \ From 92a738bf7784ea13208a532322a1e96d4d3ff274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 13 Oct 2022 00:39:39 +0900 Subject: [PATCH 36/49] Dolphin: add L1_Painting animation (#1863) Co-authored-by: hedger --- .../external/L1_Painting_128x64/frame_0.png | Bin 0 -> 1607 bytes .../external/L1_Painting_128x64/frame_1.png | Bin 0 -> 1618 bytes .../external/L1_Painting_128x64/frame_10.png | Bin 0 -> 1606 bytes .../external/L1_Painting_128x64/frame_11.png | Bin 0 -> 1579 bytes .../external/L1_Painting_128x64/frame_2.png | Bin 0 -> 1608 bytes .../external/L1_Painting_128x64/frame_3.png | Bin 0 -> 1585 bytes .../external/L1_Painting_128x64/frame_4.png | Bin 0 -> 1600 bytes .../external/L1_Painting_128x64/frame_5.png | Bin 0 -> 1609 bytes .../external/L1_Painting_128x64/frame_6.png | Bin 0 -> 1588 bytes .../external/L1_Painting_128x64/frame_7.png | Bin 0 -> 1630 bytes .../external/L1_Painting_128x64/frame_8.png | Bin 0 -> 1623 bytes .../external/L1_Painting_128x64/frame_9.png | Bin 0 -> 1614 bytes .../external/L1_Painting_128x64/meta.txt | 32 ++++++++++++++++++ assets/dolphin/external/manifest.txt | 7 ++++ .../dolphin/L1_Painting_128x64/frame_0.bm | Bin 0 -> 763 bytes .../dolphin/L1_Painting_128x64/frame_1.bm | Bin 0 -> 764 bytes .../dolphin/L1_Painting_128x64/frame_10.bm | Bin 0 -> 772 bytes .../dolphin/L1_Painting_128x64/frame_11.bm | Bin 0 -> 767 bytes .../dolphin/L1_Painting_128x64/frame_2.bm | Bin 0 -> 762 bytes .../dolphin/L1_Painting_128x64/frame_3.bm | Bin 0 -> 759 bytes .../dolphin/L1_Painting_128x64/frame_4.bm | Bin 0 -> 759 bytes .../dolphin/L1_Painting_128x64/frame_5.bm | Bin 0 -> 757 bytes .../dolphin/L1_Painting_128x64/frame_6.bm | Bin 0 -> 785 bytes .../dolphin/L1_Painting_128x64/frame_7.bm | Bin 0 -> 803 bytes .../dolphin/L1_Painting_128x64/frame_8.bm | Bin 0 -> 797 bytes .../dolphin/L1_Painting_128x64/frame_9.bm | Bin 0 -> 777 bytes .../dolphin/L1_Painting_128x64/meta.txt | 32 ++++++++++++++++++ assets/resources/dolphin/manifest.txt | 7 ++++ 28 files changed, 78 insertions(+) create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_0.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_1.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_10.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_11.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_2.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_3.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_4.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_5.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_6.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_7.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_8.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/frame_9.png create mode 100644 assets/dolphin/external/L1_Painting_128x64/meta.txt create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_10.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_11.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_4.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_5.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_6.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_7.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_8.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/frame_9.bm create mode 100644 assets/resources/dolphin/L1_Painting_128x64/meta.txt diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_0.png b/assets/dolphin/external/L1_Painting_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b2f9bc775cc50b2914c5b6db268535d21d006399 GIT binary patch literal 1607 zcmV-N2Dtf&P) z&R|;roM609XshvMfQPl!_%gu5+G?~b5mwP??26yDNr}6iSj7YttnjWdD1wOdS5O_% zXQZKO99ILJqQ|LiHIAzRPSNAkwi;gscvxGFF9STR)%FsB93LtI`{Yq1YD)EIcL%`< zPP{V>NH%FiWO|c38l|97knnzMbE{Ip3C^o~Ku0x{V zTN_!|TVwSJo~Z>Q?ELFslfeK#6yZ2O>UgO{gaM+4j;=eBfd`z4W9vRD0 zxPOjP50|gCnK@AzPiKHxa5+#4(0=cNWFG>Q=6_KYxJHx#PDi8$$iTe?c&ER$rqb3d zcu=8vEdqp2Pr~Y;ePsl4<3*K11EtI6>q$90NKjM;>n^NverwIH0VJg1_&hWfWHulf zL33cH0D5{Fm_?VTrU2<^SrB@Pjuy;rK&G86qBjQ=Qm-m`Bj;xe@IL3oA9f%)KeOPh zp(|*61p};Nk?J5N`Zr*H0$?PZ=j6)hp|R2vg1AjTR!>?@xf0cC?cvDOR(MHaFrN)PCMApwjj)&14vl;Q2vg{(qvjjmuV&<)9U9eCu<(rukCMJ4dCu%Gc>1Yr6ew7=`*qv#Z9jzNn%BWI2~p zHZp%?eXe%?bzQ%Hh$h|xoX7w~{+C7`Eqma> z;uTz;O(JVo`@#$MqicW}Ser&2Z#fL93A9>3qkB)z4(Ah1z6sokNF^bG#Q&QO3|@^))M;ugTY*!QTaNB|i}eTa1j&17#Et zD4U>d7SMYDMCm7E=44wZd8Uq-WdQW_69KmXzN!BWoRT?4pV2-KJ8l83HNOVv_+;lJ zRC>q$qqV?DmcmoAlP2>P_lsl!CkE$V}&J{Mk0?)lp&(E z4vBtiZ)9I;O}{3EfO!T@iIFq|KCJXa#Z08v9n_w{6;!LwSvXP=1uTWjs< z8B0@me2!8Nl`oB%HBlLNXMifG9H<0HKMz6t9Rif*e^3>;N0b3hN2CYHz`O-m+24B? zX{!nvRA^m`0HM>9usUcT8G+PzQKis88M5hqTn-Hq6f=W$7gjmH_pbK<9Nchp9a;)9 z2jGk#IWW@z-MtJ{G31FQfIFHugqEV-hS>w~vXe#h=756hHA|l7{A>e0);#FL0i@<< zHmn+Y25qlkfK@CqJ4jpm9Wd_z@PyNvoY`8*uuK4WYdxb%*cAX4Bt2)`rUu|^AXlo=iMLkokoi1M2O4M@=WEYaV#W6W z9NYe1fQCv|MQ$Yg^Nf4-%Kjk2R24kYMnwAg4$#Vulv$i&CEG~Z7;z42KkF7S)AkSK zj-GjU0<_@PGD-^+`b+~42&p7R%d8cwv&L#Uv{7s;DxNK9RT>~puOK%TJp43%G&J?*dMXqgIoK8mg?*V3kXAjzcjL+7Z$a|j2 ztGa9t8k_72f=fz(MvKTgsS%%` zt_}jJ#vBIAq9zK^>(e>lw3L2JPH zT2AK?JtWMs&#qEj>H)@qSHm-?WOT{-^qJLtM|4HuazI7gI z;7s$FDOJ0CadZ!miRdyVI!s~NKw=dBoXX^Lq<~!Mi{AU$3=lD7K)0{+`La&dgKq^W6^K9q8UcbLs`zQuz&Hkm4N6UOZfA2M1 zNFSlCmE_Fwg%!BvTL5yP-H3F>+FaiFWo2p4REG%rqP~!1db*ds3ET-UL-{*TM=wZt zKY-|Gl@#xpwD%65q;3IR(UtHrRC-6}SefmidOk0Bw4k2ld}RMH18`+m!^+SBNv}xb z=K%>CsZ=1DuI;mm0l2L~41gYNH;|gkpCRB5MQV3e_Rx=(or?1{_T$fB2B1ow3`(P8 z%s5_?jTjbX4C~!dJpiKgX~^nIoryGoS|)4nB06N9k7j>s00ZzteKMpPK7xSHvp%Em z5M5R>K=0jVfPug0e2Od1AMFJ^SsEj#e-AK#9KLc@Isw%>x(X2nh=8vB2SGc>cI6W{ QG5`Po07*qoM6N<$f)%Lgd;kCd literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_10.png b/assets/dolphin/external/L1_Painting_128x64/frame_10.png new file mode 100644 index 0000000000000000000000000000000000000000..ae3148c323e53a435cb5d395a91dde8fca4fd0c7 GIT binary patch literal 1606 zcmV-M2D$l(P)4I23Q=PH;3&4*c%d zbzLoi-g}EaI`;n7`L(t7W_QFF9FNpf37lZOZ&)?EW|0bj4AT>g_YG?`eih(mt7Ov| zYzu%BjQ0&|HGUP~W@|Nm72sxTHTsnZD>NF1;Ga^GLU>U~gTzyARVz5bc@@sL{1Ua@pk=-Xc!?B7Jmair z5LlJOgC!3Vgc|LY8H~`ebhGg0$EH*O?s(1s?LAaT51N8A2AZXT1n)}vo_!*qd!L@M zxB!x%QKpvg2n}!bXxzO5%!1N^TEKW%y7my+PnFa9T!ar&0Zs=p17u*H0<0`YT0t~e zD9y}_5kaJ!o`lsw`#=aWX zM5ep8fmsZCVhf-K%{p+_`2*EXLQf7+a2c!UdCs5lO>5-40Br!v7{Ai6RGx}JSWy91 zRgvl-ZS6f^{sO=vjxa_9MtV38f{GacH7dgM#9)>5E&V|VYFOkXG4{`9Le{9#91`V) zel}3~9zf#Pd$0XA&~uO^Je~MaUKwPJI+J-b?@v}a|7E_gUIb|bJV6l}*&#+lg`xozg_czkB;~El(u}oo(34;Vs}-n`0bUJ&2+-q> zmH7xA>sg70tg4{#&&Y}T zCUgv}#H_K$(3q_lQKL%qciD*Yt9}o_0sSbnGE*{V_zbwwDlOK$+IT9^M_ zfR-K9NL5FzksX?$qvvUEXi68I9k{`@eUdI#5R|P=`AwjPY(=onuoZ~B4AGoumHZ4p zWMA}@vT68&_|}~=y^Lj$Z0g` zJ+8;D3b5^O12tr-O4RY%;K%#C*FG}fQ@b=!TEV!h0&M&L0W?UxSOYRgM4T_tLt241 zOmf;1Pd;o)*Gp%Bkfw@qRj|sWw9iA-`H?b?g4>5*qeJHMwSlJqM2X$tJvHk5S$(9o zLhnm^t!qU7=@~#OMb>&EMxPx(j8FlD9^b>O5T8pj>v%r0KC=u?fF#SObm2jO&JweF zWP|#7N9S`nX3O9TRJRp0^P{*;1_i?K8M_=dteW0ROQW{mdRoQ7} z*?-~lU*@%a1`^0Hp2U|%f3^Z-`u0l9>Ve?68GtImolE(1Wh>jjj6o$xGfU)|9lklP z0=x+*ID-emtn)c-S`ql?l5A8KO-BA4cUrX`5%k{w|0*~WWxGqI#yb-EvqqDG-nth_ z627M@C_J7N*LB_J6d(<3*Y)~i5^YA9)n&HNYBas;N}s6qxl0A$kcK~R?+nnkAXNuW zOM8B%9auCaKo#I5c$x1#hrk;^=|29sH)m*csw#lTD|`x|%AXPpNZ;cbOz(N%&Xann zCQJ05MsIb3hAKc*a0Ih-k<6$2v{}NEkM6NbJ1V2bqssXa{%!@}!d1a5le3_*OZ26R zK=(_I*0Nc1KqS*8nO9bTw`$&u_W+ilD~7;mAVf>Qm#tC5A%kYrF4n1q^Nc#*n=_<) z>URND`CYiK%XLcD`INqu{d6C~)0-2l{nBR@(|-hyQ=CsRGt@*4!ktX-OaDd?31kbi z+c}vd7V8FvmI!G!UAIStM2vAhp zg9hEK^R0^TJT3DjM0;JNFKVAh0>v8KR@iM-1)$IT1OFokWDyH7p8x;=07*qoM6N<$ Ef;{l{egFUf literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_11.png b/assets/dolphin/external/L1_Painting_128x64/frame_11.png new file mode 100644 index 0000000000000000000000000000000000000000..89d003d071e2cc1f55f2c13f361641f996385ece GIT binary patch literal 1579 zcmV+`2Gse9P)7$I zpU>yBCD40s=+^P^ACbw1+6gv zQuSP6^l-}vDp&iN2aiE2Xm&M?XBZ&E!cYs~3Q_~2EdY65N(9uvCH?A7FC z2B5pQfmsZBVhf-S<%eb_{)(!jNic)x%>f11t4f|1{Om1k?D?S|4se0l%&T;;q*n$j z7+@8PR3~X`?+Not07Q87nt>`Fscb$V&ddOrs}p)=Rbo{pt7Pwz-v&kR}Oj- ztYozk74^mInFs?6p%NV-iDPAMgc|9737!*BTJ@5(3feiDD=Xp?iq{N~?Wb92ilTa; z?Zd zRsVaIKaJ9_vlBZqptM%YM#v1H%^{H+OY|K^_B}v319;B9sx?$#IE_}ST%5Iz0ScENSA^jp0`e-BWF%?W?aaR&-YXQU9ECvm8XHj}a z$>uPP=W< zhCFm{R{z**PW$)EpdHy(0nNbK;8)pF;g_r(nR9$M)MVdh>lEOQa z+m(6`uzL`ULUIJ+B*`u-L1ua{-y?lr84Jz!V`l&amAzWC$zz4yfB!lfk>lxD9TO|@ zZ}le7t4_CYzs;)qOVjX!W;dFaS5^Do}kQj@7ELvb|70S%X*xI~bt% zE;GOYI)trGl59m;10I?P1Cb%J0?}C@qC5TU?e75wuC9CuXiGq?)C2$k literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_2.png b/assets/dolphin/external/L1_Painting_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..8bfe6b33c57afb008d06a5b1743c5bd6164d2522 GIT binary patch literal 1608 zcmV-O2DkZ%P)nvKKoyEe&jcMz+Xpn?_N6%IuZ3H}PI zYwa`2P&JOz0H@e-YFmxtG{7l#oZ437%K#5+tMO%khqcmPBH;Z)B5(}$GEp*WJi9vy zP6*_1(q=7~$$V(FXUfbNNQgA}>DuU1blPMEF2l6sTSQFDsA0ltZS{Y`UKBtfe1VQI@nENfFFu5f*%b$HzL9SQAbDD_2xj6XZ8G^eGt+lu3 zEY0BYIZ8creyPojiO%tK2ABn%2Py&5&toF~4gpH@zo-gaBgz1$BccH^FmD0Y>F>RZ zv^5KwRA^m`0HM>9usUg9nF*=$qDG;KGUlf1@p)*Hpr}mNU04f0st7<+k_*nry#=Pjm0i@<< z7Myi-1#PcjfK@C~ousY(n=n5K;7v|za%RC*B5_6oWNt6$npKHanXJ-&L%$4)8h|=F z8c156qKTPxD({CRL-yT3B?Cy~d++hz24=;UH)kfpv!XKU)R~jVlZ1*{WNZZkNTT^? zPV0*xZz9xitq(=Eyl^155Y4I5*p;^gR5W`@>-pKbF}U>`DL&lART|sR8&J$c>s&;;qdqWZuuSfhJle_}a6TSn)jo z$F~0$pkd}zMQ$YgbH%-Sr9Ox-)ePRK5Rra<0<^Ltoh(kVl5eEb7zqyQKkF7y>H8OQ zN6)-F0a|ivCrV2c`b+~)2&p7R%dC~GRqeJv3+F%t;|wfj^X}8!(Z9Yp32F!KaIK$a z|MIpee-r3!E-Om3Yv9b)(py8CPg2#9Jw+#fbaIeWKl+Y2 z_-S8N^EKTvfY>eBxvXu0TL8yO(Udvu(pWx5VwBl^Xh|g{nb*fES1a0nUDuTvSmC%8 zu!7I~R5Ae)Y;^2w5`^sjyG}lfPJt#85xr5h4^&v9^X!PpdnU_HNCK(GBFLPU2&&6U zBqkBOXR_^XWP?xpQ&BmKN@m z8TF0Yv}*4=W0AfE>=1%l;4NV%y+fZzRJ&)3)*l%&a|?*#Xbq6c=vhhx$5Z`4pV4`w z=X4F;hpxRN7QOfUE#Ph~AYs-fL=;-589j|sA4$zu$3n9GH5>fXlAtyFcM7zR6eKI~ zmAZ$|A$_h6{&iiy{5{+x~@seTfp)wX$pQAOv45Uq? zN$ZsY>p5RXduG{E84GW%$9)fg;0|`86w7UiCgM&uPH6yiBX`3~REw6;5>d52?OSyq z5vB>>0tR*kU)vmdimZ82TBbBE1&Y3-b09Wa>#Sg99>b6ZKsQziD=1kzG<_gFmx8MG ztFoaY_{d&b3upjpS;9;X= z(-~|FfD?@O31cR63013YZ3#+LyeHcDrSfX@##fn%{3iIP&|+1){K zf)np71Ds8IYfbegbu>yrUXalD+Tm7}f)kuq;e2kNOquve$jew^38spnYWoQsYIHLIY*Uru%U@G)PcX2J0@Ya(?e!?*TZt;pjTF6l4y- z89{PjrU80-8JNY8Czb&2XxBvUcmsXSfn~gTl*U@KLOwgr!_gV;i@KarU%H}UeGQlsN&ijifnn|KyD$LQKhvjZwYAA>;zsWJz;0qe^W5?`dFjwFR=|mt4Lr~z)FVbmDLIoasCK^ zihAg+M>8xF0Nz^9s1kMsfCWj^PO*}0q-=~h2eqGd3#hdH3%R3b z-kks~xV4PZ0);-)zym@mNzpQE1#8u~?a#tFkcM#v7PEQxX>RCWUz`Mc2X1g}o~Hlu zu_=EO=p8QGlxWw$nX9F@ha^wxsv~EL+?pcSwk=L4BmDOORp8l!_8;T3wI=eOXY#5p z+k?g?yMo}B5}?r{vQBD*C`D(Sug&#zK^r+urge?o#Q?ViKqlKH)<7Ij*J=$FQZl08 zUAxp!TEX~FFaU>E5BblCEJ>zj^lWeA(f61`f2ILJ_m)cI$1;EhiQc8mL9%|#9Wr>f zud4Z4-!g#cE$O*zY=K(<$I7NDlkL)4zD8n{*>h+?B?Xx`$0}DV#(rJbm04I}xD~LR z&*xM!0pe_Q?Q9T)^!|UJd=#Amtw}`sjjD5?jU_5)hfm%!QFcNQNHrEgCR-w?E-MkA zMDU)8w!4vaKAlgS%2`x0B&1P-^Q5@X^q#}Bj5|z?HpCRYBZW)pd zxf6HzqW7M^1>D^WNSM`0Y6`W0;PBQ+`$+6VyZLHgNK7={0}Mf@K&yvQx*zbIFV)}~ z7Ru7Uq$`&zy-(i)PI5YhrWeib8Rzp-z~^b1NcTq0Q0WV6&e1)<45ULNPS@sX&X?p! z0fDj)eP7`VZ?CCu0#8L%lcs&vWJz<-XZ-yxpQIRoE4ms;hHC4y8jdz;8k1CHpLVV) z=Og=v8GtLh3P>Y{I5DzDT5mO3Uh{`!x+ZTG1N=$g7PtjSir?7~ddx5zu%3gt!y@}= zcFP6<-& z_O}Kw06)~H!eS4}z}9E literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_4.png b/assets/dolphin/external/L1_Painting_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..d39cddea149d9f0f70b259df9151940b13736955 GIT binary patch literal 1600 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 Hu0mjfn3n@9 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_6.png b/assets/dolphin/external/L1_Painting_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..3f492eab5e1f5c86ae35be949cb4af2cc7d78776 GIT binary patch literal 1588 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/frame_8.png b/assets/dolphin/external/L1_Painting_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..a44a7315da3d4a550f3453dd8d221dd9131bee83 GIT binary patch literal 1623 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 M07*qoM6N<$g29Fd+5i9m literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Painting_128x64/meta.txt b/assets/dolphin/external/L1_Painting_128x64/meta.txt new file mode 100644 index 00000000..6964b479 --- /dev/null +++ b/assets/dolphin/external/L1_Painting_128x64/meta.txt @@ -0,0 +1,32 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 9 +Active frames: 13 +Frames order: 0 1 2 3 4 5 2 3 4 10 6 7 8 7 8 7 8 7 8 9 10 11 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 57 +Y: 24 +Text: No mistakes, +AlignH: Left +AlignV: Center +StartFrame: 11 +EndFrame: 14 + +Slot: 0 +X: 57 +Y: 21 +Text: only happy\n accidents +AlignH: Left +AlignV: Center +StartFrame: 15 +EndFrame: 18 \ No newline at end of file diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index 19706067..6bf6957c 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -85,6 +85,13 @@ Min level: 1 Max level: 3 Weight: 3 +Name: L1_Painting_128x64 +Min butthurt: 0 +Max butthurt: 7 +Min level: 1 +Max level: 3 +Weight: 6 + Name: L3_Hijack_radio_128x64 Min butthurt: 0 Max butthurt: 8 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_0.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..2694219ef9eefda1c8d52e3ce99cd1284d0d8d31 GIT binary patch literal 763 zcmVrBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fOpudH`hRdR4*Wh)9!NbZ zIh_adpMUy@#sNqNo&#Y~)W$gb{ZIfw<%qwoMxiOILU335r~rTTb_l@W@(qL~OfVgI zeCQ0(z(yk#h%A5}HsJXK%7K8eLA8=uh6f3v53GX$#DLYLaheS-${$vcoX1}goXBPx zfcn5D6RZVhBl(EHZ3Xi-3W>5=-f&+BIKrB^N0FX!kSqp_gX>^~C7P% z5DX>*Z>qx=#&i!H0)Su~h%)?Z6x76{hvh|tRbb%t t!9;K;@{=FN1`k*l`~Wxltd|IW5PF(K20Q@x(4WHt2Oa_t4=MnBbU+(OFu?!- literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_1.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..3c9623d4c79a19e74bfe403f8819221e10322d62 GIT binary patch literal 764 zcmVrBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fOpudH`hRdR4*Wh)9!NbZ zIhhCZpMUy@#sNqNo&#Y~l*Tyw{ZIfw<%qwoMxiOILNHhQr~rTTb_l@W@(qM0fI1y` ze8A)2z(yk#h$uX*!SV-{0|8)zYb3Y~1`|XdSq1}%0jo&xGzwjmKCK}+j=m#7kjym! z^?*z#SPINX!x4bm3+8MX2Lcb^*g$j`sD{KoTB}mbpce}S2VsPOSgNW4AdmpFoCpp= zlK{|ap->H1s2+Iy1O_n)fLJQO(D?O1#el=WAajU_e4xSg_)+H&Ys7>;P*?zcKhxSI zGx!D&`XEGHG4|NPF3j?jV2LDx(;Sa(OSRfd<0r8I}kAEZeiLFwq0vN0iUOd2f&LEKuLdZY`8i5i< z8v%oO0pr*_kN{$!@qoc#5PSy~Bd7)KEAWA;h5;di+#nj8@I05|qab+9VBk@$&;A4gii65A0QiH;RX?~G2Yw$Y3?v?W z3f^Wx{O8~PqA`FZL>^KNbw*Pda1O3<3vNf`iK3A0T-E2Y~?9$#579CWt@GV27^@! zWC(ox191n5U`V6=53lfSAn|+%d|<)!;BUj?(;)dlU;*>^LG^3#6A*py6WYC2(gqmt zec&E3_~dXreF&6b*bP+Z9#PN#RslkkP%eS-yj5nP^0+}Ya0+Ci0k98@5I&p;7yJJ+ zm`5rB@qtxms`G%uiK7^ihsp!0mn+Tzb2prd zf#MJ4CW20Z<$#35A@S%p^W2$+0l7vTBA0pp;6LMRac`2Roj0Qq47 z<52KG_y_TUf4}oE`B;O4D2PEY3-N=OM*bfd6h;v+jzS^$500-KFCX}Pagq23LI;E~ z41T|V`~$|r75G5M!vNw(I1n9W_#R8~QII@@g8;5i{saPDhyZQ?^wdx81_9rP$^$6} zrGGOZ{&VmDQ5e7_0Q10VDl(YIAAhO<2t2tH2nB+%DXT&-SNf;`fAV%{i-kTgngHl^ z;q#CvL>@58t@94-g323+F!{kVJJ*7zQdKu@9E2)DJtwR311;1&XSm8m-hGd*Jy}AQ}x+DgYl$ z1zbKzVX#$yq46+?0Dc<1R1HQU@`DH0{vQ}Qpo8NDfCtZkAJ%H2p<)lj0=ZT6j0QX( zZ~*=_|NQSCLPZ!h16Aq=ox}O~xXLIOK=`5ust-7XBjNazz%~K#f(O$94}^aw^El-| zJ}@N^tBwhb@xbHKF!?}rTcCMEpkK&@5(xkglm@Gv7Z?5m3h==2m<_(G3||~@JY(<( z4-^U^@vK#Fw+gNtJT?pj0&))+H2{7zXhy3BFDeEByfFI^{HU;wt^}S`6M*0$0f7&U xnhEL^hyY~V355d@|Nr0WvRoz9R8R#_@F*NdIS0mtItQFUqBt8E7-#|U(EtcKLwx`M literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_2.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_2.bm new file mode 100644 index 0000000000000000000000000000000000000000..13916806fd62d4aed731cb58265eab34adb4b755 GIT binary patch literal 762 zcmVrBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fOpudH`hRdR4*Wh)9!NbZ zIhhCZpMUy@#sNqNo&#Y~l*Tyw{ZIfw<%qwoMxiOILNHhQr~rTTb_l@W@(qM0fI1y` ze8A)2z(yk#h$uX*!SV-{0|8)zYb3Y~1`|XdSq1}%0jo&xGzwjmKCK}+j=m!Skjym! z^?*z#SPIBIKqF``nXq6S2tR{i0f1tn8xZ+wtxGb1Tr2?b!ayulRREAk09noeJW~Up z)k2^euTVVk_yBmqAQlR*^gcaMabPg;2pX6}3?1VOfZOV@#qpg3 z%71{MVLr?8tW|Kg3aoSm5U~%+iwLU0$L9u+&*K;q s`ALuC0|%TV!$ALk|M&W=mk53o`bKaNGbsngg#Hjg6b26fD;RuqKoWI0G5`Po literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_3.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_3.bm new file mode 100644 index 0000000000000000000000000000000000000000..751fbc3efb282916cc38d5999018e804cd4c0a37 GIT binary patch literal 759 zcmVrBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fOpudH`hRdR4*Wh)9!NbZ zIhhCZpMUy@#sNqNo&#Y~l*Tyw{ZIfw<%qwoMxiOILNHhQr~rTTb_l@W@(qM0fI1y` ze8A)2z(yk#h$uX*!SV-{0|8)zYb3Y~1`|XdSq1}%0jo&xGzwjmKCK}+j=m!Skjym! z^?*z#SPIBIKqF``nXq6S2tR{i0f1tn8xZ+wtxGb1Tr2?b!ayulRREAk09noeJW~Up z)k2^euTVVk_yBmqAQlR*^gcaMabPg;2pX6}ciuJ510UA7%7K_Pe8f{#_%5zxU5Qv;P^?P8vyvh z1L6-k1mfXnnnx-D@qq`{!2pj*Ba$%rKu_WiItKznA~lG7pfy{lJfqwRg#v?zz-{$d zV))L1PFMTAvg;PWVy pM*@E-G5la)^`3vg1AnT?aEIXstOyKT0Qk_K!vhDPSm*)q(Ew_YJf;8u literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_4.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_4.bm new file mode 100644 index 0000000000000000000000000000000000000000..c1135b467cc5fe2e313984e30a04ded3dd814e7d GIT binary patch literal 759 zcmVrBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fOpudH`hRdR4*Wh)9!NbZ zIhhCZpMUy@#sNqNo&#Y~l*Tyw{ZIfw<%qwoMxiOILNHhQr~rTTb_l@W@(qM0fI1y` ze8A)2z(yk#h$uX*!SV-{0|8)zYb3Y~1`|XdSq1}%0jo&xGzwjmKCK}+j=m!Skjym! z^?*z#SPIBIKqF``nXq6S2tR{i0f1tn8xZ+wtxGb1Tr2?b!ayulRREAk09noi2jNM8 zXf;r%2CLK$JbnTL_=UhM6<_FldZ6OKVc-xyq)a|gVEX(h^N2T!P9G>N06w4T?GhRB z4TyaZA}$#FY;hNeBzQj%2*wJrDB@^!Ve!BR%m6VA6!J+bpj`vwcn^vsRwYE?)1`0? zfP7$q@duoPae(;DW0e5-z=P{xYK{gmBM+1W{vh(cP$mHJf8L-2#t(j-z3jS2iPFmd1^0P>&*$3*xWIm`e6 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_5.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_5.bm new file mode 100644 index 0000000000000000000000000000000000000000..a4681af98e85a780faca27f632565d56a90abee8 GIT binary patch literal 757 zcmVB0PzBVP#_wh1V*4h^Q%=r4;6re#y}sidI#q!KOp_)f#@Ib|JA;~|NVSF zaiA#b1NRjIjbK0F{}1|oq7Vqjg1#Sx_{cBtNru2bFs=pzg&nX(e-Qe|)~{6o3|1Ks zpV(mf2-Q+6sFiCqKp~AmBoql03&9`$N9z+>rBnnlSRlM?kSPVi2@upQgaA>f5hQr9 zSqB0O5bPdE05MQ_z-+K%nDOE|fONp1LOSv&;#X!fI=t` z5Wt_t1^)lc!{uTJj)MUKz%RxQT^sm(U{M%EBB20>U_3g!aJ+xv@y18T<2XbV?!ABf z1IEJ@_(0&F2sk{U`pfV8P)bMOCA7{DnI3j{I&fY?-JF^)d}Q~(fpOcVuBl+~daEB#aeKl(capz;lbCV)B} zcznR(Ef~aNu>}W}xIRGiutBwwTm}OPq7T0k16GmXXcW6BeW3?2*TiTt8HS)f(+SoB zvk~ybU^asJ-@)U+gZMTO9R?~Pu@9E2)UzlB!odO9VIUSNs(?r&04(PM1CXS^G#aQ> z16Aq=o<9Krj6zofRsM&^stzm$9svWKL__5U53jfcU^cr6ZnJ5c|hPO1_=NUlm@GH2bT|nFn~aCm<_(G z3||@0yz$V81RMl4imn#nRgQztV0airGJroCG$U0G2b;Kj5epFfsIZEx93Ef+$V6}_ n@{=FN1`k+A`~Wxltd|IW5PHD?#lR1Z3H&fHdP0HaKo5?HvfnzS literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_6.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_6.bm new file mode 100644 index 0000000000000000000000000000000000000000..36f2d084fe3277d555dda68b3a9675916ce237c3 GIT binary patch literal 785 zcmV+s1Md6*01X3xP#_wh1V*4h^Q%=r4;6re#y}sidI#q!KOp_)f#@Ib|JA;~|NVSF zaiA#b1NRjIjbK0F{}1|oq7Vr#7-N!1m0(_h@t{H>K=F(N$51I5i%Xy{O8~P zqA?GT_#QAVR;r^ZjB)qiVbxF|ANYBQYV}!7S`mW3)j$J(fPY{Z2nMfJ2@DJeULQue zU;^U>2bH)!Kw*qG$AA|ZE&~CC(Fe&^Fo*;~z!w=F27ybmhsbsy@q}yw;}L+!W*UI` z1H^7HYQS7U;sF~#e81rF!(erRae%-vQ4NTEy+HB2U@F0J2aXZ}VydVIst*_k0PsNZ zq(C$ps8j$DK=H4J2(Ct9{)faKRsi_Nuo3uxe4xSfoL9cEIP}6mA12U;&V96I0|$?S0TQeMhJ65_C&nR!3=9In;187I{2w?*5(45cgiJm^&;0;CSWF}W@c@W^ z1Lgkz%){kk#y~K_LH;ks4qY4gd|*a_fIwhSPxE|n!twuy#~B~EKrb*MSii>q_y>)K zEAWBQFdxVy0{$Nx@I05|TN(xf%#jdy)+hf00YyRUfS-rPe{e7k{61712lyT#p|9p- zAI^RM>IfPH1OE@;YxP>HjHWTi-+_lz4JrmYCUU%fg3b0>gwY4f01qf9^08Hs;Aj-PD13q902~~DQL2c* zWHSILht2`PPZd-iAQ7|&%l;1&0Khexs0;%Y5ZH&y)Gr_a)vBQJ!ayulRRHxt0stNc ztUgqT27^@!fNHQH^1Kbi9wu?HRez!J2cGzDAn}L?$_yVK2qb(9@#>YvKp!Y91FOM< zz(37_pWpz(A82F)@qg-r2KfMw2hOWOXO07ZKAe0w9DNCtVAu^+4mcYh1P+Y|z{+SB zK=_(R2ObBF0yrfY46XsN4~!F3%oKS@r``wz$~jOEj0>v+pM%E$BPaxFMjt2+st0Tb zmjVU^64-~z1J!|Y0p&4*cpx}j2H#bNz-P#_wh1V*4h^Q%=r4;6re#y}sidI#q!KOp_)f#@Ib|JA;~|NVSF zaiA#b1NRjIjbK0F{}0FF1|O98#2^spFn(9#Aiu!jf%=7TI}jK^e18!7$JVb^0Ss0d z5cl9e`uNpSE2x!gH9#SaK_nN81P}2Q{zvN*TBTG3F<2)8VbFkJBXCHDp=2NejXI17Q$+fWtn3P!r=2!UhHbV7^4d<2b(u&Jl!wgU5l6hzG~{|DXrU350-N0pkNN zj0^q$nTN{7jDTUFJO?1wAm!1&hsFgFtUw?zDFgxqsK*P({vRAVa1LJ-NlKe|!K)`vDBM5<3C;tKgMM3QZ4~+icU>*2;s5lSsJWYdN z%*a2S`~TENGzbU&9%3C{s-r24argS50E5T-0Kh;h^;u0?5rV(fKm&hco&Y{Dkifuo z;q;6*$AA|YC_Jsf@>Pr?0TA#7#!G;}VKhPV9f&+(7XY}(@H7ftls-W56O0>h7Z{8N zLon0_(ZE%}xP!z3Hh}qm!Q*&5czt6;s6@>TtVZ6fLN-k0qTMV0l+*E z7--To62B0rGm~YybuYLa-bg=7gh&92aW(nPzcnFK2RN04%iPa1Pllz zu@967s{-T$%3}oZKybJXzN-y@^+B=?5`@Ac7$x}DD!5yR*NqVslrCWq;X^0`@jDHw z4I)wu0u?5RSZqV`qQWk)N+Q6a(jNrD&>``YK_^g3MED**LxBE2|NH$`ON5@mG8_n=;>2_ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/frame_9.bm b/assets/resources/dolphin/L1_Painting_128x64/frame_9.bm new file mode 100644 index 0000000000000000000000000000000000000000..99ed507179a3dc7a64a99f871d18c55796a97cb1 GIT binary patch literal 777 zcmV+k1NQs@00jepP#_wh1V*4h^Q%=r4;6re#y}sidI#q!KOp_)f#@Ib|JA;~|NVSF zaiA#b1NRjIjbK0F{}0djKPmBu1I7ne55oLp7ysl0KTxg)0_;C8#6Ge0tJOe56^2A7 z@;C?jH&lx1C0fl;2xCx51p-X~fkpq3`oz|$RRIiE2rnAoJY$eZhM{C20*ye4BWHj> zZUFJ@9!LN&P$bQ$M&E2Yw$Y3=|%4 ziq2+1{O8~PqA`F$0pkY(4!)x)jB)q+pa6n~0WlJc3acrrLNHhQr~rTA!G}OF7#&@`ss42EH- z53BqiZEy(eDD+a z33bwjuI>)nnlDkWeER*d`kRx77g0 zRTmbF4nZJ-SYVLI1!Aj(xOHM{frdmRAB+SJ5kMb}8WHMI|3CNotd|LO2b2N}C@_p71Q!ta(5F)Xc|fHc0C>Pq H!XF(FZihX= literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Painting_128x64/meta.txt b/assets/resources/dolphin/L1_Painting_128x64/meta.txt new file mode 100644 index 00000000..e5f5fc0a --- /dev/null +++ b/assets/resources/dolphin/L1_Painting_128x64/meta.txt @@ -0,0 +1,32 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 9 +Active frames: 13 +Frames order: 0 1 2 3 4 5 2 3 4 10 6 7 8 7 8 7 8 7 8 9 10 11 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 57 +Y: 24 +Text: No mistakes, +AlignH: Left +AlignV: Center +StartFrame: 11 +EndFrame: 14 + +Slot: 0 +X: 57 +Y: 21 +Text: only happy\n accidents +AlignH: Left +AlignV: Center +StartFrame: 15 +EndFrame: 18 diff --git a/assets/resources/dolphin/manifest.txt b/assets/resources/dolphin/manifest.txt index 19706067..6bf6957c 100644 --- a/assets/resources/dolphin/manifest.txt +++ b/assets/resources/dolphin/manifest.txt @@ -85,6 +85,13 @@ Min level: 1 Max level: 3 Weight: 3 +Name: L1_Painting_128x64 +Min butthurt: 0 +Max butthurt: 7 +Min level: 1 +Max level: 3 +Weight: 6 + Name: L3_Hijack_radio_128x64 Min butthurt: 0 Max butthurt: 8 From afff1adf8fc09c37703b8a79a2c97c97bf675501 Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 12 Oct 2022 20:48:13 +0500 Subject: [PATCH 37/49] [FL-2882] BLE tiktok controller (#1859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bt hid: introduce tiktok controller * assets: add bt tiktok assets * bt hid: finish tiktok draw * bt hid: add input process to tiktok view * bt hid: add tiktok swipe emulation * bt hid: fix exit from tiktok controller * ble hid: add delay to emulate double tap * ble hid: change options order * bt hid: build as external application * ble hid: fix naming Co-authored-by: あく --- applications/plugins/application.fam | 1 - .../plugins/bt_hid_app/application.fam | 11 +- .../plugins/bt_hid_app/assets/Arr_dwn_7x9.png | Bin 0 -> 3602 bytes .../plugins/bt_hid_app/assets/Arr_up_7x9.png | Bin 0 -> 3605 bytes .../bt_hid_app/assets/Ble_connected_15x15.png | Bin 0 -> 3634 bytes .../assets/Ble_disconnected_15x15.png | Bin 0 -> 3632 bytes .../bt_hid_app/assets/Button_18x18.png | Bin 0 -> 3609 bytes .../bt_hid_app/assets/Circles_47x47.png | Bin 0 -> 3712 bytes .../bt_hid_app/assets/Left_mouse_icon_9x9.png | Bin 0 -> 3622 bytes .../bt_hid_app/assets/Like_def_11x9.png | Bin 0 -> 3616 bytes .../bt_hid_app/assets/Like_pressed_17x17.png | Bin 0 -> 3643 bytes .../assets/Ok_btn_pressed_13x13.png | Bin 0 -> 3625 bytes .../assets/Pressed_Button_13x13.png | Bin 0 -> 3606 bytes .../assets/Right_mouse_icon_9x9.png | Bin 0 -> 3622 bytes .../plugins/bt_hid_app/assets/Space_65x18.png | Bin 0 -> 3619 bytes .../plugins/bt_hid_app/assets/Voldwn_6x6.png | Bin 0 -> 3593 bytes .../plugins/bt_hid_app/assets/Volup_8x6.png | Bin 0 -> 3595 bytes applications/plugins/bt_hid_app/bt_hid.c | 16 ++ applications/plugins/bt_hid_app/bt_hid.h | 3 + .../bt_hid_app/views/bt_hid_keyboard.c | 2 + .../plugins/bt_hid_app/views/bt_hid_keynote.c | 2 + .../plugins/bt_hid_app/views/bt_hid_media.c | 2 + .../plugins/bt_hid_app/views/bt_hid_mouse.c | 2 + .../plugins/bt_hid_app/views/bt_hid_tiktok.c | 207 ++++++++++++++++++ .../plugins/bt_hid_app/views/bt_hid_tiktok.h | 13 ++ 25 files changed, 250 insertions(+), 9 deletions(-) create mode 100644 applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png create mode 100644 applications/plugins/bt_hid_app/assets/Arr_up_7x9.png create mode 100644 applications/plugins/bt_hid_app/assets/Ble_connected_15x15.png create mode 100644 applications/plugins/bt_hid_app/assets/Ble_disconnected_15x15.png create mode 100644 applications/plugins/bt_hid_app/assets/Button_18x18.png create mode 100644 applications/plugins/bt_hid_app/assets/Circles_47x47.png create mode 100644 applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png create mode 100644 applications/plugins/bt_hid_app/assets/Like_def_11x9.png create mode 100644 applications/plugins/bt_hid_app/assets/Like_pressed_17x17.png create mode 100644 applications/plugins/bt_hid_app/assets/Ok_btn_pressed_13x13.png create mode 100644 applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png create mode 100644 applications/plugins/bt_hid_app/assets/Right_mouse_icon_9x9.png create mode 100644 applications/plugins/bt_hid_app/assets/Space_65x18.png create mode 100644 applications/plugins/bt_hid_app/assets/Voldwn_6x6.png create mode 100644 applications/plugins/bt_hid_app/assets/Volup_8x6.png create mode 100644 applications/plugins/bt_hid_app/views/bt_hid_tiktok.c create mode 100644 applications/plugins/bt_hid_app/views/bt_hid_tiktok.h diff --git a/applications/plugins/application.fam b/applications/plugins/application.fam index c88f6d28..6d25e45a 100644 --- a/applications/plugins/application.fam +++ b/applications/plugins/application.fam @@ -5,6 +5,5 @@ App( provides=[ "music_player", "snake_game", - "bt_hid", ], ) diff --git a/applications/plugins/bt_hid_app/application.fam b/applications/plugins/bt_hid_app/application.fam index e6a3b175..2712fded 100644 --- a/applications/plugins/bt_hid_app/application.fam +++ b/applications/plugins/bt_hid_app/application.fam @@ -1,15 +1,10 @@ App( appid="bt_hid", name="Bluetooth Remote", - apptype=FlipperAppType.PLUGIN, + apptype=FlipperAppType.EXTERNAL, entry_point="bt_hid_app", stack_size=1 * 1024, - cdefines=["APP_BLE_HID"], - requires=[ - "bt", - "gui", - ], - order=10, - fap_icon="bt_remote_10px.png", fap_category="Tools", + fap_icon="bt_remote_10px.png", + fap_icon_assets="assets", ) diff --git a/applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png b/applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..d4034efc432b102f6f751d001dc6891b0763c55c GIT binary patch literal 3602 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 JTZ;Aw|2NmVF(Lo} literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Arr_up_7x9.png b/applications/plugins/bt_hid_app/assets/Arr_up_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..28b4236a292708b412629ffafe30f6d011491505 GIT binary patch literal 3605 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 literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Circles_47x47.png b/applications/plugins/bt_hid_app/assets/Circles_47x47.png new file mode 100644 index 0000000000000000000000000000000000000000..6a16ebf7bbe999fa143c683bef713a6e2f466cbb GIT binary patch literal 3712 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 biU<_Yn+9Io=xs3K`2!qm58ISjpSt)z2v?8| literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png b/applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..c533d85729f9b778cba33227141c90dea298f5e3 GIT binary patch literal 3622 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 literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Like_def_11x9.png b/applications/plugins/bt_hid_app/assets/Like_def_11x9.png new file mode 100644 index 0000000000000000000000000000000000000000..555bea3d4b0239ae1be630d0306316d3e9494c4c GIT binary patch literal 3616 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 literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png b/applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png new file mode 100644 index 0000000000000000000000000000000000000000..823926b842b8f9868fd70d6f1434dff071c04d5d GIT binary patch literal 3606 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 literal 0 HcmV?d00001 diff --git a/applications/plugins/bt_hid_app/assets/Voldwn_6x6.png b/applications/plugins/bt_hid_app/assets/Voldwn_6x6.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a82a2df8262667a9a03419f437ff9b350e645f GIT binary patch literal 3593 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 = BtHidViewMouse; view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewMouse); + } else if(index == BtHidSubmenuIndexTikTok) { + app->view_id = BtHidViewTikTok; + view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok); } } @@ -65,6 +69,7 @@ void bt_hid_connection_status_changed_callback(BtStatus status, void* context) { bt_hid_keyboard_set_connected_status(bt_hid->bt_hid_keyboard, connected); bt_hid_media_set_connected_status(bt_hid->bt_hid_media, connected); bt_hid_mouse_set_connected_status(bt_hid->bt_hid_mouse, connected); + bt_hid_tiktok_set_connected_status(bt_hid->bt_hid_tiktok, connected); } BtHid* bt_hid_app_alloc() { @@ -91,6 +96,8 @@ BtHid* bt_hid_app_alloc() { submenu_add_item( app->submenu, "Keyboard", BtHidSubmenuIndexKeyboard, bt_hid_submenu_callback, app); submenu_add_item(app->submenu, "Media", BtHidSubmenuIndexMedia, bt_hid_submenu_callback, app); + submenu_add_item( + app->submenu, "TikTok Controller", BtHidSubmenuIndexTikTok, bt_hid_submenu_callback, app); submenu_add_item(app->submenu, "Mouse", BtHidSubmenuIndexMouse, bt_hid_submenu_callback, app); view_set_previous_callback(submenu_get_view(app->submenu), bt_hid_exit); view_dispatcher_add_view( @@ -127,6 +134,13 @@ BtHid* bt_hid_app_alloc() { view_dispatcher_add_view( app->view_dispatcher, BtHidViewMedia, bt_hid_media_get_view(app->bt_hid_media)); + // TikTok view + app->bt_hid_tiktok = bt_hid_tiktok_alloc(); + view_set_previous_callback( + bt_hid_tiktok_get_view(app->bt_hid_tiktok), bt_hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, BtHidViewTikTok, bt_hid_tiktok_get_view(app->bt_hid_tiktok)); + // Mouse view app->bt_hid_mouse = bt_hid_mouse_alloc(); view_set_previous_callback(bt_hid_mouse_get_view(app->bt_hid_mouse), bt_hid_exit_confirm_view); @@ -159,6 +173,8 @@ void bt_hid_app_free(BtHid* app) { bt_hid_media_free(app->bt_hid_media); view_dispatcher_remove_view(app->view_dispatcher, BtHidViewMouse); bt_hid_mouse_free(app->bt_hid_mouse); + view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); + bt_hid_tiktok_free(app->bt_hid_tiktok); view_dispatcher_free(app->view_dispatcher); // Close records diff --git a/applications/plugins/bt_hid_app/bt_hid.h b/applications/plugins/bt_hid_app/bt_hid.h index 0f4c7be9..89e8807f 100644 --- a/applications/plugins/bt_hid_app/bt_hid.h +++ b/applications/plugins/bt_hid_app/bt_hid.h @@ -13,6 +13,7 @@ #include "views/bt_hid_keyboard.h" #include "views/bt_hid_media.h" #include "views/bt_hid_mouse.h" +#include "views/bt_hid_tiktok.h" typedef struct { Bt* bt; @@ -25,6 +26,7 @@ typedef struct { BtHidKeyboard* bt_hid_keyboard; BtHidMedia* bt_hid_media; BtHidMouse* bt_hid_mouse; + BtHidTikTok* bt_hid_tiktok; uint32_t view_id; } BtHid; @@ -34,5 +36,6 @@ typedef enum { BtHidViewKeyboard, BtHidViewMedia, BtHidViewMouse, + BtHidViewTikTok, BtHidViewExitConfirm, } BtHidView; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c index 2c65f6ab..a1077b79 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c @@ -5,6 +5,8 @@ #include #include +#include "bt_hid_icons.h" + struct BtHidKeyboard { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c index db88b800..0e81c5fa 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c @@ -4,6 +4,8 @@ #include #include +#include "bt_hid_icons.h" + struct BtHidKeynote { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_media.c b/applications/plugins/bt_hid_app/views/bt_hid_media.c index 181cd347..df7349a9 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_media.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_media.c @@ -4,6 +4,8 @@ #include #include +#include "bt_hid_icons.h" + struct BtHidMedia { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c index 098adb73..bd48bab1 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c @@ -4,6 +4,8 @@ #include #include +#include "bt_hid_icons.h" + struct BtHidMouse { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c new file mode 100644 index 00000000..9af00157 --- /dev/null +++ b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c @@ -0,0 +1,207 @@ +#include "bt_hid_tiktok.h" +#include +#include +#include +#include + +#include "bt_hid_icons.h" + +struct BtHidTikTok { + View* view; +}; + +typedef struct { + bool left_pressed; + bool up_pressed; + bool right_pressed; + bool down_pressed; + bool ok_pressed; + bool connected; +} BtHidTikTokModel; + +static void bt_hid_tiktok_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + BtHidTikTokModel* model = context; + + // Header + if(model->connected) { + canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); + } else { + canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); + } + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "TikTok"); + canvas_set_font(canvas, FontSecondary); + + // Keypad circles + canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47); + + // Up + if(model->up_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 96, 11, &I_Arr_up_7x9); + canvas_set_color(canvas, ColorBlack); + + // Down + if(model->down_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 96, 44, &I_Arr_dwn_7x9); + canvas_set_color(canvas, ColorBlack); + + // Left + if(model->left_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 81, 29, &I_Voldwn_6x6); + canvas_set_color(canvas, ColorBlack); + + // Right + if(model->right_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 111, 29, &I_Volup_8x6); + canvas_set_color(canvas, ColorBlack); + + // Ok + if(model->ok_pressed) { + canvas_draw_icon(canvas, 91, 23, &I_Like_pressed_17x17); + } else { + canvas_draw_icon(canvas, 94, 27, &I_Like_def_11x9); + } + // Exit + canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); +} + +static void bt_hid_tiktok_process_press(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { + with_view_model( + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + if(event->key == InputKeyUp) { + model->up_pressed = true; + } else if(event->key == InputKeyDown) { + model->down_pressed = true; + } else if(event->key == InputKeyLeft) { + model->left_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = true; + } + }, + true); +} + +static void bt_hid_tiktok_process_release(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { + with_view_model( + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + if(event->key == InputKeyUp) { + model->up_pressed = false; + } else if(event->key == InputKeyDown) { + model->down_pressed = false; + } else if(event->key == InputKeyLeft) { + model->left_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = false; + } + }, + true); +} + +static bool bt_hid_tiktok_input_callback(InputEvent* event, void* context) { + furi_assert(context); + BtHidTikTok* bt_hid_tiktok = context; + bool consumed = false; + + if(event->type == InputTypePress) { + bt_hid_tiktok_process_press(bt_hid_tiktok, event); + consumed = true; + } else if(event->type == InputTypeRelease) { + bt_hid_tiktok_process_release(bt_hid_tiktok, event); + consumed = true; + } else if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + consumed = true; + } else if(event->key == InputKeyUp) { + // Emulate up swipe + furi_hal_bt_hid_mouse_scroll(-6); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-19); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-6); + consumed = true; + } else if(event->key == InputKeyDown) { + // Emulate down swipe + furi_hal_bt_hid_mouse_scroll(6); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(19); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(6); + consumed = true; + } else if(event->key == InputKeyBack) { + furi_hal_bt_hid_consumer_key_release_all(); + consumed = true; + } + } + + return consumed; +} + +BtHidTikTok* bt_hid_tiktok_alloc() { + BtHidTikTok* bt_hid_tiktok = malloc(sizeof(BtHidTikTok)); + bt_hid_tiktok->view = view_alloc(); + view_set_context(bt_hid_tiktok->view, bt_hid_tiktok); + view_allocate_model(bt_hid_tiktok->view, ViewModelTypeLocking, sizeof(BtHidTikTokModel)); + view_set_draw_callback(bt_hid_tiktok->view, bt_hid_tiktok_draw_callback); + view_set_input_callback(bt_hid_tiktok->view, bt_hid_tiktok_input_callback); + + return bt_hid_tiktok; +} + +void bt_hid_tiktok_free(BtHidTikTok* bt_hid_tiktok) { + furi_assert(bt_hid_tiktok); + view_free(bt_hid_tiktok->view); + free(bt_hid_tiktok); +} + +View* bt_hid_tiktok_get_view(BtHidTikTok* bt_hid_tiktok) { + furi_assert(bt_hid_tiktok); + return bt_hid_tiktok->view; +} + +void bt_hid_tiktok_set_connected_status(BtHidTikTok* bt_hid_tiktok, bool connected) { + furi_assert(bt_hid_tiktok); + with_view_model( + bt_hid_tiktok->view, BtHidTikTokModel * model, { model->connected = connected; }, true); +} diff --git a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h new file mode 100644 index 00000000..03c9afec --- /dev/null +++ b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +typedef struct BtHidTikTok BtHidTikTok; + +BtHidTikTok* bt_hid_tiktok_alloc(); + +void bt_hid_tiktok_free(BtHidTikTok* bt_hid_tiktok); + +View* bt_hid_tiktok_get_view(BtHidTikTok* bt_hid_tiktok); + +void bt_hid_tiktok_set_connected_status(BtHidTikTok* bt_hid_tiktok, bool connected); From eb4ff3c0fd4cee9e710732d98cc728bbcf2d31cf Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 12 Oct 2022 20:12:05 +0400 Subject: [PATCH 38/49] [FL-2832] fbt: more fixes & improvements (#1854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * github: bundling debug folder with scripts; docs: fixes & updates; fbt: added FAP_EXAMPLES variable to enable building example apps. Disabled by default. fbt: added TERM to list of proxied environment variables * fbt: better help output; disabled implicit_deps_unchanged; added color to import validator reports * fbt: moved debug configuration to separate tool * fbt: proper dependency tracker for SDK source file; renamed linker script for external apps * fbt: fixed debug elf path * fbt: packaging sdk archive * scripts: fixed sconsdist.py * fbt: reworked sdk packing; docs: updates * docs: info on cli target; linter fixes * fbt: moved main code to scripts folder * scripts: packing update into .tgz * fbt, scripts: reworked copro_dist to build .tgz * scripts: fixed naming for archived updater package * Scripts: fix ぐるぐる回る Co-authored-by: Aleksandr Kutuzov --- .github/workflows/build.yml | 18 +- SConstruct | 63 ++--- .../examples/example_images/example_images.c | 2 + documentation/AppManifests.md | 4 +- documentation/AppsOnSDCard.md | 4 +- documentation/fbt.md | 3 +- firmware.scons | 17 +- ...{application-ext.ld => application_ext.ld} | 0 {site_scons => scripts}/fbt/__init__.py | 0 {site_scons => scripts}/fbt/appmanifest.py | 0 {site_scons => scripts}/fbt/elfmanifest.py | 0 {site_scons => scripts}/fbt/sdk.py | 0 {site_scons => scripts}/fbt/util.py | 22 -- {site_scons => scripts}/fbt/version.py | 0 .../fbt_tools}/blackmagic.py | 0 .../fbt_tools}/ccache.py | 0 .../fbt_tools}/crosscc.py | 0 .../fbt_tools}/fbt_apps.py | 0 .../fbt_tools}/fbt_assets.py | 0 scripts/fbt_tools/fbt_debugopts.py | 41 ++++ .../fbt_tools}/fbt_dist.py | 3 +- .../fbt_tools}/fbt_extapps.py | 8 +- scripts/fbt_tools/fbt_help.py | 44 ++++ .../fbt_tools}/fbt_sdk.py | 80 ++++++- .../fbt_tools}/fbt_version.py | 0 .../site_tools => scripts/fbt_tools}/fwbin.py | 0 .../site_tools => scripts/fbt_tools}/gdb.py | 0 .../fbt_tools}/jflash.py | 0 .../fbt_tools}/objdump.py | 0 .../fbt_tools}/openocd.py | 0 .../fbt_tools}/python3.py | 0 .../fbt_tools}/sconsmodular.py | 0 .../fbt_tools}/sconsrecursiveglob.py | 0 .../site_tools => scripts/fbt_tools}/strip.py | 0 scripts/flipper/assets/copro.py | 36 +-- scripts/guruguru.py | 2 +- scripts/sconsdist.py | 71 ++++-- site_scons/commandline.scons | 224 ++++++++---------- site_scons/environ.scons | 17 +- site_scons/extapps.scons | 3 +- site_scons/fbt_extra/util.py | 23 ++ 41 files changed, 413 insertions(+), 272 deletions(-) rename firmware/targets/f7/{application-ext.ld => application_ext.ld} (100%) rename {site_scons => scripts}/fbt/__init__.py (100%) rename {site_scons => scripts}/fbt/appmanifest.py (100%) rename {site_scons => scripts}/fbt/elfmanifest.py (100%) rename {site_scons => scripts}/fbt/sdk.py (100%) rename {site_scons => scripts}/fbt/util.py (58%) rename {site_scons => scripts}/fbt/version.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/blackmagic.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/ccache.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/crosscc.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/fbt_apps.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/fbt_assets.py (100%) create mode 100644 scripts/fbt_tools/fbt_debugopts.py rename {site_scons/site_tools => scripts/fbt_tools}/fbt_dist.py (98%) rename {site_scons/site_tools => scripts/fbt_tools}/fbt_extapps.py (96%) create mode 100644 scripts/fbt_tools/fbt_help.py rename {site_scons/site_tools => scripts/fbt_tools}/fbt_sdk.py (71%) rename {site_scons/site_tools => scripts/fbt_tools}/fbt_version.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/fwbin.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/gdb.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/jflash.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/objdump.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/openocd.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/python3.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/sconsmodular.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/sconsrecursiveglob.py (100%) rename {site_scons/site_tools => scripts/fbt_tools}/strip.py (100%) create mode 100644 site_scons/fbt_extra/util.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1304c5d7..8fb67ed1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,14 +56,14 @@ jobs: - name: 'Bundle scripts' if: ${{ !github.event.pull_request.head.repo.fork }} run: | - tar czpf artifacts/flipper-z-any-scripts-${SUFFIX}.tgz scripts + tar czpf artifacts/flipper-z-any-scripts-${SUFFIX}.tgz scripts debug - name: 'Build the firmware' run: | set -e for TARGET in ${TARGETS}; do FBT_TOOLCHAIN_PATH=/runner/_work ./fbt TARGET_HW="$(echo "${TARGET}" | sed 's/f//')" \ - updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} + copro_dist updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} done - name: 'Move upload files' @@ -74,17 +74,6 @@ jobs: mv dist/${TARGET}-*/* artifacts/ done - - name: 'Bundle self-update package' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - set -e - for UPDATEBUNDLE in artifacts/*/; do - BUNDLE_NAME="$(echo "$UPDATEBUNDLE" | cut -d'/' -f2)" - echo Packaging "${BUNDLE_NAME}" - tar czpf "artifacts/flipper-z-${BUNDLE_NAME}.tgz" -C artifacts "${BUNDLE_NAME}" - rm -rf "artifacts/${BUNDLE_NAME}" - done - - name: "Check for uncommitted changes" run: | git diff --exit-code @@ -97,8 +86,7 @@ jobs: - name: 'Bundle core2 firmware' if: ${{ !github.event.pull_request.head.repo.fork }} run: | - FBT_TOOLCHAIN_PATH=/runner/_work ./fbt copro_dist - tar czpf "artifacts/flipper-z-any-core2_firmware-${SUFFIX}.tgz" -C assets core2_firmware + cp build/core2_firmware.tgz "artifacts/flipper-z-any-core2_firmware-${SUFFIX}.tgz" - name: 'Copy .map file' run: | diff --git a/SConstruct b/SConstruct index 5ad2ac3c..74fa5667 100644 --- a/SConstruct +++ b/SConstruct @@ -7,7 +7,6 @@ # construction of certain targets behind command-line options. import os -import subprocess DefaultEnvironment(tools=[]) @@ -15,17 +14,22 @@ EnsurePythonVersion(3, 8) # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15) - # This environment is created only for loading options & validating file/dir existence fbt_variables = SConscript("site_scons/commandline.scons") -cmd_environment = Environment(tools=[], variables=fbt_variables) -Help(fbt_variables.GenerateHelpText(cmd_environment)) +cmd_environment = Environment( + toolpath=["#/scripts/fbt_tools"], + tools=[ + ("fbt_help", {"vars": fbt_variables}), + ], + variables=fbt_variables, +) # Building basic environment - tools, utility methods, cross-compilation # settings, gcc flags for Cortex-M4, basic builders and more coreenv = SConscript( "site_scons/environ.scons", exports={"VAR_ENV": cmd_environment}, + toolpath=["#/scripts/fbt_tools"], ) SConscript("site_scons/cc.scons", exports={"ENV": coreenv}) @@ -35,41 +39,13 @@ coreenv["ROOT_DIR"] = Dir(".") # Create a separate "dist" environment and add construction envs to it distenv = coreenv.Clone( - tools=["fbt_dist", "openocd", "blackmagic", "jflash"], - OPENOCD_GDB_PIPE=[ - "|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}" + tools=[ + "fbt_dist", + "fbt_debugopts", + "openocd", + "blackmagic", + "jflash", ], - GDBOPTS_BASE=[ - "-ex", - "target extended-remote ${GDBREMOTE}", - "-ex", - "set confirm off", - "-ex", - "set pagination off", - ], - GDBOPTS_BLACKMAGIC=[ - "-ex", - "monitor swdp_scan", - "-ex", - "monitor debug_bmp enable", - "-ex", - "attach 1", - "-ex", - "set mem inaccessible-by-default off", - ], - GDBPYOPTS=[ - "-ex", - "source debug/FreeRTOS/FreeRTOS.py", - "-ex", - "source debug/flipperapps.py", - "-ex", - "source debug/PyCortexMDebug/PyCortexMDebug.py", - "-ex", - "svd_load ${SVD_FILE}", - "-ex", - "compare-sections", - ], - JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash", ENV=os.environ, ) @@ -166,7 +142,7 @@ basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"]) distenv.Default(basic_dist) dist_dir = distenv.GetProjetDirName() -plugin_dist = [ +fap_dist = [ distenv.Install( f"#/dist/{dist_dir}/apps/debug_elf", firmware_env["FW_EXTAPPS"]["debug"].values(), @@ -176,9 +152,9 @@ plugin_dist = [ for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values() ), ] -Depends(plugin_dist, firmware_env["FW_EXTAPPS"]["validators"].values()) -Alias("plugin_dist", plugin_dist) -# distenv.Default(plugin_dist) +Depends(fap_dist, firmware_env["FW_EXTAPPS"]["validators"].values()) +Alias("fap_dist", fap_dist) +# distenv.Default(fap_dist) plugin_resources_dist = list( distenv.Install(f"#/assets/resources/apps/{dist_entry[0]}", dist_entry[1]) @@ -189,9 +165,10 @@ distenv.Depends(firmware_env["FW_RESOURCES"], plugin_resources_dist) # Target for bundling core2 package for qFlipper copro_dist = distenv.CoproBuilder( - distenv.Dir("assets/core2_firmware"), + "#/build/core2_firmware.tgz", [], ) +distenv.AlwaysBuild(copro_dist) distenv.Alias("copro_dist", copro_dist) firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env) diff --git a/applications/examples/example_images/example_images.c b/applications/examples/example_images/example_images.c index 48fa5e77..b00818cd 100644 --- a/applications/examples/example_images/example_images.c +++ b/applications/examples/example_images/example_images.c @@ -4,6 +4,8 @@ #include #include +/* Magic happens here -- this file is generated by fbt. + * Just set fap_icon_assets in application.fam and #include {APPID}_icons.h */ #include "example_images_icons.h" typedef struct { diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 4fec9d22..c7c73110 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -30,7 +30,7 @@ Only 2 parameters are mandatory: ***appid*** and ***apptype***, others are optio | METAPACKAGE | Does not define any code to be run, used for declaring dependencies and application bundles | * **name**: Name that is displayed in menus. -* **entry_point**: C function to be used as application's entry point. +* **entry_point**: C function to be used as application's entry point. Note that C++ function names are mangled, so you need to wrap them in `extern "C"` in order to use them as entry points. * **flags**: Internal flags for system apps. Do not use. * **cdefines**: C preprocessor definitions to declare globally for other apps when current application is included in active build configuration. * **requires**: List of application IDs to also include in build configuration, when current application is referenced in list of applications to build. @@ -55,7 +55,7 @@ The following parameters are used only for [FAPs](./AppsOnSDCard.md): * **fap_author**: string, may be empty. Application's author. * **fap_weburl**: string, may be empty. Application's homepage. * **fap_icon_assets**: string. If present, defines a folder name to be used for gathering image assets for this application. These images will be preprocessed and built alongside the application. See [FAP assets](./AppsOnSDCard.md#fap-assets) for details. -* **fap_extbuild**: provides support for parts of application sources to be build by external tools. Contains a list of `ExtFile(path="file name", command="shell command")` definitions. **`fbt`** will run the specified command for each file in the list. +* **fap_extbuild**: provides support for parts of application sources to be built by external tools. Contains a list of `ExtFile(path="file name", command="shell command")` definitions. **`fbt`** will run the specified command for each file in the list. Note that commands are executed at the firmware root folder's root, and all intermediate files must be placed in a application's temporary build folder. For that, you can use pattern expansion by **`fbt`**: `${FAP_WORK_DIR}` will be replaced with the path to the application's temporary build folder, and `${FAP_SRC_DIR}` will be replaced with the path to the application's source folder. You can also use other variables defined internally by **`fbt`**. Example for building an app from Rust sources: diff --git a/documentation/AppsOnSDCard.md b/documentation/AppsOnSDCard.md index aff8314d..4acb3ec3 100644 --- a/documentation/AppsOnSDCard.md +++ b/documentation/AppsOnSDCard.md @@ -2,7 +2,7 @@ [fbt](./fbt.md) has support for building applications as FAP files. FAP are essentially .elf executables with extra metadata and resources bundled in. -FAPs are built with `faps` **`fbt`** target. They can also be deployed to `dist` folder with `plugin_dist` **`fbt`** target. +FAPs are built with `faps` target. They can also be deployed to `dist` folder with `fap_dist` target. FAPs do not depend on being run on a specific firmware version. Compatibility is determined by the FAP's metadata, which includes the required [API version](#api-versioning). @@ -15,7 +15,7 @@ To build your application as a FAP, just create a folder with your app's source * To build your application, run `./fbt fap_{APPID}`, where APPID is your application's ID in its manifest. * To build your app, then upload it over USB & run it on Flipper, use `./fbt launch_app APPSRC=applications/path/to/app`. This command is configured in default [VSCode profile](../.vscode/ReadMe.md) as "Launch App on Flipper" build action (Ctrl+Shift+B menu). - * To build all FAPs, run `./fbt plugin_dist`. + * To build all FAPs, run `./fbt faps` or `./fbt fap_dist`. ## FAP assets diff --git a/documentation/fbt.md b/documentation/fbt.md index e20d4317..3fac7ce7 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -43,7 +43,7 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. ### High-level (what you most likely need) - `fw_dist` - build & publish firmware to `dist` folder. This is a default target, when no other are specified -- `plugin_dist` - build external plugins & publish to `dist` folder +- `fap_dist` - build external plugins & publish to `dist` folder - `updater_package`, `updater_minpackage` - build self-update package. Minimal version only inclues firmware's DFU file; full version also includes radio stack & resources for SD card - `copro_dist` - bundle Core2 FUS+stack binaries for qFlipper - `flash` - flash attached device with OpenOCD over ST-Link @@ -56,6 +56,7 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. - `get_blackmagic` - output blackmagic address in gdb remote format. Useful for IDE integration - `lint`, `format` - run clang-format on C source code to check and reformat it according to `.clang-format` specs - `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on Python source code, build system files & application manifests +- `cli` - start Flipper CLI session over USB ### Firmware targets diff --git a/firmware.scons b/firmware.scons index dd13b6b3..d28309d0 100644 --- a/firmware.scons +++ b/firmware.scons @@ -3,7 +3,7 @@ Import("ENV", "fw_build_meta") from SCons.Errors import UserError import itertools -from fbt.util import ( +from fbt_extra.util import ( should_gen_cdb_and_link_dir, link_elf_dir_as_latest, ) @@ -141,6 +141,10 @@ else: if extra_int_apps := GetOption("extra_int_apps"): fwenv.Append(APPS=extra_int_apps.split(",")) + +if fwenv["FAP_EXAMPLES"]: + fwenv.Append(APPDIRS=[("applications/examples", False)]) + fwenv.LoadApplicationManifests() fwenv.PrepareApplicationsBuild() @@ -316,10 +320,13 @@ if fwenv["IS_BASE_FIRMWARE"]: "-D__inline__=inline", ], ) - Depends(sdk_source, (fwenv["SDK_HEADERS"], fwenv["FW_ASSETS_HEADERS"])) + # Depends(sdk_source, (fwenv["SDK_HEADERS"], fwenv["FW_ASSETS_HEADERS"])) + Depends(sdk_source, fwenv.ProcessSdkDepends("sdk_origin.d")) - sdk_tree = fwenv.SDKTree("sdk/sdk.opts", "sdk_origin") - AlwaysBuild(sdk_tree) + fwenv["SDK_DIR"] = fwenv.Dir("sdk") + sdk_tree = fwenv.SDKTree(fwenv["SDK_DIR"], "sdk_origin") + fw_artifacts.append(sdk_tree) + # AlwaysBuild(sdk_tree) Alias("sdk_tree", sdk_tree) sdk_apicheck = fwenv.SDKSymUpdater(fwenv.subst("$SDK_DEFINITION"), "sdk_origin") @@ -329,7 +336,7 @@ if fwenv["IS_BASE_FIRMWARE"]: Alias("sdk_check", sdk_apicheck) sdk_apisyms = fwenv.SDKSymGenerator( - "assets/compiled/symbols.h", fwenv.subst("$SDK_DEFINITION") + "assets/compiled/symbols.h", fwenv["SDK_DEFINITION"] ) Alias("api_syms", sdk_apisyms) diff --git a/firmware/targets/f7/application-ext.ld b/firmware/targets/f7/application_ext.ld similarity index 100% rename from firmware/targets/f7/application-ext.ld rename to firmware/targets/f7/application_ext.ld diff --git a/site_scons/fbt/__init__.py b/scripts/fbt/__init__.py similarity index 100% rename from site_scons/fbt/__init__.py rename to scripts/fbt/__init__.py diff --git a/site_scons/fbt/appmanifest.py b/scripts/fbt/appmanifest.py similarity index 100% rename from site_scons/fbt/appmanifest.py rename to scripts/fbt/appmanifest.py diff --git a/site_scons/fbt/elfmanifest.py b/scripts/fbt/elfmanifest.py similarity index 100% rename from site_scons/fbt/elfmanifest.py rename to scripts/fbt/elfmanifest.py diff --git a/site_scons/fbt/sdk.py b/scripts/fbt/sdk.py similarity index 100% rename from site_scons/fbt/sdk.py rename to scripts/fbt/sdk.py diff --git a/site_scons/fbt/util.py b/scripts/fbt/util.py similarity index 58% rename from site_scons/fbt/util.py rename to scripts/fbt/util.py index 8d8af518..baa4ddfe 100644 --- a/site_scons/fbt/util.py +++ b/scripts/fbt/util.py @@ -41,25 +41,3 @@ def link_dir(target_path, source_path, is_windows): def single_quote(arg_list): return " ".join(f"'{arg}'" if " " in arg else str(arg) for arg in arg_list) - - -def link_elf_dir_as_latest(env, elf_node): - elf_dir = elf_node.Dir(".") - latest_dir = env.Dir("#build/latest") - print(f"Setting {elf_dir} as latest built dir (./build/latest/)") - return link_dir(latest_dir.abspath, elf_dir.abspath, env["PLATFORM"] == "win32") - - -def should_gen_cdb_and_link_dir(env, requested_targets): - explicitly_building_updater = False - # Hacky way to check if updater-related targets were requested - for build_target in requested_targets: - if "updater" in str(build_target): - explicitly_building_updater = True - - is_updater = not env["IS_BASE_FIRMWARE"] - # If updater is explicitly requested, link to the latest updater - # Otherwise, link to firmware - return (is_updater and explicitly_building_updater) or ( - not is_updater and not explicitly_building_updater - ) diff --git a/site_scons/fbt/version.py b/scripts/fbt/version.py similarity index 100% rename from site_scons/fbt/version.py rename to scripts/fbt/version.py diff --git a/site_scons/site_tools/blackmagic.py b/scripts/fbt_tools/blackmagic.py similarity index 100% rename from site_scons/site_tools/blackmagic.py rename to scripts/fbt_tools/blackmagic.py diff --git a/site_scons/site_tools/ccache.py b/scripts/fbt_tools/ccache.py similarity index 100% rename from site_scons/site_tools/ccache.py rename to scripts/fbt_tools/ccache.py diff --git a/site_scons/site_tools/crosscc.py b/scripts/fbt_tools/crosscc.py similarity index 100% rename from site_scons/site_tools/crosscc.py rename to scripts/fbt_tools/crosscc.py diff --git a/site_scons/site_tools/fbt_apps.py b/scripts/fbt_tools/fbt_apps.py similarity index 100% rename from site_scons/site_tools/fbt_apps.py rename to scripts/fbt_tools/fbt_apps.py diff --git a/site_scons/site_tools/fbt_assets.py b/scripts/fbt_tools/fbt_assets.py similarity index 100% rename from site_scons/site_tools/fbt_assets.py rename to scripts/fbt_tools/fbt_assets.py diff --git a/scripts/fbt_tools/fbt_debugopts.py b/scripts/fbt_tools/fbt_debugopts.py new file mode 100644 index 00000000..3e7b0701 --- /dev/null +++ b/scripts/fbt_tools/fbt_debugopts.py @@ -0,0 +1,41 @@ +def generate(env, **kw): + env.SetDefault( + OPENOCD_GDB_PIPE=[ + "|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}" + ], + GDBOPTS_BASE=[ + "-ex", + "target extended-remote ${GDBREMOTE}", + "-ex", + "set confirm off", + "-ex", + "set pagination off", + ], + GDBOPTS_BLACKMAGIC=[ + "-ex", + "monitor swdp_scan", + "-ex", + "monitor debug_bmp enable", + "-ex", + "attach 1", + "-ex", + "set mem inaccessible-by-default off", + ], + GDBPYOPTS=[ + "-ex", + "source debug/FreeRTOS/FreeRTOS.py", + "-ex", + "source debug/flipperapps.py", + "-ex", + "source debug/PyCortexMDebug/PyCortexMDebug.py", + "-ex", + "svd_load ${SVD_FILE}", + "-ex", + "compare-sections", + ], + JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash", + ) + + +def exists(env): + return True diff --git a/site_scons/site_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py similarity index 98% rename from site_scons/site_tools/fbt_dist.py rename to scripts/fbt_tools/fbt_dist.py index 2b5c83df..853013e9 100644 --- a/site_scons/site_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -136,7 +136,6 @@ def generate(env): "CoproBuilder": Builder( action=Action( [ - Mkdir("$TARGET"), '${PYTHON3} "${ROOT_DIR.abspath}/scripts/assets.py" ' "copro ${COPRO_CUBE_DIR} " "${TARGET} ${COPRO_MCU_FAMILY} " @@ -145,7 +144,7 @@ def generate(env): '--stack_file="${COPRO_STACK_BIN}" ' "--stack_addr=${COPRO_STACK_ADDR} ", ], - "", + "\tCOPRO\t${TARGET}", ) ), } diff --git a/site_scons/site_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py similarity index 96% rename from site_scons/site_tools/fbt_extapps.py rename to scripts/fbt_tools/fbt_extapps.py index a1fa7714..34fb942a 100644 --- a/site_scons/site_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -6,12 +6,10 @@ import SCons.Warnings import os import pathlib from fbt.elfmanifest import assemble_manifest_data -from fbt.appmanifest import FlipperManifestException +from fbt.appmanifest import FlipperApplication, FlipperManifestException from fbt.sdk import SdkCache import itertools -from site_scons.fbt.appmanifest import FlipperApplication - def BuildAppElf(env, app): ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR") @@ -111,7 +109,7 @@ def BuildAppElf(env, app): ) app_elf_raw = app_env.Program( - os.path.join(app_work_dir, f"{app.appid}_d"), + os.path.join(ext_apps_work_dir, f"{app.appid}_d"), app_sources, APP_ENTRY=app.entry_point, ) @@ -180,7 +178,7 @@ def validate_app_imports(target, source, env): if unresolved_syms: SCons.Warnings.warn( SCons.Warnings.LinkWarning, - f"{source[0].path}: app won't run. Unresolved symbols: {unresolved_syms}", + f"\033[93m{source[0].path}: app won't run. Unresolved symbols: \033[95m{unresolved_syms}\033[0m", ) diff --git a/scripts/fbt_tools/fbt_help.py b/scripts/fbt_tools/fbt_help.py new file mode 100644 index 00000000..0475f51b --- /dev/null +++ b/scripts/fbt_tools/fbt_help.py @@ -0,0 +1,44 @@ +targets_help = """Configuration variables: +""" + +tail_help = """ + +TASKS: +Building: + firmware_all, fw_dist: + Build firmware; create distribution package + faps, fap_dist: + Build all FAP apps + fap_{APPID}, launch_app APPSRC={APPID}: + Build FAP app with appid={APPID}; upload & start it over USB + +Flashing & debugging: + flash, flash_blackmagic, jflash: + Flash firmware to target using debug probe + flash_usb, flash_usb_full: + Install firmware using self-update package + debug, debug_other, blackmagic: + Start GDB + +Other: + cli: + Open a Flipper CLI session over USB + firmware_cdb, updater_cdb: + Generate сompilation_database.json + lint, lint_py: + run linters + format, format_py: + run code formatters + +For more targets & info, see documentation/fbt.md +""" + + +def generate(env, **kw): + vars = kw["vars"] + basic_help = vars.GenerateHelpText(env) + env.Help(targets_help + basic_help + tail_help) + + +def exists(env): + return True diff --git a/site_scons/site_tools/fbt_sdk.py b/scripts/fbt_tools/fbt_sdk.py similarity index 71% rename from site_scons/site_tools/fbt_sdk.py rename to scripts/fbt_tools/fbt_sdk.py index f6c2d452..ed0abdff 100644 --- a/site_scons/site_tools/fbt_sdk.py +++ b/scripts/fbt_tools/fbt_sdk.py @@ -9,10 +9,32 @@ from SCons.Util import LogicalLines import os.path import posixpath import pathlib +import json from fbt.sdk import SdkCollector, SdkCache +def ProcessSdkDepends(env, filename): + try: + with open(filename, "r") as fin: + lines = LogicalLines(fin).readlines() + except IOError: + return [] + + _, depends = lines[0].split(":", 1) + depends = depends.split() + depends.pop(0) # remove the .c file + depends = list( + # Don't create dependency on non-existing files + # (e.g. when they were renamed since last build) + filter( + lambda file: file.exists(), + (env.File(f"#{path}") for path in depends), + ) + ) + return depends + + def prebuild_sdk_emitter(target, source, env): target.append(env.ChangeFileExtension(target[0], ".d")) target.append(env.ChangeFileExtension(target[0], ".i.c")) @@ -25,6 +47,25 @@ def prebuild_sdk_create_origin_file(target, source, env): sdk_c.write("\n".join(f"#include <{h.path}>" for h in env["SDK_HEADERS"])) +class SdkMeta: + def __init__(self, env): + self.env = env + + def save_to(self, json_manifest_path: str): + meta_contents = { + "sdk_symbols": self.env["SDK_DEFINITION"].name, + "cc_args": self._wrap_scons_vars("$CCFLAGS $_CCCOMCOM"), + "cpp_args": self._wrap_scons_vars("$CXXFLAGS $CCFLAGS $_CCCOMCOM"), + "linker_args": self._wrap_scons_vars("$LINKFLAGS"), + } + with open(json_manifest_path, "wt") as f: + json.dump(meta_contents, f, indent=4) + + def _wrap_scons_vars(self, vars: str): + expanded_vars = self.env.subst(vars, target=Entry("dummy")) + return expanded_vars.replace("\\", "/") + + class SdkTreeBuilder: def __init__(self, env, target, source) -> None: self.env = env @@ -34,8 +75,9 @@ class SdkTreeBuilder: self.header_depends = [] self.header_dirs = [] - self.target_sdk_dir = env.subst("f${TARGET_HW}_sdk") - self.sdk_deploy_dir = target[0].Dir(self.target_sdk_dir) + self.target_sdk_dir_name = env.subst("f${TARGET_HW}_sdk") + self.sdk_root_dir = target[0].Dir(".") + self.sdk_deploy_dir = self.sdk_root_dir.Dir(self.target_sdk_dir_name) def _parse_sdk_depends(self): deps_file = self.source[0] @@ -50,7 +92,7 @@ class SdkTreeBuilder: ) def _generate_sdk_meta(self): - filtered_paths = [self.target_sdk_dir] + filtered_paths = [self.target_sdk_dir_name] full_fw_paths = list( map( os.path.normpath, @@ -62,17 +104,18 @@ class SdkTreeBuilder: for dir in full_fw_paths: if dir in sdk_dirs: filtered_paths.append( - posixpath.normpath(posixpath.join(self.target_sdk_dir, dir)) + posixpath.normpath(posixpath.join(self.target_sdk_dir_name, dir)) ) sdk_env = self.env.Clone() sdk_env.Replace(CPPPATH=filtered_paths) - with open(self.target[0].path, "wt") as f: - cmdline_options = sdk_env.subst( - "$CCFLAGS $_CCCOMCOM", target=Entry("dummy") - ) - f.write(cmdline_options.replace("\\", "/")) - f.write("\n") + meta = SdkMeta(sdk_env) + meta.save_to(self.target[0].path) + + def emitter(self, target, source, env): + target_folder = target[0] + target = [target_folder.File("sdk.opts")] + return target, source def _create_deploy_commands(self): dirs_to_create = set( @@ -81,13 +124,17 @@ class SdkTreeBuilder: actions = [ Delete(self.sdk_deploy_dir), Mkdir(self.sdk_deploy_dir), + Copy( + self.sdk_root_dir, + self.env["SDK_DEFINITION"], + ), ] actions += [Mkdir(d) for d in dirs_to_create] actions += [ - Copy( - self.sdk_deploy_dir.File(h).path, - h, + Action( + Copy(self.sdk_deploy_dir.File(h).path, h), + # f"Copy {h} to {self.sdk_deploy_dir}", ) for h in self.header_depends ] @@ -108,6 +155,11 @@ def deploy_sdk_tree(target, source, env, for_signature): return sdk_tree.generate_actions() +def deploy_sdk_tree_emitter(target, source, env): + sdk_tree = SdkTreeBuilder(env, target, source) + return sdk_tree.emitter(target, source, env) + + def gen_sdk_data(sdk_cache: SdkCache): api_def = [] api_def.extend( @@ -165,6 +217,7 @@ def generate_sdk_symbols(source, target, env): def generate(env, **kw): + env.AddMethod(ProcessSdkDepends) env.Append( BUILDERS={ "SDKPrebuilder": Builder( @@ -183,6 +236,7 @@ def generate(env, **kw): ), "SDKTree": Builder( generator=deploy_sdk_tree, + emitter=deploy_sdk_tree_emitter, src_suffix=".d", ), "SDKSymUpdater": Builder( diff --git a/site_scons/site_tools/fbt_version.py b/scripts/fbt_tools/fbt_version.py similarity index 100% rename from site_scons/site_tools/fbt_version.py rename to scripts/fbt_tools/fbt_version.py diff --git a/site_scons/site_tools/fwbin.py b/scripts/fbt_tools/fwbin.py similarity index 100% rename from site_scons/site_tools/fwbin.py rename to scripts/fbt_tools/fwbin.py diff --git a/site_scons/site_tools/gdb.py b/scripts/fbt_tools/gdb.py similarity index 100% rename from site_scons/site_tools/gdb.py rename to scripts/fbt_tools/gdb.py diff --git a/site_scons/site_tools/jflash.py b/scripts/fbt_tools/jflash.py similarity index 100% rename from site_scons/site_tools/jflash.py rename to scripts/fbt_tools/jflash.py diff --git a/site_scons/site_tools/objdump.py b/scripts/fbt_tools/objdump.py similarity index 100% rename from site_scons/site_tools/objdump.py rename to scripts/fbt_tools/objdump.py diff --git a/site_scons/site_tools/openocd.py b/scripts/fbt_tools/openocd.py similarity index 100% rename from site_scons/site_tools/openocd.py rename to scripts/fbt_tools/openocd.py diff --git a/site_scons/site_tools/python3.py b/scripts/fbt_tools/python3.py similarity index 100% rename from site_scons/site_tools/python3.py rename to scripts/fbt_tools/python3.py diff --git a/site_scons/site_tools/sconsmodular.py b/scripts/fbt_tools/sconsmodular.py similarity index 100% rename from site_scons/site_tools/sconsmodular.py rename to scripts/fbt_tools/sconsmodular.py diff --git a/site_scons/site_tools/sconsrecursiveglob.py b/scripts/fbt_tools/sconsrecursiveglob.py similarity index 100% rename from site_scons/site_tools/sconsrecursiveglob.py rename to scripts/fbt_tools/sconsrecursiveglob.py diff --git a/site_scons/site_tools/strip.py b/scripts/fbt_tools/strip.py similarity index 100% rename from site_scons/site_tools/strip.py rename to scripts/fbt_tools/strip.py diff --git a/scripts/flipper/assets/copro.py b/scripts/flipper/assets/copro.py index 0c78e889..33c3ac23 100644 --- a/scripts/flipper/assets/copro.py +++ b/scripts/flipper/assets/copro.py @@ -1,10 +1,9 @@ import logging -import datetime -import shutil import json -from os.path import basename - +from io import BytesIO +import tarfile import xml.etree.ElementTree as ET + from flipper.utils import * from flipper.assets.coprobin import CoproBinary, get_stack_type @@ -51,20 +50,19 @@ class Copro: raise Exception(f"Unsupported cube version") self.version = cube_version + @staticmethod + def _getFileName(name): + return os.path.join("core2_firmware", name) + def addFile(self, array, filename, **kwargs): source_file = os.path.join(self.mcu_copro, filename) - destination_file = os.path.join(self.output_dir, filename) - shutil.copyfile(source_file, destination_file) - array.append( - {"name": filename, "sha256": file_sha256(destination_file), **kwargs} - ) + self.output_tar.add(source_file, arcname=self._getFileName(filename)) + array.append({"name": filename, "sha256": file_sha256(source_file), **kwargs}) + + def bundle(self, output_file, stack_file_name, stack_type, stack_addr=None): + self.output_tar = tarfile.open(output_file, "w:gz") - def bundle(self, output_dir, stack_file_name, stack_type, stack_addr=None): - if not os.path.isdir(output_dir): - raise Exception(f'"{output_dir}" doesn\'t exists') - self.output_dir = output_dir stack_file = os.path.join(self.mcu_copro, stack_file_name) - manifest_file = os.path.join(self.output_dir, "Manifest.json") # Form Manifest manifest = dict(MANIFEST_TEMPLATE) manifest["manifest"]["timestamp"] = timestamp() @@ -105,6 +103,10 @@ class Copro: stack_file_name, address=f"0x{stack_addr:X}", ) - # Save manifest to - with open(manifest_file, "w", newline="\n") as file: - json.dump(manifest, file) + + # Save manifest + manifest_data = json.dumps(manifest, indent=4).encode("utf-8") + info = tarfile.TarInfo(self._getFileName("Manifest.json")) + info.size = len(manifest_data) + self.output_tar.addfile(info, BytesIO(manifest_data)) + self.output_tar.close() diff --git a/scripts/guruguru.py b/scripts/guruguru.py index 3560bcd9..c227e17e 100755 --- a/scripts/guruguru.py +++ b/scripts/guruguru.py @@ -17,7 +17,7 @@ class Main(App): async def rebuild(self, line): self.clearConsole() self.logger.info(f"Triggered by: {line}") - proc = await asyncio.create_subprocess_exec("make") + proc = await asyncio.create_subprocess_exec("./fbt") await proc.wait() await asyncio.sleep(1) self.is_building = False diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index 1e95ee2f..45ae03e3 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 from flipper.app import App -from os.path import join, exists -from os import makedirs +from os.path import join, exists, relpath +from os import makedirs, walk from update import Main as UpdateMain import shutil +import zipfile +import tarfile class ProjectDir: @@ -17,6 +19,8 @@ class ProjectDir: class Main(App): + DIST_FILE_PREFIX = "flipper-z-" + def init(self): self.subparsers = self.parser.add_subparsers(help="sub-command help") @@ -45,9 +49,13 @@ class Main(App): def get_project_filename(self, project, filetype): # Temporary fix project_name = project.project - if project_name == "firmware" and filetype != "elf": - project_name = "full" - return f"flipper-z-{self.target}-{project_name}-{self.args.suffix}.{filetype}" + if project_name == "firmware": + if filetype == "zip": + project_name = "sdk" + elif filetype != "elf": + project_name = "full" + + return f"{self.DIST_FILE_PREFIX}{self.target}-{project_name}-{self.args.suffix}.{filetype}" def get_dist_filepath(self, filename): return join(self.output_dir_path, filename) @@ -56,10 +64,28 @@ class Main(App): obj_directory = join("build", project.dir) for filetype in ("elf", "bin", "dfu", "json"): - shutil.copyfile( - join(obj_directory, f"{project.project}.{filetype}"), - self.get_dist_filepath(self.get_project_filename(project, filetype)), - ) + if exists(src_file := join(obj_directory, f"{project.project}.{filetype}")): + shutil.copyfile( + src_file, + self.get_dist_filepath( + self.get_project_filename(project, filetype) + ), + ) + if exists(sdk_folder := join(obj_directory, "sdk")): + with zipfile.ZipFile( + self.get_dist_filepath(self.get_project_filename(project, "zip")), + "w", + zipfile.ZIP_DEFLATED, + ) as zf: + for root, dirs, files in walk(sdk_folder): + for file in files: + zf.write( + join(root, file), + relpath( + join(root, file), + sdk_folder, + ), + ) def copy(self): self.projects = dict( @@ -103,9 +129,8 @@ class Main(App): ) if self.args.version: - bundle_dir = join( - self.output_dir_path, f"{self.target}-update-{self.args.suffix}" - ) + bundle_dir_name = f"{self.target}-update-{self.args.suffix}" + bundle_dir = join(self.output_dir_path, bundle_dir_name) bundle_args = [ "generate", "-d", @@ -131,10 +156,24 @@ class Main(App): ) ) bundle_args.extend(self.other_args) - self.logger.info( - f"Use this directory to self-update your Flipper:\n\t{bundle_dir}" - ) - return UpdateMain(no_exit=True)(bundle_args) + + if (bundle_result := UpdateMain(no_exit=True)(bundle_args)) == 0: + self.logger.info( + f"Use this directory to self-update your Flipper:\n\t{bundle_dir}" + ) + + # Create tgz archive + with tarfile.open( + join( + self.output_dir_path, + f"{self.DIST_FILE_PREFIX}{bundle_dir_name}.tgz", + ), + "w:gz", + compresslevel=9, + ) as tar: + tar.add(bundle_dir, arcname=bundle_dir_name) + + return bundle_result return 0 diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 765af08f..324dfe33 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -81,46 +81,41 @@ vars.AddVariables( help="Enable debug tools to be built", default=False, ), -) - -vars.Add( - "DIST_SUFFIX", - help="Suffix for binaries in build output for dist targets", - default="local", -) - -vars.Add( - "UPDATE_VERSION_STRING", - help="Version string for updater package", - default="${DIST_SUFFIX}", -) - - -vars.Add( - "COPRO_CUBE_VERSION", - help="Cube version", - default="", -) - -vars.Add( - "COPRO_STACK_ADDR", - help="Core2 Firmware address", - default="0", -) - -vars.Add( - "COPRO_STACK_BIN", - help="Core2 Firmware file name", - default="", -) - -vars.Add( - "COPRO_DISCLAIMER", - help="Value to pass to bundling script to confirm dangerous operations", - default="", -) - -vars.AddVariables( + BoolVariable( + "FAP_EXAMPLES", + help="Enable example applications to be built", + default=False, + ), + ( + "DIST_SUFFIX", + "Suffix for binaries in build output for dist targets", + "local", + ), + ( + "UPDATE_VERSION_STRING", + "Version string for updater package", + "${DIST_SUFFIX}", + ), + ( + "COPRO_CUBE_VERSION", + "Cube version", + "", + ), + ( + "COPRO_STACK_ADDR", + "Core2 Firmware address", + "0", + ), + ( + "COPRO_STACK_BIN", + "Core2 Firmware file name", + "", + ), + ( + "COPRO_DISCLAIMER", + "Value to pass to bundling script to confirm dangerous operations", + "", + ), PathVariable( "COPRO_OB_DATA", help="Path to OB reference data", @@ -161,86 +156,75 @@ vars.AddVariables( validator=PathVariable.PathAccept, default="", ), -) - -vars.Add( - "FBT_TOOLCHAIN_VERSIONS", - help="Whitelisted toolchain versions (leave empty for no check)", - default=tuple(), -) - -vars.Add( - "OPENOCD_OPTS", - help="Options to pass to OpenOCD", - default="", -) - -vars.Add( - "BLACKMAGIC", - help="Blackmagic probe location", - default="auto", -) - -vars.Add( - "UPDATE_SPLASH", - help="Directory name with slideshow frames to render after installing update package", - default="update_default", -) - -vars.Add( - "LOADER_AUTOSTART", - help="Application name to automatically run on Flipper boot", - default="", -) - - -vars.Add( - "FIRMWARE_APPS", - help="Map of (configuration_name->application_list)", - default={ - "default": ( - # Svc - "basic_services", - # Apps - "main_apps", - "system_apps", - # Settings - "settings_apps", - # Plugins - # "basic_plugins", - # Debug - # "debug_apps", - ) - }, -) - -vars.Add( - "FIRMWARE_APP_SET", - help="Application set to use from FIRMWARE_APPS", - default="default", -) - -vars.Add( - "APPSRC", - help="Application source directory for app to build & upload", - default="", -) - -# List of tuples (directory, add_to_global_include_path) -vars.Add( - "APPDIRS", - help="Directories to search for firmware components & external apps", - default=[ - ("applications", False), - ("applications/services", True), - ("applications/main", True), - ("applications/settings", False), - ("applications/system", False), - ("applications/debug", False), - ("applications/plugins", False), - ("applications/examples", False), - ("applications_user", False), - ], + ( + "FBT_TOOLCHAIN_VERSIONS", + "Whitelisted toolchain versions (leave empty for no check)", + tuple(), + ), + ( + "OPENOCD_OPTS", + "Options to pass to OpenOCD", + "", + ), + ( + "BLACKMAGIC", + "Blackmagic probe location", + "auto", + ), + ( + "UPDATE_SPLASH", + "Directory name with slideshow frames to render after installing update package", + "update_default", + ), + ( + "LOADER_AUTOSTART", + "Application name to automatically run on Flipper boot", + "", + ), + ( + "FIRMWARE_APPS", + "Map of (configuration_name->application_list)", + { + "default": ( + # Svc + "basic_services", + # Apps + "main_apps", + "system_apps", + # Settings + "settings_apps", + # Plugins + # "basic_plugins", + # Debug + # "debug_apps", + ) + }, + ), + ( + "FIRMWARE_APP_SET", + "Application set to use from FIRMWARE_APPS", + "default", + ), + ( + "APPSRC", + "Application source directory for app to build & upload", + "", + ), + # List of tuples (directory, add_to_global_include_path) + ( + "APPDIRS", + "Directories to search for firmware components & external apps", + [ + ("applications", False), + ("applications/services", True), + ("applications/main", True), + ("applications/settings", False), + ("applications/system", False), + ("applications/debug", False), + ("applications/plugins", False), + ("applications_user", False), + ], + ), ) Return("vars") diff --git a/site_scons/environ.scons b/site_scons/environ.scons index 3e0c6bea..2d082838 100644 --- a/site_scons/environ.scons +++ b/site_scons/environ.scons @@ -1,6 +1,5 @@ -import SCons from SCons.Platform import TempFileMunge -from fbt import util +from fbt.util import tempfile_arg_esc_func, single_quote, wrap_tempfile import os import multiprocessing @@ -13,14 +12,18 @@ forward_os_env = { } # Proxying CI environment to child processes & scripts variables_to_forward = [ + # CI/CD variables "WORKFLOW_BRANCH_OR_TAG", "DIST_SUFFIX", + # Python & other tools "HOME", "APPDATA", "PYTHONHOME", "PYTHONNOUSERSITE", "TMP", "TEMP", + # Colors for tools + "TERM", ] if proxy_env := GetOption("proxy_env"): variables_to_forward.extend(proxy_env.split(",")) @@ -79,7 +82,7 @@ if not coreenv["VERBOSE"]: SetOption("num_jobs", multiprocessing.cpu_count()) # Avoiding re-scan of all sources on every startup SetOption("implicit_cache", True) -SetOption("implicit_deps_unchanged", True) +# SetOption("implicit_deps_unchanged", True) # More aggressive caching SetOption("max_drift", 1) # Random task queue - to discover isses with build logic faster @@ -87,10 +90,10 @@ SetOption("max_drift", 1) # Setting up temp file parameters - to overcome command line length limits -coreenv["TEMPFILEARGESCFUNC"] = util.tempfile_arg_esc_func -util.wrap_tempfile(coreenv, "LINKCOM") -util.wrap_tempfile(coreenv, "ARCOM") +coreenv["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func +wrap_tempfile(coreenv, "LINKCOM") +wrap_tempfile(coreenv, "ARCOM") -coreenv["SINGLEQUOTEFUNC"] = util.single_quote +coreenv["SINGLEQUOTEFUNC"] = single_quote Return("coreenv") diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index c976fbbe..9edc6b5c 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -21,7 +21,7 @@ appenv = ENV.Clone( ) appenv.Replace( - LINKER_SCRIPT="application-ext", + LINKER_SCRIPT="application_ext", ) appenv.AppendUnique( @@ -106,6 +106,7 @@ appenv.PhonyTarget("firmware_extapps", appenv.Action(legacy_app_build_stub, None Alias("faps", extapps["compact"].values()) +Alias("faps", extapps["validators"].values()) if appsrc := appenv.subst("$APPSRC"): app_manifest, fap_file, app_validator = appenv.GetExtAppFromPath(appsrc) diff --git a/site_scons/fbt_extra/util.py b/site_scons/fbt_extra/util.py new file mode 100644 index 00000000..aa3d50b6 --- /dev/null +++ b/site_scons/fbt_extra/util.py @@ -0,0 +1,23 @@ +from fbt.util import link_dir + + +def link_elf_dir_as_latest(env, elf_node): + elf_dir = elf_node.Dir(".") + latest_dir = env.Dir("#build/latest") + print(f"Setting {elf_dir} as latest built dir (./build/latest/)") + return link_dir(latest_dir.abspath, elf_dir.abspath, env["PLATFORM"] == "win32") + + +def should_gen_cdb_and_link_dir(env, requested_targets): + explicitly_building_updater = False + # Hacky way to check if updater-related targets were requested + for build_target in requested_targets: + if "updater" in str(build_target): + explicitly_building_updater = True + + is_updater = not env["IS_BASE_FIRMWARE"] + # If updater is explicitly requested, link to the latest updater + # Otherwise, link to firmware + return (is_updater and explicitly_building_updater) or ( + not is_updater and not explicitly_building_updater + ) From ede3bac799f8c2c7e1184b09473fd0ecc1d2c511 Mon Sep 17 00:00:00 2001 From: Thibaut CHARLES Date: Wed, 12 Oct 2022 18:21:54 +0200 Subject: [PATCH 39/49] Badusb: show script errors on screen (#1506) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/bad_usb/bad_usb_script.c | 39 +++++++++++++++++-- applications/main/bad_usb/bad_usb_script.h | 1 + .../main/bad_usb/views/bad_usb_view.c | 1 + 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 78aba88e..8ff38ef6 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -231,7 +231,8 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) { return 0; } -static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { +static int32_t + ducky_parse_line(BadUsbScript* bad_usb, FuriString* line, char* error, size_t error_len) { uint32_t line_len = furi_string_size(line); const char* line_tmp = furi_string_get_cstr(line); bool state = false; @@ -261,6 +262,9 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { if((state) && (delay_val > 0)) { return (int32_t)delay_val; } + if(error != NULL) { + snprintf(error, error_len, "Invalid number %s", line_tmp); + } return SCRIPT_STATE_ERROR; } else if( (strncmp(line_tmp, ducky_cmd_defdelay_1, strlen(ducky_cmd_defdelay_1)) == 0) || @@ -268,17 +272,26 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { // DEFAULT_DELAY line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; state = ducky_get_number(line_tmp, &bad_usb->defdelay); + if(!state && error != NULL) { + snprintf(error, error_len, "Invalid number %s", line_tmp); + } return (state) ? (0) : SCRIPT_STATE_ERROR; } else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) { // STRING line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; state = ducky_string(line_tmp); + if(!state && error != NULL) { + snprintf(error, error_len, "Invalid string %s", line_tmp); + } return (state) ? (0) : SCRIPT_STATE_ERROR; } else if(strncmp(line_tmp, ducky_cmd_altchar, strlen(ducky_cmd_altchar)) == 0) { // ALTCHAR line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; ducky_numlock_on(); state = ducky_altchar(line_tmp); + if(!state && error != NULL) { + snprintf(error, error_len, "Invalid altchar %s", line_tmp); + } return (state) ? (0) : SCRIPT_STATE_ERROR; } else if( (strncmp(line_tmp, ducky_cmd_altstr_1, strlen(ducky_cmd_altstr_1)) == 0) || @@ -287,11 +300,17 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; ducky_numlock_on(); state = ducky_altstring(line_tmp); + if(!state && error != NULL) { + snprintf(error, error_len, "Invalid altstring %s", line_tmp); + } return (state) ? (0) : SCRIPT_STATE_ERROR; } else if(strncmp(line_tmp, ducky_cmd_repeat, strlen(ducky_cmd_repeat)) == 0) { // REPEAT line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt); + if(!state && error != NULL) { + snprintf(error, error_len, "Invalid number %s", line_tmp); + } return (state) ? (0) : SCRIPT_STATE_ERROR; } else if(strncmp(line_tmp, ducky_cmd_sysrq, strlen(ducky_cmd_sysrq)) == 0) { // SYSRQ @@ -304,7 +323,12 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { } else { // Special keys + modifiers uint16_t key = ducky_get_keycode(line_tmp, false); - if(key == HID_KEYBOARD_NONE) return SCRIPT_STATE_ERROR; + if(key == HID_KEYBOARD_NONE) { + if(error != NULL) { + snprintf(error, error_len, "No keycode defined for %s", line_tmp); + } + return SCRIPT_STATE_ERROR; + } if((key & 0xFF00) != 0) { // It's a modifier key line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; @@ -314,6 +338,9 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { furi_hal_hid_kb_release(key); return (0); } + if(error != NULL) { + strncpy(error, "Unknown error", error_len); + } return SCRIPT_STATE_ERROR; } @@ -392,7 +419,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil if(bad_usb->repeat_cnt > 0) { bad_usb->repeat_cnt--; - delay_val = ducky_parse_line(bad_usb, bad_usb->line_prev); + delay_val = ducky_parse_line( + bad_usb, bad_usb->line_prev, bad_usb->st.error, sizeof(bad_usb->st.error)); if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line return 0; } else if(delay_val < 0) { // Script error @@ -426,7 +454,9 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil bad_usb->st.line_cur++; bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1); bad_usb->buf_start = i + 1; - delay_val = ducky_parse_line(bad_usb, bad_usb->line); + delay_val = ducky_parse_line( + bad_usb, bad_usb->line, bad_usb->st.error, sizeof(bad_usb->st.error)); + if(delay_val < 0) { bad_usb->st.error_line = bad_usb->st.line_cur; FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); @@ -602,6 +632,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) { furi_string_set(bad_usb->file_path, file_path); bad_usb->st.state = BadUsbStateInit; + bad_usb->st.error[0] = '\0'; bad_usb->thread = furi_thread_alloc(); furi_thread_set_name(bad_usb->thread, "BadUsbWorker"); diff --git a/applications/main/bad_usb/bad_usb_script.h b/applications/main/bad_usb/bad_usb_script.h index 5fee6505..f24372fa 100644 --- a/applications/main/bad_usb/bad_usb_script.h +++ b/applications/main/bad_usb/bad_usb_script.h @@ -25,6 +25,7 @@ typedef struct { uint16_t line_nb; uint32_t delay_remain; uint16_t error_line; + char error[64]; } BadUsbState; BadUsbScript* bad_usb_script_open(FuriString* file_path); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index db10d01e..6c6a1584 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -53,6 +53,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned( canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); + canvas_draw_str_aligned(canvas, 127, 56, AlignRight, AlignBottom, model->state.error); } else if(model->state.state == BadUsbStateIdle) { canvas_draw_icon(canvas, 4, 22, &I_Smile_18x18); canvas_set_font(canvas, FontBigNumbers); From 50dc2d738991205f2d05905517fac96c619c3b5a Mon Sep 17 00:00:00 2001 From: Luke Williams Date: Wed, 12 Oct 2022 11:31:54 -0500 Subject: [PATCH 40/49] 36-bit AWID (L11601 Lenel) (#1838) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 36-bit AWID * Rfid: correct vendor name AWIG -> AWID Co-authored-by: Sergey Gavrilov Co-authored-by: あく --- lib/lfrfid/protocols/protocol_awid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 88093900..38c7793b 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -81,7 +81,7 @@ static bool protocol_awid_can_be_decoded(uint8_t* data) { // Avoid detection for invalid formats uint8_t len = bit_lib_get_bits(data, 8, 8); - if(len != 26 && len != 50 && len != 37 && len != 34) break; + if(len != 26 && len != 50 && len != 37 && len != 34 && len != 36) break; result = true; } while(false); @@ -207,7 +207,7 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) { // Fix incorrect length byte if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 && - protocol->data[0] != 34) { + protocol->data[0] != 34 && protocol->data[0] != 36 ) { protocol->data[0] = 26; } @@ -232,7 +232,7 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) { const ProtocolBase protocol_awid = { .name = "AWID", - .manufacturer = "AWIG", + .manufacturer = "AWID", .data_size = AWID_DECODED_DATA_SIZE, .features = LFRFIDFeatureASK, .validate_count = 3, From 8fdee1e46065036caff72194ad887b14638effb8 Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 13 Oct 2022 19:05:07 +0400 Subject: [PATCH 41/49] Scripts: simpler tar format (#1871) * scriptsL simpler tar format * scripts: shorter names for files in update bundle * scripts: limiting max OTA package dir name length to 80 * scripts: resource bundle: checks for file name length * scripts: made resource packing errors critical --- scripts/flipper/assets/copro.py | 2 +- scripts/sconsdist.py | 6 +++++- scripts/update.py | 37 +++++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/scripts/flipper/assets/copro.py b/scripts/flipper/assets/copro.py index 33c3ac23..d39f3033 100644 --- a/scripts/flipper/assets/copro.py +++ b/scripts/flipper/assets/copro.py @@ -60,7 +60,7 @@ class Copro: array.append({"name": filename, "sha256": file_sha256(source_file), **kwargs}) def bundle(self, output_file, stack_file_name, stack_type, stack_addr=None): - self.output_tar = tarfile.open(output_file, "w:gz") + self.output_tar = tarfile.open(output_file, "w:gz", format=tarfile.USTAR_FORMAT) stack_file = os.path.join(self.mcu_copro, stack_file_name) # Form Manifest diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index 45ae03e3..cb4f8f5a 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -20,6 +20,7 @@ class ProjectDir: class Main(App): DIST_FILE_PREFIX = "flipper-z-" + DIST_FOLDER_MAX_NAME_LENGTH = 80 def init(self): self.subparsers = self.parser.add_subparsers(help="sub-command help") @@ -129,7 +130,9 @@ class Main(App): ) if self.args.version: - bundle_dir_name = f"{self.target}-update-{self.args.suffix}" + bundle_dir_name = f"{self.target}-update-{self.args.suffix}"[ + : self.DIST_FOLDER_MAX_NAME_LENGTH + ] bundle_dir = join(self.output_dir_path, bundle_dir_name) bundle_args = [ "generate", @@ -170,6 +173,7 @@ class Main(App): ), "w:gz", compresslevel=9, + format=tarfile.USTAR_FORMAT, ) as tar: tar.add(bundle_dir, arcname=bundle_dir_name) diff --git a/scripts/update.py b/scripts/update.py index 52391965..6be1dce0 100755 --- a/scripts/update.py +++ b/scripts/update.py @@ -22,6 +22,7 @@ class Main(App): RESOURCE_TAR_MODE = "w:" RESOURCE_TAR_FORMAT = tarfile.USTAR_FORMAT RESOURCE_FILE_NAME = "resources.tar" + RESOURCE_ENTRY_NAME_MAX_LENGTH = 100 WHITELISTED_STACK_TYPES = set( map( @@ -76,9 +77,9 @@ class Main(App): self.parser_generate.set_defaults(func=self.generate) def generate(self): - stage_basename = basename(self.args.stage) - dfu_basename = basename(self.args.dfu) - radiobin_basename = basename(self.args.radiobin) + stage_basename = "updater.bin" # used to be basename(self.args.stage) + dfu_basename = "firmware.dfu" # used to be basename(self.args.dfu) + radiobin_basename = "radio.bin" # used to be basename(self.args.radiobin) resources_basename = "" radio_version = 0 @@ -120,9 +121,10 @@ class Main(App): ) if self.args.resources: resources_basename = self.RESOURCE_FILE_NAME - self.package_resources( + if not self.package_resources( self.args.resources, join(self.args.directory, resources_basename) - ) + ): + return 3 if not self.layout_check(dfu_size, radio_addr): self.logger.warn("Memory layout looks suspicious") @@ -199,11 +201,28 @@ class Main(App): "Please confirm that you REALLY want to do that with --I-understand-what-I-am-doing=yes" ) + def _tar_filter(self, tarinfo: tarfile.TarInfo): + if len(tarinfo.name) > self.RESOURCE_ENTRY_NAME_MAX_LENGTH: + self.logger.error( + f"Cannot package resource: name '{tarinfo.name}' too long" + ) + raise ValueError("Resource name too long") + return tarinfo + def package_resources(self, srcdir: str, dst_name: str): - with tarfile.open( - dst_name, self.RESOURCE_TAR_MODE, format=self.RESOURCE_TAR_FORMAT - ) as tarball: - tarball.add(srcdir, arcname="") + try: + with tarfile.open( + dst_name, self.RESOURCE_TAR_MODE, format=self.RESOURCE_TAR_FORMAT + ) as tarball: + tarball.add( + srcdir, + arcname="", + filter=self._tar_filter, + ) + return True + except ValueError as e: + self.logger.error(f"Cannot package resources: {e}") + return False @staticmethod def copro_version_as_int(coprometa, stacktype): From e46e6f8ee90109315af75f89595f0921e5be8494 Mon Sep 17 00:00:00 2001 From: Dzhos Oleksii <35292229+Programistich@users.noreply.github.com> Date: Thu, 13 Oct 2022 18:34:27 +0300 Subject: [PATCH 42/49] Update title for web updater (#1872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fb67ed1..7d616295 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -127,7 +127,7 @@ jobs: **Compiled firmware for commit `${{steps.names.outputs.commit_sha}}`:** - [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz) - [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu) - - [☁️ Web updater](https://my.flipp.dev/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}}) + - [☁️ Web/App updater](https://my.flipp.dev/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}}) edit-mode: replace compact: From 55f8beef9f842d1b8a633562330490fe6c55a79c Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 13 Oct 2022 19:23:29 +0300 Subject: [PATCH 43/49] [FL-2876] MFC Improvements Part 2/2 (#1868) * Remove keys incorrectly added by the key cache * Improve responsiveness while checking for re-used keys and fix skipping keys when card is removed * Actually check if the card is completely read * Discard incorrect keys on a lower level * nfc: clean up Co-authored-by: gornekich --- lib/nfc/nfc_worker.c | 80 +++++++++++++++++++----------- lib/nfc/protocols/mifare_classic.c | 39 ++++++++++++++- lib/nfc/protocols/mifare_classic.h | 4 ++ 3 files changed, 93 insertions(+), 30 deletions(-) diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 55d67c65..ebe20390 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -191,7 +191,7 @@ static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FuriHalNfcTxRxCont uint8_t sectors_total = mf_classic_get_total_sectors_num(nfc_worker->dev_data->mf_classic_data.type); FURI_LOG_I(TAG, "Read %d sectors out of %d total", sectors_read, sectors_total); - read_success = (sectors_read == sectors_total); + read_success = mf_classic_is_card_read(&nfc_worker->dev_data->mf_classic_data); } } while(false); @@ -480,6 +480,9 @@ static void nfc_worker_mf_classic_key_attack( uint16_t start_sector) { furi_assert(nfc_worker); + bool card_found_notified = true; + bool card_removed_notified = false; + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); @@ -487,36 +490,52 @@ static void nfc_worker_mf_classic_key_attack( // Check every sector's A and B keys with the given key for(size_t i = start_sector; i < total_sectors; i++) { - uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); - if(mf_classic_is_sector_read(data, i)) continue; - if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { - FURI_LOG_D( - TAG, - "Trying A key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { - mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D(TAG, "Key found"); - nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + furi_hal_nfc_sleep(); + if(furi_hal_nfc_activate_nfca(200, NULL)) { + furi_hal_nfc_sleep(); + if(!card_found_notified) { + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + card_found_notified = true; + card_removed_notified = false; + } + uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); + if(mf_classic_is_sector_read(data, i)) continue; + if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { + FURI_LOG_D( + TAG, + "Trying A key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { + mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + } + } + if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { + FURI_LOG_D( + TAG, + "Trying B key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { + mf_classic_set_key_found(data, i, MfClassicKeyB, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + } + } + + if(mf_classic_is_sector_read(data, i)) continue; + mf_classic_read_sector(tx_rx, data, i); + } else { + if(!card_removed_notified) { + nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); + card_removed_notified = true; + card_found_notified = false; } } - if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { - FURI_LOG_D( - TAG, - "Trying B key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { - mf_classic_set_key_found(data, i, MfClassicKeyB, key); - FURI_LOG_D(TAG, "Key found"); - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - } - } - if(mf_classic_is_sector_read(data, i)) continue; - mf_classic_read_sector(tx_rx, data, i); if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; } } @@ -530,6 +549,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { &nfc_worker->dev_data->mf_classic_dict_attack_data; uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); uint64_t key = 0; + uint64_t prev_key = 0; FuriHalNfcTxRxContext tx_rx = {}; bool card_found_notified = true; bool card_removed_notified = false; @@ -564,6 +584,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); card_found_notified = true; card_removed_notified = false; + nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); } FURI_LOG_D( TAG, @@ -600,6 +621,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { } if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; } + memcpy(&prev_key, &key, sizeof(key)); } if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; mf_classic_read_sector(&tx_rx, data, i); diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 78320245..e879ff4e 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -155,6 +155,16 @@ void mf_classic_set_key_found( } } +void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) { + furi_assert(data); + + if(key_type == MfClassicKeyA) { + FURI_BIT_CLEAR(data->key_a_mask, sector_num); + } else if(key_type == MfClassicKeyB) { + FURI_BIT_CLEAR(data->key_b_mask, sector_num); + } +} + bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) { furi_assert(data); @@ -203,6 +213,18 @@ void mf_classic_get_read_sectors_and_keys( } } +bool mf_classic_is_card_read(MfClassicData* data) { + furi_assert(data); + + uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type); + uint8_t sectors_read = 0; + uint8_t keys_found = 0; + mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); + bool card_read = (sectors_read == sectors_total) && (keys_found == sectors_total * 2); + + return card_read; +} + static bool mf_classic_is_allowed_access_sector_trailer( MfClassicEmulator* emulator, uint8_t block_num, @@ -612,7 +634,15 @@ static bool mf_classic_read_sector_with_reader( } // Auth to first block in sector - if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto)) break; + if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto)) { + // Set key to MF_CLASSIC_NO_KEY to prevent further attempts + if(key_type == MfClassicKeyA) { + sector_reader->key_a = MF_CLASSIC_NO_KEY; + } else { + sector_reader->key_b = MF_CLASSIC_NO_KEY; + } + break; + } sector->total_blocks = mf_classic_get_blocks_num_in_sector(sector_reader->sector_num); // Read blocks @@ -711,6 +741,13 @@ uint8_t mf_classic_update_card(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]); } sectors_read++; + } else { + // Invalid key, set it to not found + if(key_a != MF_CLASSIC_NO_KEY) { + mf_classic_set_key_not_found(data, i, MfClassicKeyA); + } else { + mf_classic_set_key_not_found(data, i, MfClassicKeyB); + } } } } diff --git a/lib/nfc/protocols/mifare_classic.h b/lib/nfc/protocols/mifare_classic.h index b9921fb1..ead846e4 100644 --- a/lib/nfc/protocols/mifare_classic.h +++ b/lib/nfc/protocols/mifare_classic.h @@ -98,12 +98,16 @@ void mf_classic_set_key_found( MfClassicKey key_type, uint64_t key); +void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type); + bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num); void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data); bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num); +bool mf_classic_is_card_read(MfClassicData* data); + void mf_classic_get_read_sectors_and_keys( MfClassicData* data, uint8_t* sectors_read, From d5b239595fd40f06d9f9a79e3163886723a3c336 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Oct 2022 13:09:37 -0500 Subject: [PATCH 44/49] Desktop: Set external apps as favorites (#1816) * MVP * Display app name and icon in browser * Pre-select favorites in submenu and browser * Show animation while external favorite is loading * A little birdie told me... (Missing record_close) * DesktopSettings: reset submenu before running dialog Co-authored-by: Aleksandr Kutuzov --- applications/main/fap_loader/fap_loader_app.c | 1 + .../services/desktop/desktop_settings.h | 14 ++- .../desktop/scenes/desktop_scene_main.c | 26 +++-- .../desktop_settings/desktop_settings_app.c | 2 + .../desktop_settings/desktop_settings_app.h | 2 + .../scenes/desktop_settings_scene_favorite.c | 108 ++++++++++++++++-- 6 files changed, 130 insertions(+), 23 deletions(-) diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index d2f6b1f4..6c909aee 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -182,6 +182,7 @@ int32_t fap_loader_app(void* p) { FapLoader* loader; if(p) { loader = fap_loader_alloc((const char*)p); + view_dispatcher_switch_to_view(loader->view_dispatcher, 0); fap_loader_run_selected_app(loader); } else { loader = fap_loader_alloc(EXT_PATH("apps")); diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index 3b10fbb1..e502c35f 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -8,7 +8,7 @@ #include #include -#define DESKTOP_SETTINGS_VER (5) +#define DESKTOP_SETTINGS_VER (6) #define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) #define DESKTOP_SETTINGS_MAGIC (0x17) @@ -34,6 +34,9 @@ #define MAX_PIN_SIZE 10 #define MIN_PIN_SIZE 4 +#define MAX_APP_LENGTH 128 + +#define FAP_LOADER_APP_NAME "Applications" typedef struct { InputKey data[MAX_PIN_SIZE]; @@ -41,8 +44,13 @@ typedef struct { } PinCode; typedef struct { - uint16_t favorite_primary; - uint16_t favorite_secondary; + bool is_external; + char name_or_path[MAX_APP_LENGTH]; +} FavoriteApp; + +typedef struct { + FavoriteApp favorite_primary; + FavoriteApp favorite_secondary; PinCode pin_code; uint8_t is_locked; uint32_t auto_lock_delay_ms; diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index dc9ac04d..654de44d 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -114,29 +114,39 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { case DesktopMainEventOpenFavoritePrimary: DESKTOP_SETTINGS_LOAD(&desktop->settings); - if(desktop->settings.favorite_primary < FLIPPER_APPS_COUNT) { + if(desktop->settings.favorite_primary.is_external) { LoaderStatus status = loader_start( - desktop->loader, FLIPPER_APPS[desktop->settings.favorite_primary].name, NULL); + desktop->loader, + FAP_LOADER_APP_NAME, + desktop->settings.favorite_primary.name_or_path); if(status != LoaderStatusOk) { FURI_LOG_E(TAG, "loader_start failed: %d", status); } } else { - FURI_LOG_E(TAG, "Can't find primary favorite application"); + LoaderStatus status = loader_start( + desktop->loader, desktop->settings.favorite_primary.name_or_path, NULL); + if(status != LoaderStatusOk) { + FURI_LOG_E(TAG, "loader_start failed: %d", status); + } } consumed = true; break; case DesktopMainEventOpenFavoriteSecondary: DESKTOP_SETTINGS_LOAD(&desktop->settings); - if(desktop->settings.favorite_secondary < FLIPPER_APPS_COUNT) { + if(desktop->settings.favorite_secondary.is_external) { LoaderStatus status = loader_start( desktop->loader, - FLIPPER_APPS[desktop->settings.favorite_secondary].name, - NULL); + FAP_LOADER_APP_NAME, + desktop->settings.favorite_secondary.name_or_path); if(status != LoaderStatusOk) { FURI_LOG_E(TAG, "loader_start failed: %d", status); } } else { - FURI_LOG_E(TAG, "Can't find secondary favorite application"); + LoaderStatus status = loader_start( + desktop->loader, desktop->settings.favorite_secondary.name_or_path, NULL); + if(status != LoaderStatusOk) { + FURI_LOG_E(TAG, "loader_start failed: %d", status); + } } consumed = true; break; @@ -166,7 +176,7 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { } case DesktopMainEventOpenGameMenu: { LoaderStatus status = loader_start( - desktop->loader, "Applications", EXT_PATH("/apps/Games/snake_game.fap")); + desktop->loader, FAP_LOADER_APP_NAME, EXT_PATH("/apps/Games/snake_game.fap")); if(status != LoaderStatusOk) { FURI_LOG_E(TAG, "loader_start failed: %d", status); } diff --git a/applications/settings/desktop_settings/desktop_settings_app.c b/applications/settings/desktop_settings/desktop_settings_app.c index a2ed8b72..afb5d59e 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.c +++ b/applications/settings/desktop_settings/desktop_settings_app.c @@ -22,6 +22,7 @@ DesktopSettingsApp* desktop_settings_app_alloc() { DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); app->gui = furi_record_open(RECORD_GUI); + app->dialogs = furi_record_open(RECORD_DIALOGS); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&desktop_settings_scene_handlers, app); view_dispatcher_enable_queue(app->view_dispatcher); @@ -83,6 +84,7 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); // Records + furi_record_close(RECORD_DIALOGS); furi_record_close(RECORD_GUI); free(app); } diff --git a/applications/settings/desktop_settings/desktop_settings_app.h b/applications/settings/desktop_settings/desktop_settings_app.h index 25c5b3ad..fc56c325 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 @@ -25,6 +26,7 @@ typedef struct { DesktopSettings settings; Gui* gui; + DialogsApp* dialogs; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; VariableItemList* variable_item_list; 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 d8c579b3..07ba9925 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -1,6 +1,28 @@ #include "../desktop_settings_app.h" #include "applications.h" #include "desktop_settings_scene.h" +#include +#include +#include + +static bool favorite_fap_selector_item_callback( + FuriString* file_path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { + UNUSED(context); + Storage* storage = furi_record_open(RECORD_STORAGE); + bool success = fap_loader_load_name_and_icon(file_path, storage, icon_ptr, item_name); + furi_record_close(RECORD_STORAGE); + return success; +} + +static bool favorite_fap_selector_file_exists(char* file_path) { + Storage* storage = furi_record_open(RECORD_STORAGE); + bool exists = storage_file_exists(storage, file_path); + furi_record_close(RECORD_STORAGE); + return exists; +} static void desktop_settings_scene_favorite_submenu_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; @@ -12,6 +34,10 @@ void desktop_settings_scene_favorite_on_enter(void* context) { Submenu* submenu = app->submenu; submenu_reset(submenu); + uint32_t primary_favorite = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); + uint32_t pre_select_item = 0; + for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { submenu_add_item( submenu, @@ -19,38 +45,96 @@ void desktop_settings_scene_favorite_on_enter(void* context) { i, desktop_settings_scene_favorite_submenu_callback, app); - } - uint32_t primary_favorite = - scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); + if(primary_favorite) { // Select favorite item in submenu + if((app->settings.favorite_primary.is_external && + !strcmp(FLIPPER_APPS[i].name, FAP_LOADER_APP_NAME)) || + (!strcmp(FLIPPER_APPS[i].name, app->settings.favorite_primary.name_or_path))) { + pre_select_item = i; + } + } else { + if((app->settings.favorite_secondary.is_external && + !strcmp(FLIPPER_APPS[i].name, FAP_LOADER_APP_NAME)) || + (!strcmp(FLIPPER_APPS[i].name, app->settings.favorite_secondary.name_or_path))) { + pre_select_item = i; + } + } + } submenu_set_header( - app->submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:"); + submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:"); + submenu_set_selected_item(submenu, pre_select_item); // If set during loop, visual glitch. - if(primary_favorite) { - submenu_set_selected_item(app->submenu, app->settings.favorite_primary); - } else { - submenu_set_selected_item(app->submenu, app->settings.favorite_secondary); - } view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); } bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent event) { DesktopSettingsApp* app = context; bool consumed = false; + FuriString* temp_path = furi_string_alloc_set_str(EXT_PATH("apps")); uint32_t primary_favorite = scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); if(event.type == SceneManagerEventTypeCustom) { - if(primary_favorite) { - app->settings.favorite_primary = event.event; + if(strcmp(FLIPPER_APPS[event.event].name, FAP_LOADER_APP_NAME)) { + if(primary_favorite) { + app->settings.favorite_primary.is_external = false; + strncpy( + app->settings.favorite_primary.name_or_path, + FLIPPER_APPS[event.event].name, + MAX_APP_LENGTH); + } else { + app->settings.favorite_secondary.is_external = false; + strncpy( + app->settings.favorite_secondary.name_or_path, + FLIPPER_APPS[event.event].name, + MAX_APP_LENGTH); + } } else { - app->settings.favorite_secondary = event.event; + const DialogsFileBrowserOptions browser_options = { + .extension = ".fap", + .icon = &I_unknown_10px, + .skip_assets = true, + .hide_ext = true, + .item_loader_callback = favorite_fap_selector_item_callback, + .item_loader_context = app, + }; + + if(primary_favorite) { // Select favorite fap in file browser + if(favorite_fap_selector_file_exists( + app->settings.favorite_primary.name_or_path)) { + furi_string_set_str(temp_path, app->settings.favorite_primary.name_or_path); + } + } else { + if(favorite_fap_selector_file_exists( + app->settings.favorite_secondary.name_or_path)) { + furi_string_set_str(temp_path, app->settings.favorite_secondary.name_or_path); + } + } + + submenu_reset(app->submenu); + if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { + if(primary_favorite) { + app->settings.favorite_primary.is_external = true; + strncpy( + app->settings.favorite_primary.name_or_path, + furi_string_get_cstr(temp_path), + MAX_APP_LENGTH); + } else { + app->settings.favorite_secondary.is_external = true; + strncpy( + app->settings.favorite_secondary.name_or_path, + furi_string_get_cstr(temp_path), + MAX_APP_LENGTH); + } + } } scene_manager_previous_scene(app->scene_manager); consumed = true; } + + furi_string_free(temp_path); return consumed; } From 9ff29d12b2e25e6053b9fcff41a4c64523094f23 Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Fri, 14 Oct 2022 18:54:52 +0200 Subject: [PATCH 45/49] Fix typo in fap loader logging (#1875) --- applications/main/fap_loader/fap_loader_app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index 6c909aee..faf8eefc 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -101,7 +101,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { } FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start)); - FURI_LOG_I(TAG, "FAP Loader is staring app"); + FURI_LOG_I(TAG, "FAP Loader is starting app"); FuriThread* thread = flipper_application_spawn(loader->app, NULL); furi_thread_start(thread); From ead9f134f4e554cd29d30ed4b7c55bc184db3774 Mon Sep 17 00:00:00 2001 From: gornekich Date: Fri, 14 Oct 2022 21:21:23 +0400 Subject: [PATCH 46/49] [FL-2623] Add BLE disconnect request #1686 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: LionZXY Co-authored-by: あく --- applications/services/bt/bt_service/bt.c | 19 +++++-- firmware/targets/f7/ble_glue/serial_service.c | 53 ++++++++++++++++++- firmware/targets/f7/ble_glue/serial_service.h | 8 +++ .../targets/f7/furi_hal/furi_hal_bt_serial.c | 10 ++++ .../furi_hal_include/furi_hal_bt_serial.h | 11 ++++ 5 files changed, 97 insertions(+), 4 deletions(-) diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index aeb2beec..c003013e 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -165,6 +165,11 @@ static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context ret = rpc_session_get_available_size(bt->rpc_session); } else if(event.event == SerialServiceEventTypeDataSent) { furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); + } else if(event.event == SerialServiceEventTypesBleResetRequest) { + FURI_LOG_I(TAG, "BLE restart request received"); + BtMessage message = {.type = BtMessageTypeSetProfile, .data.profile = BtProfileSerial}; + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); } return ret; } @@ -226,6 +231,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { rpc_session_set_context(bt->rpc_session, bt); furi_hal_bt_serial_set_event_callback( RPC_BUFFER_SIZE, bt_serial_event_callback, bt); + furi_hal_bt_serial_set_rpc_status(FuriHalBtSerialRpcStatusActive); } else { FURI_LOG_W(TAG, "RPC is busy, failed to open new session"); } @@ -241,6 +247,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { } else if(event.type == GapEventTypeDisconnected) { if(bt->profile == BtProfileSerial && bt->rpc_session) { FURI_LOG_I(TAG, "Close RPC connection"); + furi_hal_bt_serial_set_rpc_status(FuriHalBtSerialRpcStatusNotActive); furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); rpc_session_close(bt->rpc_session); furi_hal_bt_serial_set_event_callback(0, NULL, NULL); @@ -330,14 +337,20 @@ static void bt_change_profile(Bt* bt, BtMessage* message) { } furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt); bt->profile = message->data.profile; - *message->result = true; + if(message->result) { + *message->result = true; + } } else { FURI_LOG_E(TAG, "Failed to start Bt App"); - *message->result = false; + if(message->result) { + *message->result = false; + } } } else { bt_show_warning(bt, "Radio stack doesn't support this app"); - *message->result = false; + if(message->result) { + *message->result = false; + } } furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT); } diff --git a/firmware/targets/f7/ble_glue/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c index 536557cc..c6421dc2 100644 --- a/firmware/targets/f7/ble_glue/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -11,6 +11,7 @@ typedef struct { uint16_t rx_char_handle; uint16_t tx_char_handle; uint16_t flow_ctrl_char_handle; + uint16_t rpc_status_char_handle; FuriMutex* buff_size_mtx; uint32_t buff_size; uint16_t bytes_ready_to_receive; @@ -28,6 +29,8 @@ static const uint8_t char_rx_uuid[] = {0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; static const uint8_t flow_ctrl_uuid[] = {0x00, 0x00, 0xfe, 0x63, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; +static const uint8_t rpc_status_uuid[] = + {0x00, 0x00, 0xfe, 0x64, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; @@ -67,6 +70,17 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; + } else if(attribute_modified->Attr_Handle == serial_svc->rpc_status_char_handle + 1) { + SerialServiceRpcStatus* rpc_status = + (SerialServiceRpcStatus*)attribute_modified->Attr_Data; + if(*rpc_status == SerialServiceRpcStatusNotActive) { + if(serial_svc->callback) { + SerialServiceEvent event = { + .event = SerialServiceEventTypesBleResetRequest, + }; + serial_svc->callback(event, serial_svc->context); + } + } } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { FURI_LOG_T(TAG, "Ack received"); @@ -82,6 +96,18 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { return ret; } +static void serial_svc_update_rpc_char(SerialServiceRpcStatus status) { + tBleStatus ble_status = aci_gatt_update_char_value( + serial_svc->svc_handle, + serial_svc->rpc_status_char_handle, + 0, + sizeof(SerialServiceRpcStatus), + (uint8_t*)&status); + if(ble_status) { + FURI_LOG_E(TAG, "Failed to update RPC status char: %d", ble_status); + } +} + void serial_svc_start() { tBleStatus status; serial_svc = malloc(sizeof(SerialSvc)); @@ -90,7 +116,7 @@ void serial_svc_start() { // Add service status = aci_gatt_add_service( - UUID_TYPE_128, (Service_UUID_t*)service_uuid, PRIMARY_SERVICE, 10, &serial_svc->svc_handle); + UUID_TYPE_128, (Service_UUID_t*)service_uuid, PRIMARY_SERVICE, 12, &serial_svc->svc_handle); if(status) { FURI_LOG_E(TAG, "Failed to add Serial service: %d", status); } @@ -141,6 +167,22 @@ void serial_svc_start() { if(status) { FURI_LOG_E(TAG, "Failed to add Flow Control characteristic: %d", status); } + // Add RPC status characteristic + status = aci_gatt_add_char( + serial_svc->svc_handle, + UUID_TYPE_128, + (const Char_UUID_t*)rpc_status_uuid, + sizeof(SerialServiceRpcStatus), + CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &serial_svc->rpc_status_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add RPC status characteristic: %d", status); + } + serial_svc_update_rpc_char(SerialServiceRpcStatusNotActive); // Allocate buffer size mutex serial_svc->buff_size_mtx = furi_mutex_alloc(FuriMutexTypeNormal); } @@ -198,6 +240,10 @@ void serial_svc_stop() { if(status) { FURI_LOG_E(TAG, "Failed to delete Flow Control characteristic: %d", status); } + status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->rpc_status_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete RPC Status characteristic: %d", status); + } // Delete service status = aci_gatt_del_service(serial_svc->svc_handle); if(status) { @@ -242,3 +288,8 @@ bool serial_svc_update_tx(uint8_t* data, uint16_t data_len) { return true; } + +void serial_svc_set_rpc_status(SerialServiceRpcStatus status) { + furi_assert(serial_svc); + serial_svc_update_rpc_char(status); +} diff --git a/firmware/targets/f7/ble_glue/serial_service.h b/firmware/targets/f7/ble_glue/serial_service.h index a1e5bc1c..7d38066f 100644 --- a/firmware/targets/f7/ble_glue/serial_service.h +++ b/firmware/targets/f7/ble_glue/serial_service.h @@ -10,9 +10,15 @@ extern "C" { #endif +typedef enum { + SerialServiceRpcStatusNotActive = 0UL, + SerialServiceRpcStatusActive = 1UL, +} SerialServiceRpcStatus; + typedef enum { SerialServiceEventTypeDataReceived, SerialServiceEventTypeDataSent, + SerialServiceEventTypesBleResetRequest, } SerialServiceEventType; typedef struct { @@ -34,6 +40,8 @@ void serial_svc_set_callbacks( SerialServiceEventCallback callback, void* context); +void serial_svc_set_rpc_status(SerialServiceRpcStatus status); + void serial_svc_notify_buffer_is_empty(); void serial_svc_stop(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c index 9bdad5bf..aa09dde5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c @@ -31,6 +31,16 @@ void furi_hal_bt_serial_notify_buffer_is_empty() { serial_svc_notify_buffer_is_empty(); } +void furi_hal_bt_serial_set_rpc_status(FuriHalBtSerialRpcStatus status) { + SerialServiceRpcStatus st; + if(status == FuriHalBtSerialRpcStatusActive) { + st = SerialServiceRpcStatusActive; + } else { + st = SerialServiceRpcStatusNotActive; + } + serial_svc_set_rpc_status(st); +} + bool furi_hal_bt_serial_tx(uint8_t* data, uint16_t size) { if(size > FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX) { return false; diff --git a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h index e1b7af22..1b6e79ab 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h @@ -8,6 +8,11 @@ extern "C" { #define FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX SERIAL_SVC_DATA_LEN_MAX +typedef enum { + FuriHalBtSerialRpcStatusNotActive, + FuriHalBtSerialRpcStatusActive, +} FuriHalBtSerialRpcStatus; + /** Serial service callback type */ typedef SerialServiceEventCallback FuriHalBtSerialCallback; @@ -30,6 +35,12 @@ void furi_hal_bt_serial_set_event_callback( FuriHalBtSerialCallback callback, void* context); +/** Set BLE RPC status + * + * @param status FuriHalBtSerialRpcStatus instance + */ +void furi_hal_bt_serial_set_rpc_status(FuriHalBtSerialRpcStatus status); + /** Notify that application buffer is empty */ void furi_hal_bt_serial_notify_buffer_is_empty(); From f81999ea4a0dff606e0a19c6e50f3459e2ec3689 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Fri, 14 Oct 2022 20:35:53 +0300 Subject: [PATCH 47/49] Fix number of dolphin_apps (#1874) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/services/dolphin/helpers/dolphin_deed.c | 6 ++---- applications/services/dolphin/helpers/dolphin_deed.h | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/applications/services/dolphin/helpers/dolphin_deed.c b/applications/services/dolphin/helpers/dolphin_deed.c index d3c40298..ce3e058b 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.c +++ b/applications/services/dolphin/helpers/dolphin_deed.c @@ -35,9 +35,9 @@ static const DolphinDeedWeight dolphin_deed_weights[] = { {2, DolphinAppIbutton}, // DolphinDeedIbuttonAdd {3, DolphinAppBadusb}, // DolphinDeedBadUsbPlayScript - {3, DolphinAppU2f}, // DolphinDeedU2fAuthorized + {3, DolphinAppPlugin}, // DolphinDeedU2fAuthorized - {1, DolphinAppGpio}, // DolphinDeedGpioUartBridge + {1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge {1, DolphinAppPlugin}, // DolphinDeedPluginStart {1, DolphinAppPlugin}, // DolphinDeedPluginGameStart @@ -51,8 +51,6 @@ static uint8_t dolphin_deed_limits[] = { 20, // DolphinAppIr 20, // DolphinAppIbutton 20, // DolphinAppBadusb - 20, // DolphinAppU2f - 20, // DolphinAppGpio 20, // DolphinAppPlugin }; diff --git a/applications/services/dolphin/helpers/dolphin_deed.h b/applications/services/dolphin/helpers/dolphin_deed.h index 969f0d5c..abe027d7 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.h +++ b/applications/services/dolphin/helpers/dolphin_deed.h @@ -13,8 +13,6 @@ typedef enum { DolphinAppIr, DolphinAppIbutton, DolphinAppBadusb, - DolphinAppU2f, - DolphinAppGpio, DolphinAppPlugin, DolphinAppMAX, } DolphinApp; @@ -55,7 +53,6 @@ typedef enum { DolphinDeedBadUsbPlayScript, DolphinDeedU2fAuthorized, - DolphinDeedGpioUartBridge, DolphinDeedPluginStart, From 865baed0bbcd30fc378f2e92eb00ebc20be8dcdd Mon Sep 17 00:00:00 2001 From: Kevin Kwok Date: Fri, 14 Oct 2022 11:07:23 -0700 Subject: [PATCH 48/49] Fix FileNotFoundError in ./fbt flash_usb (#1876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix FileNotFoundError in ./fbt flash_usb * scripts: update.py: proper fix for file naming Co-authored-by: あく Co-authored-by: hedger --- scripts/update.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/update.py b/scripts/update.py index 6be1dce0..3259c5b0 100755 --- a/scripts/update.py +++ b/scripts/update.py @@ -78,8 +78,12 @@ class Main(App): def generate(self): stage_basename = "updater.bin" # used to be basename(self.args.stage) - dfu_basename = "firmware.dfu" # used to be basename(self.args.dfu) - radiobin_basename = "radio.bin" # used to be basename(self.args.radiobin) + dfu_basename = ( + "firmware.dfu" if self.args.dfu else "" + ) # used to be basename(self.args.dfu) + radiobin_basename = ( + "radio.bin" if self.args.radiobin else "" + ) # used to be basename(self.args.radiobin) resources_basename = "" radio_version = 0 From f06930e4ae98bfad66c38f9bea5bb67601c64001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sat, 15 Oct 2022 03:23:06 +0900 Subject: [PATCH 49/49] Desktop: fix fap in settings (#1877) --- applications/main/fap_loader/application.fam | 1 + .../scenes/desktop_settings_scene_favorite.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/applications/main/fap_loader/application.fam b/applications/main/fap_loader/application.fam index bd0403e0..784ee950 100644 --- a/applications/main/fap_loader/application.fam +++ b/applications/main/fap_loader/application.fam @@ -3,6 +3,7 @@ App( name="Applications", apptype=FlipperAppType.APP, entry_point="fap_loader_app", + cdefines=["APP_FAP_LOADER"], requires=[ "gui", "storage", 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 07ba9925..bdd9589e 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -11,9 +11,16 @@ static bool favorite_fap_selector_item_callback( uint8_t** icon_ptr, FuriString* item_name) { UNUSED(context); +#ifdef APP_FAP_LOADER Storage* storage = furi_record_open(RECORD_STORAGE); bool success = fap_loader_load_name_and_icon(file_path, storage, icon_ptr, item_name); furi_record_close(RECORD_STORAGE); +#else + UNUSED(file_path); + UNUSED(icon_ptr); + UNUSED(item_name); + bool success = false; +#endif return success; }