From feb1b2f34942962d886683fd7fb1310c480f2a7f Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 5 Sep 2024 20:44:22 +0300 Subject: [PATCH 1/5] [FL-3882] Clean up of LFS traces (#3849) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updater, storage: removed mentions of LFS from public APIs; updated corresponding strings * rpc: updated include path Co-authored-by: あく --- applications/services/rpc/rpc_storage.c | 6 +++--- applications/services/storage/storage.h | 2 +- applications/system/updater/cli/updater_cli.c | 6 +++--- applications/system/updater/util/update_task.c | 14 +++++++------- applications/system/updater/util/update_task.h | 4 ++-- .../updater/util/update_task_worker_backup.c | 14 +++++++------- .../updater/util/update_task_worker_flasher.c | 2 +- documentation/OTA.md | 4 ++-- lib/update_util/{lfs_backup.c => int_backup.c} | 16 ++++++++-------- lib/update_util/int_backup.h | 18 ++++++++++++++++++ lib/update_util/lfs_backup.h | 18 ------------------ targets/f7/furi_hal/furi_hal_rtc.h | 3 ++- 12 files changed, 54 insertions(+), 53 deletions(-) rename lib/update_util/{lfs_backup.c => int_backup.c} (77%) create mode 100644 lib/update_util/int_backup.h delete mode 100644 lib/update_util/lfs_backup.h diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index 89991aa86c..aedcf8c943 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -656,7 +656,7 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi rpc_system_storage_reset_state(rpc_storage, session, true); - bool backup_ok = lfs_backup_create( + bool backup_ok = int_backup_create( rpc_storage->api, request->content.storage_backup_create_request.archive_path); rpc_send_and_release_empty( @@ -676,7 +676,7 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo rpc_system_storage_reset_state(rpc_storage, session, true); - bool backup_ok = lfs_backup_unpack( + bool backup_ok = int_backup_unpack( rpc_storage->api, request->content.storage_backup_restore_request.archive_path); rpc_send_and_release_empty( diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index 6dbeb0d36b..072db1305b 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -504,7 +504,7 @@ FS_Error storage_sd_info(Storage* storage, SDInfo* info); */ FS_Error storage_sd_status(Storage* storage); -/******************* Internal LFS Functions *******************/ +/************ Internal Storage Backup/Restore ************/ typedef void (*StorageNameConverter)(FuriString*); diff --git a/applications/system/updater/cli/updater_cli.c b/applications/system/updater/cli/updater_cli.c index 0b734c0f49..56a16bd9d3 100644 --- a/applications/system/updater/cli/updater_cli.c +++ b/applications/system/updater/cli/updater_cli.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include typedef void (*cmd_handler)(FuriString* args); @@ -35,7 +35,7 @@ static void updater_cli_install(FuriString* manifest_path) { 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, furi_string_get_cstr(args)); + bool success = int_backup_create(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } @@ -43,7 +43,7 @@ static void updater_cli_backup(FuriString* 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, furi_string_get_cstr(args)); + bool success = int_backup_unpack(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } diff --git a/applications/system/updater/util/update_task.c b/applications/system/updater/util/update_task.c index 8f051ff77a..cca488475e 100644 --- a/applications/system/updater/util/update_task.c +++ b/applications/system/updater/util/update_task.c @@ -22,8 +22,8 @@ static const char* update_task_stage_descr[] = { [UpdateTaskStageRadioInstall] = "Installing radio FW", [UpdateTaskStageRadioBusy] = "Core 2 busy", [UpdateTaskStageOBValidation] = "Validating opt. bytes", - [UpdateTaskStageLfsBackup] = "Backing up LFS", - [UpdateTaskStageLfsRestore] = "Restoring LFS", + [UpdateTaskStageIntBackup] = "Backing up configuration", + [UpdateTaskStageIntRestore] = "Restoring configuration", [UpdateTaskStageResourcesFileCleanup] = "Cleaning up files", [UpdateTaskStageResourcesDirCleanup] = "Cleaning up directories", [UpdateTaskStageResourcesFileUnpack] = "Extracting resources", @@ -82,7 +82,7 @@ static const struct { }, #ifndef FURI_RAM_EXEC { - .stage = UpdateTaskStageLfsBackup, + .stage = UpdateTaskStageIntBackup, .percent_min = 0, .percent_max = 100, .descr = "FS R/W error", @@ -193,10 +193,10 @@ static const struct { #endif #ifndef FURI_RAM_EXEC { - .stage = UpdateTaskStageLfsRestore, + .stage = UpdateTaskStageIntRestore, .percent_min = 0, .percent_max = 100, - .descr = "LFS I/O error", + .descr = "SD card I/O error", }, { .stage = UpdateTaskStageResourcesFileCleanup, @@ -245,7 +245,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { [UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0), [UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 45), - [UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5), + [UpdateTaskStageIntBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5), [UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15), [UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 25), @@ -259,7 +259,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { [UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100), [UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 20), - [UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5), + [UpdateTaskStageIntRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5), [UpdateTaskStageResourcesFileCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 100), [UpdateTaskStageResourcesDirCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 50), diff --git a/applications/system/updater/util/update_task.h b/applications/system/updater/util/update_task.h index 52bdfdbd23..c346c55fa4 100644 --- a/applications/system/updater/util/update_task.h +++ b/applications/system/updater/util/update_task.h @@ -16,7 +16,7 @@ typedef enum { UpdateTaskStageProgress = 0, UpdateTaskStageReadManifest, - UpdateTaskStageLfsBackup, + UpdateTaskStageIntBackup, UpdateTaskStageRadioImageValidate, UpdateTaskStageRadioErase, @@ -30,7 +30,7 @@ typedef enum { UpdateTaskStageFlashWrite, UpdateTaskStageFlashValidate, - UpdateTaskStageLfsRestore, + UpdateTaskStageIntRestore, UpdateTaskStageResourcesFileCleanup, UpdateTaskStageResourcesDirCleanup, UpdateTaskStageResourcesFileUnpack, diff --git a/applications/system/updater/util/update_task_worker_backup.c b/applications/system/updater/util/update_task_worker_backup.c index 8d5039a16d..1b5bea25b3 100644 --- a/applications/system/updater/util/update_task_worker_backup.c +++ b/applications/system/updater/util/update_task_worker_backup.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -21,14 +21,14 @@ static bool update_task_pre_update(UpdateTask* update_task) { backup_file_path = furi_string_alloc(); path_concat( furi_string_get_cstr(update_task->update_path), - LFS_BACKUP_DEFAULT_FILENAME, + INT_BACKUP_DEFAULT_FILENAME, backup_file_path); - update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); + update_task_set_progress(update_task, UpdateTaskStageIntBackup, 0); /* to avoid bootloops */ furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); if((success = - lfs_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { + int_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate); } @@ -145,12 +145,12 @@ static bool update_task_post_update(UpdateTask* update_task) { do { path_concat( furi_string_get_cstr(update_task->update_path), - LFS_BACKUP_DEFAULT_FILENAME, + INT_BACKUP_DEFAULT_FILENAME, file_path); - update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); + update_task_set_progress(update_task, UpdateTaskStageIntRestore, 0); - CHECK_RESULT(lfs_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); + CHECK_RESULT(int_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); if(update_task->state.groups & UpdateTaskStageGroupResources) { TarUnpackProgress progress = { diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index e7e1bbbedc..a464815f0e 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -341,7 +341,7 @@ int32_t update_task_worker_flash_writer(void* context) { } furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate); - // Format LFS before restoring backup on next boot + // Clean up /int before restoring backup on next boot furi_hal_rtc_set_flag(FuriHalRtcFlagStorageFormatInternal); #ifdef FURI_NDEBUG // Production diff --git a/documentation/OTA.md b/documentation/OTA.md index 0456eab1f9..9783a70477 100644 --- a/documentation/OTA.md +++ b/documentation/OTA.md @@ -83,7 +83,7 @@ Even if something goes wrong, updater allows you to retry failed operations and | | | **50** | Package has mismatching HW target | | | | **60** | Missing DFU file | | | | **80** | Missing radio firmware file | -| Backing up LFS | **2** | **0-100** | FS read/write error | +| Backing up configuration| **2** | **0-100** | FS read/write error | | Checking radio FW | **3** | **0-99** | Error reading radio firmware file | | | | **100** | CRC mismatch | | Uninstalling radio FW | **4** | **0** | SHCI Delete command error | @@ -101,7 +101,7 @@ Even if something goes wrong, updater allows you to retry failed operations and | | | **99-100** | Corrupted DFU file | | Writing flash | **10** | **0-100** | Block read/write error | | Validating flash | **11** | **0-100** | Block read/write error | -| Restoring LFS | **12** | **0-100** | FS read/write error | +| Restoring configuration | **12** | **0-100** | FS read/write error | | Updating resources | **13-15** | **0-100** | SD card read/write error | ## Building update packages diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/int_backup.c similarity index 77% rename from lib/update_util/lfs_backup.c rename to lib/update_util/int_backup.c index 7786524ef6..a904db247f 100644 --- a/lib/update_util/lfs_backup.c +++ b/lib/update_util/int_backup.c @@ -1,4 +1,4 @@ -#include "lfs_backup.h" +#include "int_backup.h" #include @@ -9,7 +9,7 @@ #include #include -#define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME) +#define INT_BACKUP_DEFAULT_LOCATION EXT_PATH(INT_BACKUP_DEFAULT_FILENAME) static void backup_name_converter(FuriString* filename) { if(furi_string_empty(filename) || (furi_string_get_char(filename, 0) == '.')) { @@ -34,18 +34,18 @@ static void backup_name_converter(FuriString* filename) { } } -bool lfs_backup_create(Storage* storage, const char* destination) { +bool int_backup_create(Storage* storage, const char* destination) { const char* final_destination = - destination && strlen(destination) ? destination : LFS_BACKUP_DEFAULT_LOCATION; + destination && strlen(destination) ? destination : INT_BACKUP_DEFAULT_LOCATION; return storage_int_backup(storage, final_destination) == FSE_OK; } -bool lfs_backup_exists(Storage* storage, const char* source) { - const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; +bool int_backup_exists(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION; return storage_common_stat(storage, final_source, NULL) == FSE_OK; } -bool lfs_backup_unpack(Storage* storage, const char* source) { - const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; +bool int_backup_unpack(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION; return storage_int_restore(storage, final_source, backup_name_converter) == FSE_OK; } diff --git a/lib/update_util/int_backup.h b/lib/update_util/int_backup.h new file mode 100644 index 0000000000..168efda504 --- /dev/null +++ b/lib/update_util/int_backup.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#define INT_BACKUP_DEFAULT_FILENAME "backup.tar" + +#ifdef __cplusplus +extern "C" { +#endif + +bool int_backup_create(Storage* storage, const char* destination); +bool int_backup_exists(Storage* storage, const char* source); +bool int_backup_unpack(Storage* storage, const char* source); + +#ifdef __cplusplus +} +#endif diff --git a/lib/update_util/lfs_backup.h b/lib/update_util/lfs_backup.h deleted file mode 100644 index 5a7738c86e..0000000000 --- a/lib/update_util/lfs_backup.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -#define LFS_BACKUP_DEFAULT_FILENAME "backup.tar" - -#ifdef __cplusplus -extern "C" { -#endif - -bool lfs_backup_create(Storage* storage, const char* destination); -bool lfs_backup_exists(Storage* storage, const char* source); -bool lfs_backup_unpack(Storage* storage, const char* source); - -#ifdef __cplusplus -} -#endif diff --git a/targets/f7/furi_hal/furi_hal_rtc.h b/targets/f7/furi_hal/furi_hal_rtc.h index 030b464cf7..c5eab12ec5 100644 --- a/targets/f7/furi_hal/furi_hal_rtc.h +++ b/targets/f7/furi_hal/furi_hal_rtc.h @@ -9,6 +9,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -44,7 +45,7 @@ typedef enum { FuriHalRtcRegisterHeader, /**< RTC structure header */ FuriHalRtcRegisterSystem, /**< Various system bits */ FuriHalRtcRegisterVersion, /**< Pointer to Version */ - FuriHalRtcRegisterLfsFingerprint, /**< LFS geometry fingerprint */ + FuriHalRtcRegisterLfsFingerprint FURI_DEPRECATED, /**< LFS geometry fingerprint */ FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */ FuriHalRtcRegisterPinFails, /**< Failed PINs count */ /* Index of FS directory entry corresponding to FW update to be applied */ From 62bbf406be28bd5855a0a160e73e001f40c1d8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 6 Sep 2024 03:55:43 +0900 Subject: [PATCH 2/5] Debug: use proper hook for handle_exit in flipperapps (#3842) * Debug: use proper hook for handle_exit in flipperapps * fbt: flash firmware for `blackmagic` target Co-authored-by: hedger Co-authored-by: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> --- SConstruct | 3 ++- scripts/debug/flipperapps.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SConstruct b/SConstruct index b4c8d7b290..1279679688 100644 --- a/SConstruct +++ b/SConstruct @@ -234,7 +234,7 @@ firmware_debug = distenv.PhonyTarget( ) distenv.Depends(firmware_debug, firmware_flash) -distenv.PhonyTarget( +firmware_blackmagic = distenv.PhonyTarget( "blackmagic", "${GDBPYCOM}", source=firmware_env["FW_ELF"], @@ -242,6 +242,7 @@ distenv.PhonyTarget( GDBREMOTE="${BLACKMAGIC_ADDR}", FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) +distenv.Depends(firmware_blackmagic, firmware_flash) # Debug alien elf debug_other_opts = [ diff --git a/scripts/debug/flipperapps.py b/scripts/debug/flipperapps.py index 6dba89a564..81aa43c34c 100644 --- a/scripts/debug/flipperapps.py +++ b/scripts/debug/flipperapps.py @@ -124,7 +124,7 @@ def invoke(self, arg, from_tty): print(f"Set '{arg}' as debug info lookup path for Flipper external apps") helper.attach_to_fw() gdb.events.stop.connect(helper.handle_stop) - gdb.events.exited.connect(helper.handle_exit) + gdb.events.gdb_exiting.connect(helper.handle_exit) except gdb.error as e: print(f"Support for Flipper external apps debug is not available: {e}") From 49e1ae6e875d46c4f54c635895092abd682836dc Mon Sep 17 00:00:00 2001 From: RebornedBrain <138568282+RebornedBrain@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:54:49 +0300 Subject: [PATCH 3/5] [FL-3895] Broken file interaction fixes (#3852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Show error screen if corrupted filed has been loaded * Added rpc error codes and error processing to NFC * Made iButton scene on_enter handler clear to prevent showing scene before file is loaded * Added rpc error codes and error processing to iButton * Made lfRfid scene on_enter handler clear to prevent showing scene before file is loaded * Added rpc error codes and error processing to lfRfid * Made SubGHz scene on_enter handler clear to prevent showing scene before file is loaded. Also moved file_name_tmp formatting logic to a separate function * Now function returns loading status and starts rx only if load succeeded * Added show error logic on tx_button start * Introduced rpc error codes for infrared * Adjusted rpc scene logic to show scene only when loading is fine * Added new list of rpc errors which are common within several applications * Removed same enums from apps * Same rpc error in different apps replaced with common value from rpc error code list * SubGHz error codes now start from RpcAppSystemErrorCodesReserved value * Infrared error codes now start from RpcAppSystemErrorCodesReserved value * Removed unused enum * Now all rpc error codes are more generalized and can be used among all apps without any specific enums * Removed specific error codes, now rpc error codes are used instead * RPC: no plurals in enums Co-authored-by: あく --- .../main/ibutton/scenes/ibutton_scene_rpc.c | 24 +++++----- applications/main/infrared/infrared_app.c | 12 +++-- applications/main/infrared/infrared_app_i.h | 2 +- .../infrared/scenes/infrared_scene_remote.c | 7 ++- .../main/infrared/scenes/infrared_scene_rpc.c | 45 ++++++++++++------- .../main/lfrfid/scenes/lfrfid_scene_rpc.c | 30 +++++++------ .../protocol_support/nfc_protocol_support.c | 4 ++ applications/main/nfc/nfc_app.c | 2 +- .../main/subghz/helpers/subghz_error_type.h | 14 ------ .../main/subghz/scenes/subghz_scene_rpc.c | 41 ++++++++--------- applications/main/subghz/subghz_i.h | 1 - applications/services/rpc/rpc_app.h | 1 + .../services/rpc/rpc_app_error_codes.h | 11 +++++ 13 files changed, 106 insertions(+), 88 deletions(-) delete mode 100644 applications/main/subghz/helpers/subghz_error_type.h create mode 100644 applications/services/rpc/rpc_app_error_codes.h diff --git a/applications/main/ibutton/scenes/ibutton_scene_rpc.c b/applications/main/ibutton/scenes/ibutton_scene_rpc.c index f4f193a47e..87f51f2d8b 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/main/ibutton/scenes/ibutton_scene_rpc.c @@ -1,22 +1,26 @@ #include "../ibutton_i.h" void ibutton_scene_rpc_on_enter(void* context) { - iButton* ibutton = context; + UNUSED(context); +} + +static void ibutton_rpc_start_emulation(iButton* ibutton) { Popup* popup = ibutton->popup; popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); - + popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop); popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_worker_emulate_start(ibutton->worker, ibutton->key); + + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); notification_message(ibutton->notifications, &sequence_display_backlight_on); } bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { iButton* ibutton = context; - Popup* popup = ibutton->popup; bool consumed = false; @@ -27,17 +31,13 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(ibutton_load_key(ibutton, false)) { - popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - - ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); - ibutton_worker_emulate_start(ibutton->worker, ibutton->key); - + ibutton_rpc_start_emulation(ibutton); result = true; + } else { + rpc_system_app_set_error_code(ibutton->rpc, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(ibutton->rpc, "Cannot load key file"); } - rpc_system_app_confirm(ibutton->rpc, result); - } else if(event.event == iButtonCustomEventRpcExit) { rpc_system_app_confirm(ibutton->rpc, true); scene_manager_stop(ibutton->scene_manager); diff --git a/applications/main/infrared/infrared_app.c b/applications/main/infrared/infrared_app.c index 75c874e73b..4ddf0776bf 100644 --- a/applications/main/infrared/infrared_app.c +++ b/applications/main/infrared/infrared_app.c @@ -382,17 +382,15 @@ void infrared_tx_start(InfraredApp* infrared) { infrared->app_state.is_transmitting = true; } -void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) { +bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) { furi_assert(button_index < infrared_remote_get_signal_count(infrared->remote)); - if(infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index)) { + bool result = + infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index); + if(result) { infrared_tx_start(infrared); - } else { - infrared_show_error_message( - infrared, - "Failed to load\n\"%s\"", - infrared_remote_get_signal_name(infrared->remote, button_index)); } + return result; } void infrared_tx_stop(InfraredApp* infrared) { diff --git a/applications/main/infrared/infrared_app_i.h b/applications/main/infrared/infrared_app_i.h index 75d4e230d2..002a8c2ee8 100644 --- a/applications/main/infrared/infrared_app_i.h +++ b/applications/main/infrared/infrared_app_i.h @@ -208,7 +208,7 @@ void infrared_tx_start(InfraredApp* infrared); * @param[in] button_index index of the signal to be loaded. * @returns true if the signal could be loaded, false otherwise. */ -void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index); +bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index); /** * @brief Stop transmission of the currently loaded signal. diff --git a/applications/main/infrared/scenes/infrared_scene_remote.c b/applications/main/infrared/scenes/infrared_scene_remote.c index 6c1d1ec4e3..e1195c5163 100644 --- a/applications/main/infrared/scenes/infrared_scene_remote.c +++ b/applications/main/infrared/scenes/infrared_scene_remote.c @@ -85,7 +85,12 @@ bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) { if(custom_type == InfraredCustomEventTypeTransmitStarted) { furi_assert(button_index >= 0); - infrared_tx_start_button_index(infrared, button_index); + if(!infrared_tx_start_button_index(infrared, button_index)) { + infrared_show_error_message( + infrared, + "Failed to load\n\"%s\"", + infrared_remote_get_signal_name(infrared->remote, button_index)); + } consumed = true; } else if(custom_type == InfraredCustomEventTypeTransmitStopped) { infrared_tx_stop(infrared); diff --git a/applications/main/infrared/scenes/infrared_scene_rpc.c b/applications/main/infrared/scenes/infrared_scene_rpc.c index 4c263a1175..1672476685 100644 --- a/applications/main/infrared/scenes/infrared_scene_rpc.c +++ b/applications/main/infrared/scenes/infrared_scene_rpc.c @@ -20,18 +20,24 @@ static int32_t infrared_scene_rpc_task_callback(void* context) { void infrared_scene_rpc_on_enter(void* context) { InfraredApp* infrared = context; + scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle); +} + +static void infrared_scene_rpc_show(InfraredApp* infrared) { Popup* popup = infrared->popup; popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); + popup_set_text(popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop); popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); - popup_set_context(popup, context); + popup_set_context(popup, infrared); popup_set_callback(popup, infrared_popup_closed_callback); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); - scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle); + scene_manager_set_scene_state( + infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending); notification_message(infrared->notifications, &sequence_display_backlight_on); } @@ -52,24 +58,20 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { } else if(event.event == InfraredCustomEventTypeTaskFinished) { const bool task_success = infrared_blocking_task_finalize(infrared); - if(task_success) { - const char* remote_name = infrared_remote_get_name(infrared->remote); - infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name); scene_manager_set_scene_state( infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded); - } else { - infrared_text_store_set( - infrared, 0, "failed to load\n%s", furi_string_get_cstr(infrared->file_path)); - } + FuriString* str = furi_string_alloc(); + furi_string_printf( + str, "Failed to load\n%s", furi_string_get_cstr(infrared->file_path)); - popup_set_text( - infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); + rpc_system_app_set_error_code(infrared->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(infrared->rpc_ctx, furi_string_get_cstr(str)); + furi_string_free(str); + } rpc_system_app_confirm(infrared->rpc_ctx, task_success); - } else if( event.event == InfraredCustomEventTypeRpcButtonPressName || event.event == InfraredCustomEventTypeRpcButtonPressIndex) { @@ -88,10 +90,19 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { TAG, "Sending signal with index \"%ld\"", app_state->current_button_index); } if(infrared->app_state.current_button_index != InfraredButtonIndexNone) { - infrared_tx_start_button_index(infrared, app_state->current_button_index); - scene_manager_set_scene_state( - infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending); - result = true; + if(infrared_tx_start_button_index(infrared, app_state->current_button_index)) { + const char* remote_name = infrared_remote_get_name(infrared->remote); + infrared_text_store_set(infrared, 0, "emulating\n%s", remote_name); + + infrared_scene_rpc_show(infrared); + result = true; + } else { + rpc_system_app_set_error_code( + infrared->rpc_ctx, RpcAppSystemErrorCodeInternalParse); + rpc_system_app_set_error_text( + infrared->rpc_ctx, "Cannot load button data"); + result = false; + } } } rpc_system_app_confirm(infrared->rpc_ctx, result); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c index 906218d74f..65ffa1ef65 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c @@ -2,23 +2,30 @@ void lfrfid_scene_rpc_on_enter(void* context) { LfRfid* app = context; + app->rpc_state = LfRfidRpcStateIdle; +} + +static void lfrfid_rpc_start_emulation(LfRfid* app) { Popup* popup = app->popup; + lfrfid_text_store_set(app, "emulating\n%s", furi_string_get_cstr(app->file_name)); + popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); + popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - notification_message(app->notifications, &sequence_display_backlight_on); + lfrfid_worker_start_thread(app->lfworker); + lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); - app->rpc_state = LfRfidRpcStateIdle; + notification_message(app->notifications, &sequence_display_backlight_on); + notification_message(app->notifications, &sequence_blink_start_magenta); + app->rpc_state = LfRfidRpcStateEmulating; } bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { LfRfid* app = context; - Popup* popup = app->popup; - UNUSED(event); bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -34,16 +41,11 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(app->rpc_state == LfRfidRpcStateIdle) { 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", 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); + lfrfid_rpc_start_emulation(app); result = true; + } else { + rpc_system_app_set_error_code(app->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(app->rpc_ctx, "Cannot load key file"); } } rpc_system_app_confirm(app->rpc_ctx, result); diff --git a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c index 630b3beef6..7a07404fdc 100644 --- a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c +++ b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c @@ -717,6 +717,10 @@ static bool nfc_protocol_support_scene_rpc_on_event(NfcApp* instance, SceneManag if(nfc_load_file(instance, instance->file_path, false)) { nfc_protocol_support_scene_rpc_setup_ui_and_emulate(instance); success = true; + } else { + rpc_system_app_set_error_code( + instance->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(instance->rpc_ctx, "Cannot load key file"); } } rpc_system_app_confirm(instance->rpc_ctx, success); diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index bdf9c0e2f8..5365d6bef6 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -488,7 +488,7 @@ int32_t nfc_app(void* p) { nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); furi_string_set(nfc->file_path, args); - if(nfc_load_file(nfc, nfc->file_path, false)) { + if(nfc_load_file(nfc, nfc->file_path, true)) { nfc_show_initial_scene_for_device(nfc); } else { view_dispatcher_stop(nfc->view_dispatcher); diff --git a/applications/main/subghz/helpers/subghz_error_type.h b/applications/main/subghz/helpers/subghz_error_type.h deleted file mode 100644 index 0f86d6ea7d..0000000000 --- a/applications/main/subghz/helpers/subghz_error_type.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include - -/** SubGhzErrorType */ -typedef enum { - SubGhzErrorTypeNoError = 0, /** There are no errors */ - SubGhzErrorTypeParseFile = - 1, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */ - SubGhzErrorTypeOnlyRX = - 2, /** Transmission on this frequency is blocked by regional settings */ - SubGhzErrorTypeParserOthers = 3, /** Error in protocol parameters description */ -} SubGhzErrorType; diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 42ec98a396..c1476746d4 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -8,23 +8,33 @@ typedef enum { void subghz_scene_rpc_on_enter(void* context) { SubGhz* subghz = context; + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); +} + +static void subghz_format_file_name_tmp(SubGhz* subghz) { + 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", furi_string_get_cstr(file_name)); + furi_string_free(file_name); +} + +static void subghz_scene_rpc_emulation_show(SubGhz* subghz) { Popup* popup = subghz->popup; + subghz_format_file_name_tmp(subghz); popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); + popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); - notification_message(subghz->notifications, &sequence_display_backlight_on); } bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; - Popup* popup = subghz->popup; bool consumed = false; SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc); @@ -43,13 +53,15 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { switch( subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) { case SubGhzTxRxStartTxStateErrorOnlyRx: - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX); + rpc_system_app_set_error_code( + subghz->rpc_ctx, RpcAppSystemErrorCodeRegionLock); rpc_system_app_set_error_text( subghz->rpc_ctx, "Transmission on this frequency is restricted in your region"); break; case SubGhzTxRxStartTxStateErrorParserOthers: - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParserOthers); + rpc_system_app_set_error_code( + subghz->rpc_ctx, RpcAppSystemErrorCodeInternalParse); rpc_system_app_set_error_text( subghz->rpc_ctx, "Error in protocol parameters description"); break; @@ -77,23 +89,12 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(state == SubGhzRpcStateIdle) { if(subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), false)) { + subghz_scene_rpc_emulation_show(subghz); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded); result = true; - 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", - furi_string_get_cstr(file_name)); - popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); - - furi_string_free(file_name); } else { - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParseFile); + rpc_system_app_set_error_code(subghz->rpc_ctx, RpcAppSystemErrorCodeParseFile); rpc_system_app_set_error_text(subghz->rpc_ctx, "Cannot parse file"); } } diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 9e58f3947d..08687a4f79 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -1,7 +1,6 @@ #pragma once #include "helpers/subghz_types.h" -#include "helpers/subghz_error_type.h" #include #include "subghz.h" #include "views/receiver.h" diff --git a/applications/services/rpc/rpc_app.h b/applications/services/rpc/rpc_app.h index 4ee5a24d37..aa6fd81cc8 100644 --- a/applications/services/rpc/rpc_app.h +++ b/applications/services/rpc/rpc_app.h @@ -13,6 +13,7 @@ #pragma once #include "rpc.h" +#include "rpc_app_error_codes.h" #ifdef __cplusplus extern "C" { diff --git a/applications/services/rpc/rpc_app_error_codes.h b/applications/services/rpc/rpc_app_error_codes.h new file mode 100644 index 0000000000..fc0edd4d2d --- /dev/null +++ b/applications/services/rpc/rpc_app_error_codes.h @@ -0,0 +1,11 @@ +#pragma once + +/** + * @brief Enumeration of possible error codes for application which can be started through rpc + */ +typedef enum { + RpcAppSystemErrorCodeNone, /** There are no errors */ + RpcAppSystemErrorCodeParseFile, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */ + RpcAppSystemErrorCodeRegionLock, /** Requested function is blocked by regional settings */ + RpcAppSystemErrorCodeInternalParse, /** Error in protocol parameters description, or some data in opened file are unsupported */ +} RpcAppSystemErrorCode; From 20aff7320f1b2fc248b0d1e3e42eb155c1b24884 Mon Sep 17 00:00:00 2001 From: Valera Olexienko Date: Thu, 5 Sep 2024 22:14:57 +0200 Subject: [PATCH 4/5] Infrared: Add Airwell AW-HKD012-N91 (#3856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../infrared/resources/infrared/assets/ac.ir | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/applications/main/infrared/resources/infrared/assets/ac.ir b/applications/main/infrared/resources/infrared/assets/ac.ir index 68abaf2592..df958ffba2 100644 --- a/applications/main/infrared/resources/infrared/assets/ac.ir +++ b/applications/main/infrared/resources/infrared/assets/ac.ir @@ -858,3 +858,41 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 4348 4439 520 1646 520 1646 520 1646 519 1646 520 561 520 561 520 1646 519 561 520 561 520 562 519 562 519 561 520 1646 520 1647 518 563 518 1646 519 562 519 561 520 561 520 562 519 562 519 561 520 1648 517 1647 519 1646 519 1647 519 1646 520 1646 520 1645 520 1647 519 561 520 561 520 562 519 562 519 562 519 562 519 561 520 562 519 561 520 1646 520 562 519 1647 518 1646 520 562 519 560 521 561 520 561 520 561 520 562 519 562 519 560 521 562 519 562 519 560 521 1646 520 1646 520 561 520 562 519 561 520 562 519 561 520 561 520 561 520 561 520 561 520 1647 518 1646 520 562 519 562 519 561 520 1646 520 561 520 5409 4348 4440 519 1645 521 1646 519 1645 521 1645 521 561 520 561 520 1644 522 561 520 561 520 561 520 560 521 562 519 1646 520 1646 520 562 519 1644 522 561 520 561 520 561 520 561 520 561 520 561 520 1646 520 1645 520 1646 520 1645 521 1646 520 1646 520 1644 522 1645 521 560 521 560 521 561 520 561 520 560 521 560 521 561 520 561 520 561 520 1645 521 562 519 1645 521 1645 520 561 520 562 519 561 520 561 520 561 520 560 521 560 521 560 521 560 521 561 520 560 521 1646 520 1646 520 561 520 560 521 559 522 560 521 561 520 561 520 560 521 560 521 560 521 1646 520 1645 520 561 520 560 521 560 521 1645 521 561 520 +# +# Model: Airwell AW-HKD012-N91 +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4387 4398 547 1609 547 530 547 1610 547 1611 545 530 547 530 547 1608 547 530 548 530 547 1611 545 532 546 532 547 1609 547 1610 547 531 547 1608 548 530 547 530 548 530 547 1610 546 1609 547 1610 547 1609 547 1609 547 1611 545 1609 548 1610 546 530 547 530 548 529 549 531 547 531 546 531 547 1608 548 1610 547 1608 548 533 545 1608 548 532 546 532 546 1611 545 532 547 532 545 530 548 1608 547 530 549 1608 547 1609 548 5203 4386 4398 547 1609 546 530 547 1609 546 1607 548 531 547 531 547 1609 547 530 548 531 547 1609 547 531 547 531 547 1608 547 1613 544 531 546 1609 547 531 547 531 547 532 546 1609 547 1609 546 1609 547 1609 547 1608 547 1608 548 1608 548 1609 547 530 547 530 547 530 547 532 546 530 547 530 548 1610 546 1608 547 1609 547 530 547 1609 547 530 547 530 548 1609 546 530 548 530 547 532 546 1610 546 531 546 1608 548 1608 548 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4398 547 1608 548 531 546 1610 546 1609 547 530 547 529 548 1608 548 532 547 530 548 1612 544 529 549 530 548 1608 547 1609 547 531 546 1608 548 1607 549 529 549 1608 549 1609 548 1608 548 1608 548 1611 545 1608 548 530 548 1609 547 531 547 530 548 530 548 531 547 529 549 530 548 530 547 531 547 530 548 530 547 529 549 530 548 532 547 530 548 1609 547 1610 547 1608 548 1609 547 1608 548 1608 548 1608 548 1608 548 5203 4388 4396 549 1609 547 529 549 1610 546 1608 548 529 549 530 547 1609 547 530 548 529 549 1608 548 531 547 532 546 1609 547 1609 547 530 548 1609 548 1609 548 529 548 1608 548 1609 548 1609 547 1609 547 1608 548 1609 547 532 546 1608 548 531 548 531 548 530 548 530 548 531 547 530 548 531 548 531 547 530 548 530 548 530 548 531 547 529 549 529 549 1609 548 1608 548 1609 547 1608 548 1608 548 1608 548 1607 549 1607 549 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4384 4400 572 1585 571 505 572 1583 573 1584 572 508 570 503 575 1584 572 505 572 506 572 1583 573 504 573 506 571 1586 570 1585 572 532 546 1586 570 1585 571 506 571 1585 571 1583 573 1586 570 1583 573 1584 572 1589 569 505 572 1585 571 506 571 506 573 506 572 505 573 532 545 504 574 509 570 1611 545 506 572 1582 574 506 572 507 571 507 571 507 570 1584 572 507 571 1587 569 506 572 1584 572 1585 571 1583 573 1612 544 5179 4386 4400 570 1584 572 507 571 1583 572 1585 571 506 572 506 572 1584 572 505 572 504 574 1584 572 507 571 504 574 1583 573 1585 572 507 571 1584 572 1610 545 508 571 1587 569 1583 573 1583 573 1585 571 1585 572 1585 572 505 572 1584 572 505 573 507 572 506 571 504 574 505 573 505 574 508 571 1585 571 507 571 1585 571 506 571 506 572 504 574 505 572 1586 570 507 571 1586 570 505 573 1584 572 1585 571 1587 569 1584 573 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4386 4398 575 1582 574 503 575 1583 573 1582 574 505 573 504 574 1582 574 506 572 508 570 1583 573 504 574 505 573 1583 573 1584 573 505 573 1582 575 1583 574 504 574 1582 574 1583 573 1583 573 1583 573 1585 571 1586 572 504 573 1584 572 504 573 505 573 505 573 505 573 504 573 506 571 1583 574 505 573 1583 573 1583 573 1584 572 1583 573 505 572 505 573 504 574 1583 574 505 573 505 573 504 574 505 572 1584 572 1584 573 5178 4387 4400 571 1583 573 504 574 1584 572 1584 572 507 572 504 574 1582 574 505 572 505 573 1583 573 504 574 504 574 1582 574 1584 573 503 574 1583 573 1582 574 505 573 1583 573 1582 575 1583 573 1610 546 1584 572 1583 573 505 573 1610 546 506 572 505 573 504 574 504 574 505 573 505 573 1584 573 505 573 1582 574 1584 572 1583 573 1583 573 504 574 503 575 504 574 1585 571 507 571 504 573 506 572 505 572 1584 572 1585 571 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4399 547 1608 548 530 548 1610 547 1610 547 529 549 529 548 1608 548 530 548 530 548 1607 549 533 545 531 548 1608 548 1610 546 531 547 1609 547 1608 548 529 549 1609 547 1609 547 1609 547 1609 547 1609 547 1608 548 529 548 1638 519 530 548 530 548 530 548 529 550 528 549 530 548 530 548 1608 548 530 548 1609 548 1610 547 1609 547 531 546 529 549 1608 548 530 548 1609 548 530 548 529 548 530 548 1609 548 1609 548 5205 4387 4398 547 1609 548 531 546 1609 547 1609 547 530 548 531 546 1609 547 531 548 530 573 1583 573 507 571 506 572 1583 573 1582 574 504 574 1581 575 1582 574 506 572 1583 574 1583 573 1583 573 1585 571 1584 572 1585 570 507 571 1582 574 505 574 532 545 505 573 505 572 506 571 505 573 505 573 1584 572 506 572 1583 573 1584 572 1583 573 505 572 504 573 1583 573 505 573 1586 571 506 572 505 573 507 572 1583 573 1584 572 +# +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4399 572 1583 573 532 546 1585 571 1583 574 503 575 505 573 1584 572 504 574 505 573 1584 573 506 572 504 573 1584 573 1584 572 505 574 1611 545 506 573 1583 573 1585 571 1586 545 1609 547 531 547 1611 545 1608 548 1607 549 530 548 529 548 531 548 532 546 1610 546 533 545 530 547 1609 547 1610 547 1609 547 533 545 529 548 530 548 530 547 531 546 530 547 530 548 533 544 1608 548 1608 548 1610 546 1606 550 1609 547 5203 4388 4397 548 1609 547 531 547 1608 548 1608 548 530 548 530 548 1608 548 531 547 531 547 1610 546 531 547 530 548 1609 547 1611 546 532 547 1609 547 531 547 1608 548 1610 546 1609 547 1608 548 530 547 1609 547 1608 548 1609 547 531 546 530 548 530 547 530 547 1608 548 532 547 534 545 1608 548 1608 548 1609 547 530 548 531 547 531 547 532 546 531 546 531 547 532 546 530 548 1608 547 1608 548 1610 546 1608 548 1608 548 \ No newline at end of file From c6326915aeeaeb15a9b71620a3d2a1c8b51f2903 Mon Sep 17 00:00:00 2001 From: WillyJL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 5 Sep 2024 23:13:03 +0200 Subject: [PATCH 5/5] DialogEx: Fix NULL ptr crash (#3878) --- applications/services/gui/modules/dialog_ex.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/applications/services/gui/modules/dialog_ex.c b/applications/services/gui/modules/dialog_ex.c index 75209a4080..d27de12420 100644 --- a/applications/services/gui/modules/dialog_ex.c +++ b/applications/services/gui/modules/dialog_ex.c @@ -222,7 +222,7 @@ void dialog_ex_set_header( dialog_ex->view, DialogExModel * model, { - furi_string_set(model->header.text, text); + furi_string_set(model->header.text, text ? text : ""); model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; @@ -243,7 +243,7 @@ void dialog_ex_set_text( dialog_ex->view, DialogExModel * model, { - furi_string_set(model->text.text, text); + furi_string_set(model->text.text, text ? text : ""); model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; @@ -268,7 +268,10 @@ void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* i void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) { furi_check(dialog_ex); with_view_model( - dialog_ex->view, DialogExModel * model, { furi_string_set(model->left_text, text); }, true); + dialog_ex->view, + DialogExModel * model, + { furi_string_set(model->left_text, text ? text : ""); }, + true); } void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { @@ -276,7 +279,7 @@ void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { with_view_model( dialog_ex->view, DialogExModel * model, - { furi_string_set(model->center_text, text); }, + { furi_string_set(model->center_text, text ? text : ""); }, true); } @@ -285,7 +288,7 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { with_view_model( dialog_ex->view, DialogExModel * model, - { furi_string_set(model->right_text, text); }, + { furi_string_set(model->right_text, text ? text : ""); }, true); }