From 0f6f9ad52e6912b8b15cd3dcff7065ceb0fb3116 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 8 Sep 2022 19:40:33 +0300 Subject: [PATCH] [FL-2753] RFID app port to plain C (#1710) * LF RFID: port to plain C * LFRFID debug port to C, new reading screen * LFRFID debug: fix pvs-studio warnings * RFID read view: remove unused input callback * RFID read view: animation update --- applications/gui/modules/validators.c | 4 +- applications/lfrfid/lfrfid.c | 316 ++++++++++++++++++ applications/lfrfid/lfrfid_app.cpp | 218 ------------ applications/lfrfid/lfrfid_app.h | 137 -------- applications/lfrfid/lfrfid_app_launcher.cpp | 10 - applications/lfrfid/lfrfid_cli.c | 2 +- applications/lfrfid/lfrfid_i.h | 145 ++++++++ .../scene/lfrfid_app_scene_delete_confirm.cpp | 88 ----- .../scene/lfrfid_app_scene_delete_confirm.h | 16 - .../scene/lfrfid_app_scene_delete_success.cpp | 38 --- .../scene/lfrfid_app_scene_delete_success.h | 12 - .../lfrfid/scene/lfrfid_app_scene_emulate.cpp | 36 -- .../lfrfid/scene/lfrfid_app_scene_emulate.h | 9 - .../scene/lfrfid_app_scene_exit_confirm.cpp | 59 ---- .../scene/lfrfid_app_scene_exit_confirm.h | 13 - .../scene/lfrfid_app_scene_extra_actions.cpp | 63 ---- .../scene/lfrfid_app_scene_extra_actions.h | 13 - .../scene/lfrfid_app_scene_raw_info.cpp | 77 ----- .../lfrfid/scene/lfrfid_app_scene_raw_info.h | 12 - .../scene/lfrfid_app_scene_raw_name.cpp | 46 --- .../lfrfid/scene/lfrfid_app_scene_raw_name.h | 12 - .../scene/lfrfid_app_scene_raw_read.cpp | 107 ------ .../lfrfid/scene/lfrfid_app_scene_raw_read.h | 15 - .../scene/lfrfid_app_scene_raw_success.cpp | 45 --- .../scene/lfrfid_app_scene_raw_success.h | 13 - .../lfrfid/scene/lfrfid_app_scene_read.cpp | 100 ------ .../lfrfid/scene/lfrfid_app_scene_read.h | 9 - .../scene/lfrfid_app_scene_read_menu.cpp | 60 ---- .../lfrfid/scene/lfrfid_app_scene_read_menu.h | 13 - .../scene/lfrfid_app_scene_read_success.cpp | 96 ------ .../scene/lfrfid_app_scene_read_success.h | 16 - .../scene/lfrfid_app_scene_retry_confirm.cpp | 59 ---- .../scene/lfrfid_app_scene_retry_confirm.h | 13 - .../lfrfid/scene/lfrfid_app_scene_rpc.cpp | 66 ---- .../lfrfid/scene/lfrfid_app_scene_rpc.h | 12 - .../scene/lfrfid_app_scene_save_data.cpp | 45 --- .../lfrfid/scene/lfrfid_app_scene_save_data.h | 12 - .../scene/lfrfid_app_scene_save_name.cpp | 72 ---- .../lfrfid/scene/lfrfid_app_scene_save_name.h | 12 - .../scene/lfrfid_app_scene_save_success.cpp | 50 --- .../scene/lfrfid_app_scene_save_success.h | 12 - .../scene/lfrfid_app_scene_save_type.cpp | 53 --- .../lfrfid/scene/lfrfid_app_scene_save_type.h | 15 - .../scene/lfrfid_app_scene_saved_info.cpp | 48 --- .../scene/lfrfid_app_scene_saved_info.h | 12 - .../scene/lfrfid_app_scene_saved_key_menu.cpp | 67 ---- .../scene/lfrfid_app_scene_saved_key_menu.h | 13 - .../scene/lfrfid_app_scene_select_key.cpp | 16 - .../scene/lfrfid_app_scene_select_key.h | 9 - .../lfrfid/scene/lfrfid_app_scene_start.cpp | 67 ---- .../lfrfid/scene/lfrfid_app_scene_start.h | 13 - .../lfrfid/scene/lfrfid_app_scene_write.cpp | 88 ----- .../lfrfid/scene/lfrfid_app_scene_write.h | 9 - .../scene/lfrfid_app_scene_write_success.cpp | 38 --- .../scene/lfrfid_app_scene_write_success.h | 12 - applications/lfrfid/scenes/lfrfid_scene.c | 30 ++ applications/lfrfid/scenes/lfrfid_scene.h | 29 ++ .../lfrfid/scenes/lfrfid_scene_config.h | 24 ++ .../scenes/lfrfid_scene_delete_confirm.c | 68 ++++ .../scenes/lfrfid_scene_delete_success.c | 35 ++ .../lfrfid/scenes/lfrfid_scene_emulate.c | 44 +++ .../lfrfid/scenes/lfrfid_scene_exit_confirm.c | 39 +++ .../scenes/lfrfid_scene_extra_actions.c | 79 +++++ .../lfrfid/scenes/lfrfid_scene_raw_info.c | 64 ++++ .../lfrfid/scenes/lfrfid_scene_raw_name.c | 58 ++++ .../lfrfid/scenes/lfrfid_scene_raw_read.c | 126 +++++++ .../lfrfid/scenes/lfrfid_scene_raw_success.c | 39 +++ .../lfrfid/scenes/lfrfid_scene_read.c | 109 ++++++ .../scenes/lfrfid_scene_read_key_menu.c | 58 ++++ .../lfrfid/scenes/lfrfid_scene_read_success.c | 79 +++++ .../scenes/lfrfid_scene_retry_confirm.c | 39 +++ applications/lfrfid/scenes/lfrfid_scene_rpc.c | 67 ++++ .../lfrfid/scenes/lfrfid_scene_save_data.c | 51 +++ .../lfrfid/scenes/lfrfid_scene_save_name.c | 76 +++++ .../lfrfid/scenes/lfrfid_scene_save_success.c | 43 +++ .../lfrfid/scenes/lfrfid_scene_save_type.c | 86 +++++ .../lfrfid/scenes/lfrfid_scene_saved_info.c | 51 +++ .../scenes/lfrfid_scene_saved_key_menu.c | 69 ++++ .../lfrfid/scenes/lfrfid_scene_select_key.c | 22 ++ .../lfrfid/scenes/lfrfid_scene_start.c | 72 ++++ .../lfrfid/scenes/lfrfid_scene_write.c | 96 ++++++ .../scenes/lfrfid_scene_write_success.c | 38 +++ applications/lfrfid/view/container_vm.cpp | 115 ------- applications/lfrfid/view/container_vm.h | 17 - .../lfrfid/view/elements/button_element.cpp | 65 ---- .../lfrfid/view/elements/button_element.h | 28 -- .../lfrfid/view/elements/generic_element.cpp | 15 - .../lfrfid/view/elements/generic_element.h | 21 -- .../lfrfid/view/elements/icon_element.cpp | 25 -- .../lfrfid/view/elements/icon_element.h | 17 - .../lfrfid/view/elements/string_element.cpp | 47 --- .../lfrfid/view/elements/string_element.h | 28 -- applications/lfrfid/views/lfrfid_view_read.c | 117 +++++++ applications/lfrfid/views/lfrfid_view_read.h | 19 ++ applications/lfrfid_debug/lfrfid_debug.c | 81 +++++ .../lfrfid_debug/lfrfid_debug_app.cpp | 17 - applications/lfrfid_debug/lfrfid_debug_app.h | 40 --- .../lfrfid_debug_app_launcher.cpp | 11 - applications/lfrfid_debug/lfrfid_debug_i.h | 31 ++ .../scene/lfrfid_debug_app_scene_start.cpp | 47 --- .../scene/lfrfid_debug_app_scene_start.h | 13 - .../scene/lfrfid_debug_app_scene_tune.h | 9 - .../scenes/lfrfid_debug_app_scene_start.c | 44 +++ .../lfrfid_debug_app_scene_tune.c} | 28 +- .../lfrfid_debug/scenes/lfrfid_debug_scene.c | 30 ++ .../lfrfid_debug/scenes/lfrfid_debug_scene.h | 29 ++ .../scenes/lfrfid_debug_scene_config.h | 2 + .../view_modules/lfrfid_view_tune_vm.cpp | 214 ------------ .../view_modules/lfrfid_view_tune_vm.h | 26 -- .../views/lfrfid_debug_view_tune.c | 229 +++++++++++++ .../views/lfrfid_debug_view_tune.h | 18 + .../Common/Round_loader_8x8/frame_01.png | Bin 0 -> 7324 bytes .../Common/Round_loader_8x8/frame_02.png | Bin 0 -> 3606 bytes .../Common/Round_loader_8x8/frame_03.png | Bin 0 -> 3603 bytes .../Common/Round_loader_8x8/frame_04.png | Bin 0 -> 3605 bytes .../Common/Round_loader_8x8/frame_05.png | Bin 0 -> 3598 bytes .../icons/Common/Round_loader_8x8/frame_rate | 1 + 117 files changed, 2674 insertions(+), 2914 deletions(-) create mode 100644 applications/lfrfid/lfrfid.c delete mode 100644 applications/lfrfid/lfrfid_app.cpp delete mode 100644 applications/lfrfid/lfrfid_app.h delete mode 100644 applications/lfrfid/lfrfid_app_launcher.cpp create mode 100644 applications/lfrfid/lfrfid_i.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_delete_success.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_emulate.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_extra_actions.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_extra_actions.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_info.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_info.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_name.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_name.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_read.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_read.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_success.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_raw_success.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read_menu.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_read_success.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_rpc.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_data.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_data.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_name.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_success.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_type.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_save_type.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_saved_info.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_select_key.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_start.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_start.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_write.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_write.h delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp delete mode 100644 applications/lfrfid/scene/lfrfid_app_scene_write_success.h create mode 100644 applications/lfrfid/scenes/lfrfid_scene.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene.h create mode 100644 applications/lfrfid/scenes/lfrfid_scene_config.h create mode 100644 applications/lfrfid/scenes/lfrfid_scene_delete_confirm.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_delete_success.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_emulate.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_exit_confirm.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_extra_actions.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_raw_info.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_raw_name.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_raw_read.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_raw_success.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_read.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_read_key_menu.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_read_success.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_retry_confirm.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_rpc.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_save_data.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_save_name.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_save_success.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_save_type.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_saved_info.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_saved_key_menu.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_select_key.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_start.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_write.c create mode 100644 applications/lfrfid/scenes/lfrfid_scene_write_success.c delete mode 100644 applications/lfrfid/view/container_vm.cpp delete mode 100644 applications/lfrfid/view/container_vm.h delete mode 100644 applications/lfrfid/view/elements/button_element.cpp delete mode 100644 applications/lfrfid/view/elements/button_element.h delete mode 100644 applications/lfrfid/view/elements/generic_element.cpp delete mode 100644 applications/lfrfid/view/elements/generic_element.h delete mode 100644 applications/lfrfid/view/elements/icon_element.cpp delete mode 100644 applications/lfrfid/view/elements/icon_element.h delete mode 100644 applications/lfrfid/view/elements/string_element.cpp delete mode 100644 applications/lfrfid/view/elements/string_element.h create mode 100644 applications/lfrfid/views/lfrfid_view_read.c create mode 100644 applications/lfrfid/views/lfrfid_view_read.h create mode 100644 applications/lfrfid_debug/lfrfid_debug.c delete mode 100644 applications/lfrfid_debug/lfrfid_debug_app.cpp delete mode 100644 applications/lfrfid_debug/lfrfid_debug_app.h delete mode 100644 applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp create mode 100644 applications/lfrfid_debug/lfrfid_debug_i.h delete mode 100644 applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.cpp delete mode 100644 applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h delete mode 100644 applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h create mode 100644 applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c rename applications/lfrfid_debug/{scene/lfrfid_debug_app_scene_tune.cpp => scenes/lfrfid_debug_app_scene_tune.c} (53%) create mode 100644 applications/lfrfid_debug/scenes/lfrfid_debug_scene.c create mode 100644 applications/lfrfid_debug/scenes/lfrfid_debug_scene.h create mode 100644 applications/lfrfid_debug/scenes/lfrfid_debug_scene_config.h delete mode 100644 applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp delete mode 100644 applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.h create mode 100644 applications/lfrfid_debug/views/lfrfid_debug_view_tune.c create mode 100644 applications/lfrfid_debug/views/lfrfid_debug_view_tune.h create mode 100644 assets/icons/Common/Round_loader_8x8/frame_01.png create mode 100644 assets/icons/Common/Round_loader_8x8/frame_02.png create mode 100644 assets/icons/Common/Round_loader_8x8/frame_03.png create mode 100644 assets/icons/Common/Round_loader_8x8/frame_04.png create mode 100644 assets/icons/Common/Round_loader_8x8/frame_05.png create mode 100644 assets/icons/Common/Round_loader_8x8/frame_rate diff --git a/applications/gui/modules/validators.c b/applications/gui/modules/validators.c index ac293f8c..52f9946c 100644 --- a/applications/gui/modules/validators.c +++ b/applications/gui/modules/validators.c @@ -42,7 +42,9 @@ ValidatorIsFile* validator_is_file_alloc_init( instance->app_path_folder = strdup(app_path_folder); instance->app_extension = app_extension; - instance->current_name = strdup(current_name); + if(current_name != NULL) { + instance->current_name = strdup(current_name); + } return instance; } diff --git a/applications/lfrfid/lfrfid.c b/applications/lfrfid/lfrfid.c new file mode 100644 index 00000000..87332b1a --- /dev/null +++ b/applications/lfrfid/lfrfid.c @@ -0,0 +1,316 @@ +#include "lfrfid_i.h" + +static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + LfRfid* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool lfrfid_debug_back_event_callback(void* context) { + furi_assert(context); + LfRfid* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) { + furi_assert(context); + LfRfid* app = (LfRfid*)context; + + if(rpc_event == RpcAppEventSessionClose) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventRpcSessionClose); + // Detach RPC + rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); + app->rpc_ctx = NULL; + } else if(rpc_event == RpcAppEventAppExit) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventExit); + } else if(rpc_event == RpcAppEventLoadFile) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventRpcLoadFile); + } else { + rpc_system_app_confirm(app->rpc_ctx, rpc_event, false); + } +} + +static LfRfid* lfrfid_alloc() { + LfRfid* lfrfid = malloc(sizeof(LfRfid)); + + 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->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); + + size_t size = protocol_dict_get_max_data_size(lfrfid->dict); + lfrfid->new_key_data = (uint8_t*)malloc(size); + lfrfid->old_key_data = (uint8_t*)malloc(size); + + lfrfid->lfworker = lfrfid_worker_alloc(lfrfid->dict); + + lfrfid->view_dispatcher = view_dispatcher_alloc(); + lfrfid->scene_manager = scene_manager_alloc(&lfrfid_scene_handlers, lfrfid); + view_dispatcher_enable_queue(lfrfid->view_dispatcher); + view_dispatcher_set_event_callback_context(lfrfid->view_dispatcher, lfrfid); + view_dispatcher_set_custom_event_callback( + lfrfid->view_dispatcher, lfrfid_debug_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + lfrfid->view_dispatcher, lfrfid_debug_back_event_callback); + + // Open GUI record + lfrfid->gui = furi_record_open(RECORD_GUI); + + // Open Notification record + lfrfid->notifications = furi_record_open(RECORD_NOTIFICATION); + + // Submenu + lfrfid->submenu = submenu_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewSubmenu, submenu_get_view(lfrfid->submenu)); + + // Dialog + lfrfid->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewDialogEx, dialog_ex_get_view(lfrfid->dialog_ex)); + + // Popup + lfrfid->popup = popup_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewPopup, popup_get_view(lfrfid->popup)); + + // Widget + lfrfid->widget = widget_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewWidget, widget_get_view(lfrfid->widget)); + + // Text Input + lfrfid->text_input = text_input_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewTextInput, text_input_get_view(lfrfid->text_input)); + + // Byte Input + lfrfid->byte_input = byte_input_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewByteInput, byte_input_get_view(lfrfid->byte_input)); + + // Read custom view + lfrfid->read_view = lfrfid_view_read_alloc(); + view_dispatcher_add_view( + lfrfid->view_dispatcher, LfRfidViewRead, lfrfid_view_read_get_view(lfrfid->read_view)); + + return lfrfid; +} + +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); + protocol_dict_free(lfrfid->dict); + + lfrfid_worker_free(lfrfid->lfworker); + + if(lfrfid->rpc_ctx) { + rpc_system_app_set_callback(lfrfid->rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(lfrfid->rpc_ctx); + } + + free(lfrfid->new_key_data); + free(lfrfid->old_key_data); + + // Submenu + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewSubmenu); + submenu_free(lfrfid->submenu); + + // DialogEx + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewDialogEx); + dialog_ex_free(lfrfid->dialog_ex); + + // Popup + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewPopup); + popup_free(lfrfid->popup); + + // Widget + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewWidget); + widget_free(lfrfid->widget); + + // TextInput + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewTextInput); + text_input_free(lfrfid->text_input); + + // ByteInput + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewByteInput); + byte_input_free(lfrfid->byte_input); + + // Read custom view + view_dispatcher_remove_view(lfrfid->view_dispatcher, LfRfidViewRead); + lfrfid_view_read_free(lfrfid->read_view); + + // View Dispatcher + view_dispatcher_free(lfrfid->view_dispatcher); + + // Scene Manager + scene_manager_free(lfrfid->scene_manager); + + // GUI + furi_record_close(RECORD_GUI); + lfrfid->gui = NULL; + + // Notifications + furi_record_close(RECORD_NOTIFICATION); + lfrfid->notifications = NULL; + + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_DIALOGS); + + free(lfrfid); +} + +int32_t lfrfid_app(void* p) { + LfRfid* app = lfrfid_alloc(); + char* args = p; + + lfrfid_make_app_folder(app); + + if(args && strlen(args)) { + uint32_t rpc_ctx_ptr = 0; + if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { + app->rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; + rpc_system_app_set_callback(app->rpc_ctx, rpc_command_callback, app); + rpc_system_app_send_started(app->rpc_ctx); + view_dispatcher_attach_to_gui( + app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop); + scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc); + } else { + string_set_str(app->file_path, args); + lfrfid_load_key_data(app, app->file_path, true); + view_dispatcher_attach_to_gui( + app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); + } + + } else { + view_dispatcher_attach_to_gui( + app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + scene_manager_next_scene(app->scene_manager, LfRfidSceneStart); + } + + view_dispatcher_run(app->view_dispatcher); + + lfrfid_free(app); + + return 0; +} + +bool lfrfid_save_key(LfRfid* app) { + furi_assert(app); + + bool result = false; + + 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); + } + + string_cat_printf( + app->file_path, "/%s%s", string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); + + result = lfrfid_save_key_data(app, app->file_path); + return result; +} + +bool lfrfid_load_key_from_file_select(LfRfid* app) { + furi_assert(app); + + bool result = dialog_file_browser_show( + app->dialogs, + app->file_path, + app->file_path, + LFRFID_APP_EXTENSION, + true, + &I_125_10px, + true); + + if(result) { + result = lfrfid_load_key_data(app, app->file_path, true); + } + + return result; +} + +bool lfrfid_delete_key(LfRfid* app) { + furi_assert(app); + + return storage_simply_remove(app->storage, string_get_cstr(app->file_path)); +} + +bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) { + bool result = false; + + do { + app->protocol_id = lfrfid_dict_file_load(app->dict, string_get_cstr(path)); + if(app->protocol_id == PROTOCOL_NO) break; + + path_extract_filename(path, app->file_name, true); + result = true; + } while(0); + + if((!result) && (show_dialog)) { + dialog_message_show_storage_error(app->dialogs, "Cannot load\nkey file"); + } + + 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)); + + if(!result) { + dialog_message_show_storage_error(app->dialogs, "Cannot save\nkey file"); + } + + return result; +} + +void lfrfid_make_app_folder(LfRfid* app) { + furi_assert(app); + + if(!storage_simply_mkdir(app->storage, LFRFID_APP_FOLDER)) { + dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder"); + } +} + +void lfrfid_text_store_set(LfRfid* app, const char* text, ...) { + furi_assert(app); + va_list args; + va_start(args, text); + + vsnprintf(app->text_store, LFRFID_TEXT_STORE_SIZE, text, args); + + va_end(args); +} + +void lfrfid_text_store_clear(LfRfid* app) { + furi_assert(app); + memset(app->text_store, 0, sizeof(app->text_store)); +} + +void lfrfid_popup_timeout_callback(void* context) { + LfRfid* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventPopupClosed); +} + +void lfrfid_widget_callback(GuiButtonType result, InputType type, void* context) { + LfRfid* app = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(app->view_dispatcher, result); + } +} + +void lfrfid_text_input_callback(void* context) { + LfRfid* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventNext); +} \ No newline at end of file diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp deleted file mode 100644 index 9373ca8c..00000000 --- a/applications/lfrfid/lfrfid_app.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "lfrfid_app.h" -#include "assets_icons.h" -#include -#include "m-string.h" -#include "scene/lfrfid_app_scene_start.h" -#include "scene/lfrfid_app_scene_read.h" -#include "scene/lfrfid_app_scene_read_success.h" -#include "scene/lfrfid_app_scene_retry_confirm.h" -#include "scene/lfrfid_app_scene_exit_confirm.h" -#include "scene/lfrfid_app_scene_read_menu.h" -#include "scene/lfrfid_app_scene_write.h" -#include "scene/lfrfid_app_scene_write_success.h" -#include "scene/lfrfid_app_scene_emulate.h" -#include "scene/lfrfid_app_scene_save_name.h" -#include "scene/lfrfid_app_scene_save_success.h" -#include "scene/lfrfid_app_scene_select_key.h" -#include "scene/lfrfid_app_scene_saved_key_menu.h" -#include "scene/lfrfid_app_scene_save_data.h" -#include "scene/lfrfid_app_scene_save_type.h" -#include "scene/lfrfid_app_scene_saved_info.h" -#include "scene/lfrfid_app_scene_delete_confirm.h" -#include "scene/lfrfid_app_scene_delete_success.h" -#include "scene/lfrfid_app_scene_rpc.h" -#include "scene/lfrfid_app_scene_extra_actions.h" -#include "scene/lfrfid_app_scene_raw_info.h" -#include "scene/lfrfid_app_scene_raw_name.h" -#include "scene/lfrfid_app_scene_raw_read.h" -#include "scene/lfrfid_app_scene_raw_success.h" - -#include -#include - -#include - -const char* LfRfidApp::app_folder = ANY_PATH("lfrfid"); -const char* LfRfidApp::app_sd_folder = EXT_PATH("lfrfid"); -const char* LfRfidApp::app_extension = ".rfid"; -const char* LfRfidApp::app_filetype = "Flipper RFID key"; - -LfRfidApp::LfRfidApp() - : scene_controller{this} - , notification{RECORD_NOTIFICATION} - , storage{RECORD_STORAGE} - , dialogs{RECORD_DIALOGS} - , text_store(40) { - string_init(file_name); - string_init(raw_file_name); - string_init_set_str(file_path, app_folder); - - dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); - - size_t size = protocol_dict_get_max_data_size(dict); - new_key_data = (uint8_t*)malloc(size); - old_key_data = (uint8_t*)malloc(size); - - lfworker = lfrfid_worker_alloc(dict); -} - -LfRfidApp::~LfRfidApp() { - string_clear(raw_file_name); - string_clear(file_name); - string_clear(file_path); - protocol_dict_free(dict); - - lfrfid_worker_free(lfworker); - - if(rpc_ctx) { - rpc_system_app_set_callback(rpc_ctx, NULL, NULL); - rpc_system_app_send_exited(rpc_ctx); - } - - free(new_key_data); - free(old_key_data); -} - -static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) { - furi_assert(context); - LfRfidApp* app = static_cast(context); - - if(rpc_event == RpcAppEventSessionClose) { - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::RpcSessionClose; - app->view_controller.send_event(&event); - // Detach RPC - rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); - app->rpc_ctx = NULL; - } else if(rpc_event == RpcAppEventAppExit) { - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Exit; - app->view_controller.send_event(&event); - } else if(rpc_event == RpcAppEventLoadFile) { - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::RpcLoadFile; - app->view_controller.send_event(&event); - } else { - rpc_system_app_confirm(app->rpc_ctx, rpc_event, false); - } -} - -void LfRfidApp::run(void* _args) { - const char* args = reinterpret_cast(_args); - - make_app_folder(); - - if(args && strlen(args)) { - uint32_t rpc_ctx_ptr = 0; - if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { - rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; - rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this); - rpc_system_app_send_started(rpc_ctx); - view_controller.attach_to_gui(ViewDispatcherTypeDesktop); - scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc()); - scene_controller.process(100, SceneType::Rpc); - } else { - string_set_str(file_path, args); - load_key_data(file_path, true); - view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); - scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); - scene_controller.process(100, SceneType::Emulate); - } - - } else { - view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); - scene_controller.add_scene(SceneType::Start, new LfRfidAppSceneStart()); - scene_controller.add_scene(SceneType::Read, new LfRfidAppSceneRead()); - scene_controller.add_scene(SceneType::RetryConfirm, new LfRfidAppSceneRetryConfirm()); - scene_controller.add_scene(SceneType::ExitConfirm, new LfRfidAppSceneExitConfirm()); - scene_controller.add_scene(SceneType::ReadSuccess, new LfRfidAppSceneReadSuccess()); - scene_controller.add_scene(SceneType::ReadKeyMenu, new LfRfidAppSceneReadKeyMenu()); - scene_controller.add_scene(SceneType::Write, new LfRfidAppSceneWrite()); - scene_controller.add_scene(SceneType::WriteSuccess, new LfRfidAppSceneWriteSuccess()); - scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); - scene_controller.add_scene(SceneType::SaveName, new LfRfidAppSceneSaveName()); - scene_controller.add_scene(SceneType::SaveSuccess, new LfRfidAppSceneSaveSuccess()); - scene_controller.add_scene(SceneType::SelectKey, new LfRfidAppSceneSelectKey()); - scene_controller.add_scene(SceneType::SavedKeyMenu, new LfRfidAppSceneSavedKeyMenu()); - scene_controller.add_scene(SceneType::SaveData, new LfRfidAppSceneSaveData()); - scene_controller.add_scene(SceneType::SaveType, new LfRfidAppSceneSaveType()); - scene_controller.add_scene(SceneType::SavedInfo, new LfRfidAppSceneSavedInfo()); - scene_controller.add_scene(SceneType::DeleteConfirm, new LfRfidAppSceneDeleteConfirm()); - scene_controller.add_scene(SceneType::DeleteSuccess, new LfRfidAppSceneDeleteSuccess()); - scene_controller.add_scene(SceneType::ExtraActions, new LfRfidAppSceneExtraActions()); - scene_controller.add_scene(SceneType::RawInfo, new LfRfidAppSceneRawInfo()); - scene_controller.add_scene(SceneType::RawName, new LfRfidAppSceneRawName()); - scene_controller.add_scene(SceneType::RawRead, new LfRfidAppSceneRawRead()); - scene_controller.add_scene(SceneType::RawSuccess, new LfRfidAppSceneRawSuccess()); - scene_controller.process(100); - } -} - -bool LfRfidApp::save_key() { - bool result = false; - - make_app_folder(); - - if(string_end_with_str_p(file_path, app_extension)) { - size_t filename_start = string_search_rchar(file_path, '/'); - string_left(file_path, filename_start); - } - - string_cat_printf(file_path, "/%s%s", string_get_cstr(file_name), app_extension); - - result = save_key_data(file_path); - return result; -} - -bool LfRfidApp::load_key_from_file_select(bool need_restore) { - if(!need_restore) { - string_set_str(file_path, app_folder); - } - - bool result = dialog_file_browser_show( - dialogs, file_path, file_path, app_extension, true, &I_125_10px, true); - - if(result) { - result = load_key_data(file_path, true); - } - - return result; -} - -bool LfRfidApp::delete_key() { - return storage_simply_remove(storage, string_get_cstr(file_path)); -} - -bool LfRfidApp::load_key_data(string_t path, bool show_dialog) { - bool result = false; - - do { - protocol_id = lfrfid_dict_file_load(dict, string_get_cstr(path)); - if(protocol_id == PROTOCOL_NO) break; - - path_extract_filename(path, file_name, true); - result = true; - } while(0); - - if((!result) && (show_dialog)) { - dialog_message_show_storage_error(dialogs, "Cannot load\nkey file"); - } - - return result; -} - -bool LfRfidApp::save_key_data(string_t path) { - bool result = lfrfid_dict_file_save(dict, protocol_id, string_get_cstr(path)); - - if(!result) { - dialog_message_show_storage_error(dialogs, "Cannot save\nkey file"); - } - - return result; -} - -void LfRfidApp::make_app_folder() { - if(!storage_simply_mkdir(storage, app_folder)) { - dialog_message_show_storage_error(dialogs, "Cannot create\napp folder"); - } -} diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h deleted file mode 100644 index 153218db..00000000 --- a/applications/lfrfid/lfrfid_app.h +++ /dev/null @@ -1,137 +0,0 @@ -#pragma once -#include "m-string.h" -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "view/container_vm.h" - -#include -#include -#include - -#include "rpc/rpc_app.h" - -#include -#include -#include -#include - -#define LFRFID_KEY_NAME_SIZE 22 - -class LfRfidApp { -public: - enum class EventType : uint8_t { - GENERIC_EVENT_ENUM_VALUES, - Next, - MenuSelected, - Stay, - Retry, - Exit, - ReadEventSenseStart, - ReadEventSenseEnd, - ReadEventSenseCardStart, - ReadEventSenseCardEnd, - ReadEventStartASK, - ReadEventStartPSK, - ReadEventDone, - ReadEventOverrun, - ReadEventError, - WriteEventOK, - WriteEventProtocolCannotBeWritten, - WriteEventFobCannotBeWritten, - WriteEventTooLongToWrite, - RpcLoadFile, - RpcSessionClose, - }; - - enum class SceneType : uint8_t { - GENERIC_SCENE_ENUM_VALUES, - Read, - ReadSuccess, - RetryConfirm, - ExitConfirm, - ReadKeyMenu, - Write, - WriteSuccess, - Emulate, - SaveName, - SaveSuccess, - SelectKey, - SavedKeyMenu, - SaveData, - SaveType, - SavedInfo, - DeleteConfirm, - DeleteSuccess, - Rpc, - ExtraActions, - RawInfo, - RawName, - RawRead, - RawSuccess, - }; - - class Event { - public: - union { - int32_t signed_int; - } payload; - - EventType type; - }; - - SceneController, LfRfidApp> scene_controller; - ViewController - view_controller; - - ~LfRfidApp(); - LfRfidApp(); - - RecordController notification; - RecordController storage; - RecordController dialogs; - - TextStore text_store; - - string_t file_path; - - RpcAppSystem* rpc_ctx; - - void run(void* args); - - static const char* app_folder; - static const char* app_sd_folder; - static const char* app_extension; - static const char* app_filetype; - - bool save_key(); - bool load_key_from_file_select(bool need_restore); - bool delete_key(); - - bool load_key_data(string_t path, bool show_dialog); - bool save_key_data(string_t path); - - void make_app_folder(); - - ProtocolDict* dict; - LFRFIDWorker* lfworker; - string_t file_name; - ProtocolId protocol_id; - LFRFIDWorkerReadType read_type; - - uint8_t* old_key_data; - uint8_t* new_key_data; - - string_t raw_file_name; -}; diff --git a/applications/lfrfid/lfrfid_app_launcher.cpp b/applications/lfrfid/lfrfid_app_launcher.cpp deleted file mode 100644 index 2855850f..00000000 --- a/applications/lfrfid/lfrfid_app_launcher.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "lfrfid_app.h" - -// app enter function -extern "C" int32_t lfrfid_app(void* args) { - LfRfidApp* app = new LfRfidApp(); - app->run(args); - delete app; - - return 0; -} diff --git a/applications/lfrfid/lfrfid_cli.c b/applications/lfrfid/lfrfid_cli.c index 9a6930a6..281a0e96 100644 --- a/applications/lfrfid/lfrfid_cli.c +++ b/applications/lfrfid/lfrfid_cli.c @@ -114,7 +114,7 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { string_t info; string_init(info); protocol_dict_render_data(dict, info, context.protocol); - if(string_size(info) > 0) { + if(!string_empty_p(info)) { printf("%s\r\n", string_get_cstr(info)); } string_clear(info); diff --git a/applications/lfrfid/lfrfid_i.h b/applications/lfrfid/lfrfid_i.h new file mode 100644 index 00000000..77e87252 --- /dev/null +++ b/applications/lfrfid/lfrfid_i.h @@ -0,0 +1,145 @@ +#pragma once + +#include "m-string.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define LFRFID_KEY_NAME_SIZE 22 +#define LFRFID_TEXT_STORE_SIZE 40 + +#define LFRFID_APP_FOLDER ANY_PATH("lfrfid") +#define LFRFID_SD_FOLDER EXT_PATH("lfrfid") +#define LFRFID_APP_EXTENSION ".rfid" +#define LFRFID_APP_SHADOW_EXTENSION ".shd" + +#define LFRFID_APP_RAW_ASK_EXTENSION ".ask.raw" +#define LFRFID_APP_RAW_PSK_EXTENSION ".psk.raw" + +enum LfRfidCustomEvent { + LfRfidEventNext = 100, + LfRfidEventExit, + LfRfidEventPopupClosed, + LfRfidEventReadSenseStart, + LfRfidEventReadSenseEnd, + LfRfidEventReadSenseCardStart, + LfRfidEventReadSenseCardEnd, + LfRfidEventReadStartASK, + LfRfidEventReadStartPSK, + LfRfidEventReadDone, + LfRfidEventReadOverrun, + LfRfidEventReadError, + LfRfidEventWriteOK, + LfRfidEventWriteProtocolCannotBeWritten, + LfRfidEventWriteFobCannotBeWritten, + LfRfidEventWriteTooLongToWrite, + LfRfidEventRpcLoadFile, + LfRfidEventRpcSessionClose, +}; + +typedef enum { + LfRfidRpcStateIdle, + LfRfidRpcStateEmulating, +} LfRfidRpcState; + +typedef struct LfRfid LfRfid; + +struct LfRfid { + LFRFIDWorker* lfworker; + ViewDispatcher* view_dispatcher; + Gui* gui; + NotificationApp* notifications; + SceneManager* scene_manager; + Storage* storage; + DialogsApp* dialogs; + Widget* widget; + + char text_store[LFRFID_TEXT_STORE_SIZE + 1]; + string_t file_path; + string_t file_name; + string_t raw_file_name; + + ProtocolDict* dict; + ProtocolId protocol_id; + ProtocolId protocol_id_next; + LFRFIDWorkerReadType read_type; + + uint8_t* old_key_data; + uint8_t* new_key_data; + + RpcAppSystem* rpc_ctx; + LfRfidRpcState rpc_state; + + // Common Views + Submenu* submenu; + DialogEx* dialog_ex; + Popup* popup; + TextInput* text_input; + ByteInput* byte_input; + + // Custom views + LfRfidReadView* read_view; +}; + +typedef enum { + LfRfidViewSubmenu, + LfRfidViewDialogEx, + LfRfidViewPopup, + LfRfidViewWidget, + LfRfidViewTextInput, + LfRfidViewByteInput, + LfRfidViewRead, +} LfRfidView; + +bool lfrfid_save_key(LfRfid* app); + +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_save_key_data(LfRfid* app, string_t path); + +void lfrfid_make_app_folder(LfRfid* app); + +void lfrfid_text_store_set(LfRfid* app, const char* text, ...); + +void lfrfid_text_store_clear(LfRfid* app); + +void lfrfid_popup_timeout_callback(void* context); + +void lfrfid_widget_callback(GuiButtonType result, InputType type, void* context); + +void lfrfid_text_input_callback(void* context); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp deleted file mode 100644 index 58ff4dcd..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "lfrfid_app_scene_delete_confirm.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_data); - string_init(string_header); - - auto container = app->view_controller.get(); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Left, "Back"); - button->set_callback(app, LfRfidAppSceneDeleteConfirm::back_callback); - - button = container->add(); - button->set_type(ButtonElement::Type::Right, "Delete"); - button->set_callback(app, LfRfidAppSceneDeleteConfirm::delete_callback); - - auto line_1 = container->add(); - auto line_2 = container->add(); - auto line_3 = container->add(); - - 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(string_data, " "); - } - - string_cat_printf(string_data, "%02X", data[i]); - } - free(data); - - string_printf(string_header, "Delete %s?", string_get_cstr(app->file_name)); - line_1->set_text( - string_get_cstr(string_header), 64, 0, 128 - 2, AlignCenter, AlignTop, FontPrimary); - line_2->set_text( - string_get_cstr(string_data), 64, 19, 0, AlignCenter, AlignTop, FontSecondary); - line_3->set_text( - protocol_dict_get_name(app->dict, app->protocol_id), - 64, - 49, - 0, - AlignCenter, - AlignBottom, - FontSecondary); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneDeleteConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - app->delete_key(); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::DeleteSuccess); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Stay) { - app->scene_controller.switch_to_previous_scene(); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneDeleteConfirm::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - string_clear(string_data); - string_clear(string_header); -} - -void LfRfidAppSceneDeleteConfirm::back_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Stay; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneDeleteConfirm::delete_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h deleted file mode 100644 index f9daed54..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneDeleteConfirm : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void back_callback(void* context); - static void delete_callback(void* context); - - string_t string_header; - string_t string_data; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp deleted file mode 100644 index 9820338d..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "lfrfid_app_scene_delete_success.h" - -void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - - popup->set_icon(0, 2, &I_DolphinMafia_115x62); - popup->set_header("Deleted", 83, 19, AlignLeft, AlignBottom); - popup->set_context(app); - popup->set_callback(LfRfidAppSceneDeleteSuccess::timeout_callback); - popup->set_timeout(1500); - popup->enable_timeout(); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneDeleteSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::SelectKey}); - - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneDeleteSuccess::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneDeleteSuccess::timeout_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h deleted file mode 100644 index 009b9f25..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneDeleteSuccess : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void timeout_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp b/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp deleted file mode 100644 index 02cb011d..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "lfrfid_app_scene_emulate.h" -#include -#include - -void LfRfidAppSceneEmulate::on_enter(LfRfidApp* app, bool /* need_restore */) { - DOLPHIN_DEED(DolphinDeedRfidEmulate); - auto popup = app->view_controller.get(); - - popup->set_header("Emulating", 89, 30, AlignCenter, AlignTop); - if(string_size(app->file_name)) { - popup->set_text(string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); - } else { - popup->set_text( - protocol_dict_get_name(app->dict, app->protocol_id), 89, 43, AlignCenter, AlignTop); - } - popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61); - - app->view_controller.switch_to(); - lfrfid_worker_start_thread(app->lfworker); - lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); - notification_message(app->notification, &sequence_blink_start_magenta); -} - -bool LfRfidAppSceneEmulate::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - UNUSED(app); - UNUSED(event); - bool consumed = false; - return consumed; -} - -void LfRfidAppSceneEmulate::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - lfrfid_worker_stop(app->lfworker); - lfrfid_worker_stop_thread(app->lfworker); - notification_message(app->notification, &sequence_blink_stop); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_emulate.h b/applications/lfrfid/scene/lfrfid_app_scene_emulate.h deleted file mode 100644 index 13d2b857..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_emulate.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneEmulate : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp deleted file mode 100644 index be070b40..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "lfrfid_app_scene_exit_confirm.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto container = app->view_controller.get(); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Left, "Exit"); - button->set_callback(app, LfRfidAppSceneExitConfirm::exit_callback); - - button = container->add(); - button->set_type(ButtonElement::Type::Right, "Stay"); - button->set_callback(app, LfRfidAppSceneExitConfirm::stay_callback); - - auto line_1 = container->add(); - auto line_2 = container->add(); - - line_1->set_text("Exit to RFID Menu?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); - line_2->set_text( - "All unsaved data will be lost!", 64, 31, 0, AlignCenter, AlignBottom, FontSecondary); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneExitConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Start}); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Stay) { - app->scene_controller.switch_to_previous_scene(); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneExitConfirm::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneExitConfirm::exit_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneExitConfirm::stay_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Stay; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h deleted file mode 100644 index a0a10232..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneExitConfirm : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void exit_callback(void* context); - static void stay_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.cpp b/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.cpp deleted file mode 100644 index ea4f03db..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "lfrfid_app_scene_extra_actions.h" - -typedef enum { - SubmenuASK, - SubmenuPSK, - SubmenuRAW, -} SubmenuIndex; - -void LfRfidAppSceneExtraActions::on_enter(LfRfidApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - - submenu->add_item("Read ASK (Animal, Ordinary Card)", SubmenuASK, submenu_callback, app); - submenu->add_item("Read PSK (Indala)", SubmenuPSK, submenu_callback, app); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - submenu->add_item("Read RAW RFID data", SubmenuRAW, submenu_callback, app); - } - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneExtraActions::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.signed_int; - switch(event->payload.signed_int) { - case SubmenuASK: - app->read_type = LFRFIDWorkerReadTypeASKOnly; - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Read); - break; - case SubmenuPSK: - app->read_type = LFRFIDWorkerReadTypePSKOnly; - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Read); - break; - case SubmenuRAW: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::RawName); - break; - } - - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneExtraActions::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneExtraActions::submenu_callback(void* context, uint32_t index) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - - event.type = LfRfidApp::EventType::MenuSelected; - event.payload.signed_int = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.h b/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.h deleted file mode 100644 index dcd74614..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_extra_actions.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneExtraActions : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_info.cpp b/applications/lfrfid/scene/lfrfid_app_scene_raw_info.cpp deleted file mode 100644 index ce3634b2..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_info.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "lfrfid_app_scene_raw_info.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -static void ok_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} - -static void back_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneRawInfo::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_info); - - auto container = app->view_controller.get(); - - bool sd_exist = storage_sd_status(app->storage) == FSE_OK; - if(!sd_exist) { - auto icon = container->add(); - icon->set_icon(0, 0, &I_SDQuestion_35x43); - auto line = container->add(); - line->set_text( - "No SD card found.\nThis function will not\nwork without\nSD card.", - 81, - 4, - 0, - AlignCenter, - AlignTop, - FontSecondary); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Left, "Back"); - button->set_callback(app, back_callback); - } else { - string_printf( - string_info, - "RAW RFID data reader\r\n" - "1) Put the Flipper on your card\r\n" - "2) Press OK\r\n" - "3) Wait until data is read"); - - auto line = container->add(); - line->set_text(string_get_cstr(string_info), 0, 1, 0, AlignLeft, AlignTop, FontSecondary); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Center, "OK"); - button->set_callback(app, ok_callback); - } - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneRawInfo::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.switch_to_scene({LfRfidApp::SceneType::RawRead}); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ExtraActions}); - consumed = true; - } - return consumed; -} - -void LfRfidAppSceneRawInfo::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - string_clear(string_info); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_info.h b/applications/lfrfid/scene/lfrfid_app_scene_raw_info.h deleted file mode 100644 index eecca143..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_info.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRawInfo : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - string_t string_info; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_raw_name.cpp deleted file mode 100644 index 0ad34619..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_name.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -#include "lfrfid_app_scene_raw_name.h" -#include "m-string.h" -#include -#include - -void LfRfidAppSceneRawName::on_enter(LfRfidApp* app, bool /* need_restore */) { - const char* key_name = string_get_cstr(app->raw_file_name); - - bool key_name_empty = (string_size(app->raw_file_name) == 0); - if(key_name_empty) { - app->text_store.set("RfidRecord"); - } else { - app->text_store.set("%s", key_name); - } - - auto text_input = app->view_controller.get(); - text_input->set_header_text("Name the raw file"); - - text_input->set_result_callback( - save_callback, app, app->text_store.text, LFRFID_KEY_NAME_SIZE, key_name_empty); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneRawName::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - string_set_str(app->raw_file_name, app->text_store.text); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::RawInfo); - } - - return consumed; -} - -void LfRfidAppSceneRawName::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneRawName::save_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_name.h b/applications/lfrfid/scene/lfrfid_app_scene_raw_name.h deleted file mode 100644 index 225d135e..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_name.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRawName : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void save_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_read.cpp b/applications/lfrfid/scene/lfrfid_app_scene_raw_read.cpp deleted file mode 100644 index 0d04e6bc..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_read.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "lfrfid_app_scene_raw_read.h" -#include - -#define RAW_READ_TIME 5000 - -static void lfrfid_read_callback(LFRFIDWorkerReadRawResult result, void* ctx) { - LfRfidApp* app = static_cast(ctx); - LfRfidApp::Event event; - - switch(result) { - case LFRFIDWorkerReadRawFileError: - event.type = LfRfidApp::EventType::ReadEventError; - break; - case LFRFIDWorkerReadRawOverrun: - event.type = LfRfidApp::EventType::ReadEventOverrun; - break; - } - - app->view_controller.send_event(&event); -} - -static void timer_callback(void* ctx) { - LfRfidApp* app = static_cast(ctx); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::ReadEventDone; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneRawRead::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_file_name); - auto popup = app->view_controller.get(); - popup->set_icon(0, 3, &I_RFIDDolphinReceive_97x61); - app->view_controller.switch_to(); - lfrfid_worker_start_thread(app->lfworker); - app->make_app_folder(); - - timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app); - furi_timer_start(timer, RAW_READ_TIME); - string_printf( - string_file_name, "%s/%s.ask.raw", app->app_sd_folder, string_get_cstr(app->raw_file_name)); - popup->set_header("Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); - lfrfid_worker_read_raw_start( - app->lfworker, - string_get_cstr(string_file_name), - LFRFIDWorkerReadTypeASKOnly, - lfrfid_read_callback, - app); - - notification_message(app->notification, &sequence_blink_start_cyan); - - is_psk = false; - error = false; -} - -bool LfRfidAppSceneRawRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - UNUSED(app); - bool consumed = true; - auto popup = app->view_controller.get(); - - switch(event->type) { - case LfRfidApp::EventType::ReadEventError: - error = true; - popup->set_header("Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop); - notification_message(app->notification, &sequence_blink_start_red); - furi_timer_stop(timer); - break; - case LfRfidApp::EventType::ReadEventDone: - if(!error) { - if(is_psk) { - notification_message(app->notification, &sequence_success); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::RawSuccess); - } else { - popup->set_header("Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop); - notification_message(app->notification, &sequence_blink_start_yellow); - lfrfid_worker_stop(app->lfworker); - string_printf( - string_file_name, - "%s/%s.psk.raw", - app->app_sd_folder, - string_get_cstr(app->raw_file_name)); - lfrfid_worker_read_raw_start( - app->lfworker, - string_get_cstr(string_file_name), - LFRFIDWorkerReadTypePSKOnly, - lfrfid_read_callback, - app); - furi_timer_start(timer, RAW_READ_TIME); - is_psk = true; - } - } - break; - default: - consumed = false; - break; - } - - return consumed; -} - -void LfRfidAppSceneRawRead::on_exit(LfRfidApp* app) { - notification_message(app->notification, &sequence_blink_stop); - app->view_controller.get()->clean(); - lfrfid_worker_stop(app->lfworker); - lfrfid_worker_stop_thread(app->lfworker); - furi_timer_free(timer); - string_clear(string_file_name); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_read.h b/applications/lfrfid/scene/lfrfid_app_scene_raw_read.h deleted file mode 100644 index 09ef7463..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_read.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRawRead : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - string_t string_file_name; - FuriTimer* timer; - bool is_psk; - bool error; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_raw_success.cpp deleted file mode 100644 index 227ab580..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_success.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "lfrfid_app_scene_raw_success.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneRawSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_info); - - string_printf(string_info, "RAW RFID read success!\r\n"); - string_cat_printf(string_info, "Now you can analyze files\r\n"); - string_cat_printf(string_info, "Or send them to developers"); - - auto container = app->view_controller.get(); - - auto line = container->add(); - line->set_text(string_get_cstr(string_info), 0, 1, 0, AlignLeft, AlignTop, FontSecondary); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Center, "OK"); - button->set_callback(app, LfRfidAppSceneRawSuccess::ok_callback); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneRawSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ExtraActions}); - consumed = true; - } - return consumed; -} - -void LfRfidAppSceneRawSuccess::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - string_clear(string_info); -} - -void LfRfidAppSceneRawSuccess::ok_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_raw_success.h b/applications/lfrfid/scene/lfrfid_app_scene_raw_success.h deleted file mode 100644 index 0a0b0116..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_raw_success.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRawSuccess : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - string_t string_info; - static void ok_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp deleted file mode 100644 index 120eb1a0..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "lfrfid_app_scene_read.h" -#include - -static void lfrfid_read_callback(LFRFIDWorkerReadResult result, ProtocolId protocol, void* ctx) { - LfRfidApp* app = static_cast(ctx); - LfRfidApp::Event event; - - switch(result) { - case LFRFIDWorkerReadSenseStart: - event.type = LfRfidApp::EventType::ReadEventSenseStart; - break; - case LFRFIDWorkerReadSenseEnd: - event.type = LfRfidApp::EventType::ReadEventSenseEnd; - break; - case LFRFIDWorkerReadSenseCardStart: - event.type = LfRfidApp::EventType::ReadEventSenseCardStart; - break; - case LFRFIDWorkerReadSenseCardEnd: - event.type = LfRfidApp::EventType::ReadEventSenseCardEnd; - break; - case LFRFIDWorkerReadDone: - event.type = LfRfidApp::EventType::ReadEventDone; - break; - case LFRFIDWorkerReadStartASK: - event.type = LfRfidApp::EventType::ReadEventStartASK; - break; - case LFRFIDWorkerReadStartPSK: - event.type = LfRfidApp::EventType::ReadEventStartPSK; - break; - } - - event.payload.signed_int = protocol; - - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneRead::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - - DOLPHIN_DEED(DolphinDeedRfidRead); - if(app->read_type == LFRFIDWorkerReadTypePSKOnly) { - popup->set_header("Reading\nLF RFID\nPSK", 89, 30, AlignCenter, AlignTop); - } else { - popup->set_header("Reading\nLF RFID\nASK", 89, 30, AlignCenter, AlignTop); - } - - popup->set_icon(0, 3, &I_RFIDDolphinReceive_97x61); - - app->view_controller.switch_to(); - lfrfid_worker_start_thread(app->lfworker); - lfrfid_worker_read_start(app->lfworker, app->read_type, lfrfid_read_callback, app); - - notification_message(app->notification, &sequence_blink_start_cyan); -} - -bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = true; - auto popup = app->view_controller.get(); - - switch(event->type) { - case LfRfidApp::EventType::ReadEventSenseStart: - notification_message(app->notification, &sequence_blink_stop); - notification_message(app->notification, &sequence_blink_start_yellow); - break; - case LfRfidApp::EventType::ReadEventSenseCardStart: - notification_message(app->notification, &sequence_blink_stop); - notification_message(app->notification, &sequence_blink_start_green); - break; - case LfRfidApp::EventType::ReadEventSenseEnd: - case LfRfidApp::EventType::ReadEventSenseCardEnd: - notification_message(app->notification, &sequence_blink_stop); - notification_message(app->notification, &sequence_blink_start_cyan); - break; - case LfRfidApp::EventType::ReadEventDone: - app->protocol_id = event->payload.signed_int; - DOLPHIN_DEED(DolphinDeedRfidReadSuccess); - notification_message(app->notification, &sequence_success); - string_reset(app->file_name); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); - break; - case LfRfidApp::EventType::ReadEventStartPSK: - popup->set_header("Reading\nLF RFID\nPSK", 89, 30, AlignCenter, AlignTop); - break; - case LfRfidApp::EventType::ReadEventStartASK: - popup->set_header("Reading\nLF RFID\nASK", 89, 30, AlignCenter, AlignTop); - break; - default: - consumed = false; - break; - } - - return consumed; -} - -void LfRfidAppSceneRead::on_exit(LfRfidApp* app) { - notification_message(app->notification, &sequence_blink_stop); - app->view_controller.get()->clean(); - lfrfid_worker_stop(app->lfworker); - lfrfid_worker_stop_thread(app->lfworker); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.h b/applications/lfrfid/scene/lfrfid_app_scene_read.h deleted file mode 100644 index b5035b72..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRead : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp deleted file mode 100644 index aa3b3f1f..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "lfrfid_app_scene_read_menu.h" - -typedef enum { - SubmenuSave, - SubmenuEmulate, - SubmenuWrite, -} SubmenuIndex; - -void LfRfidAppSceneReadKeyMenu::on_enter(LfRfidApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - - submenu->add_item("Save", SubmenuSave, submenu_callback, app); - submenu->add_item("Emulate", SubmenuEmulate, submenu_callback, app); - submenu->add_item("Write", SubmenuWrite, submenu_callback, app); - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneReadKeyMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.signed_int; - switch(event->payload.signed_int) { - case SubmenuWrite: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Write); - break; - case SubmenuSave: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveName); - break; - case SubmenuEmulate: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Emulate); - break; - } - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.switch_to_previous_scene(); - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneReadKeyMenu::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneReadKeyMenu::submenu_callback(void* context, uint32_t index) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - - event.type = LfRfidApp::EventType::MenuSelected; - event.payload.signed_int = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h deleted file mode 100644 index 2b50b96f..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneReadKeyMenu : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp deleted file mode 100644 index 277b43a3..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "lfrfid_app_scene_read_success.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_info); - string_init(string_header); - - string_init_printf( - string_header, - "%s[%s]", - protocol_dict_get_name(app->dict, app->protocol_id), - protocol_dict_get_manufacturer(app->dict, app->protocol_id)); - - 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 != 0) { - string_cat_printf(string_info, " "); - } - - if(i >= 9) { - string_cat_printf(string_info, "..."); - break; - } else { - string_cat_printf(string_info, "%02X", data[i]); - } - } - free(data); - - string_t render_data; - string_init(render_data); - protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id); - string_cat_printf(string_info, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); - - auto container = app->view_controller.get(); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Left, "Retry"); - button->set_callback(app, LfRfidAppSceneReadSuccess::back_callback); - - button = container->add(); - button->set_type(ButtonElement::Type::Right, "More"); - button->set_callback(app, LfRfidAppSceneReadSuccess::more_callback); - - auto header = container->add(); - header->set_text(string_get_cstr(string_header), 0, 2, 0, AlignLeft, AlignTop, FontPrimary); - - auto text = container->add(); - text->set_text(string_get_cstr(string_info), 0, 16, 0, AlignLeft, AlignTop, FontSecondary); - - app->view_controller.switch_to(); - - notification_message_block(app->notification, &sequence_set_green_255); -} - -bool LfRfidAppSceneReadSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadKeyMenu); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Retry) { - app->scene_controller.switch_to_next_scene({LfRfidApp::SceneType::RetryConfirm}); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.switch_to_next_scene({LfRfidApp::SceneType::ExitConfirm}); - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneReadSuccess::on_exit(LfRfidApp* app) { - notification_message_block(app->notification, &sequence_reset_green); - app->view_controller.get()->clean(); - string_clear(string_info); - string_clear(string_header); -} - -void LfRfidAppSceneReadSuccess::back_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Retry; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneReadSuccess::more_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.h b/applications/lfrfid/scene/lfrfid_app_scene_read_success.h deleted file mode 100644 index 6d90f631..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneReadSuccess : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void back_callback(void* context); - static void more_callback(void* context); - - string_t string_header; - string_t string_info; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp deleted file mode 100644 index c1812232..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "lfrfid_app_scene_retry_confirm.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneRetryConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto container = app->view_controller.get(); - - auto button = container->add(); - button->set_type(ButtonElement::Type::Left, "Exit"); - button->set_callback(app, LfRfidAppSceneRetryConfirm::exit_callback); - - button = container->add(); - button->set_type(ButtonElement::Type::Right, "Stay"); - button->set_callback(app, LfRfidAppSceneRetryConfirm::stay_callback); - - auto line_1 = container->add(); - auto line_2 = container->add(); - - line_1->set_text("Return to Reading?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); - line_2->set_text( - "All unsaved data will be lost!", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneRetryConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Read}); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Stay) { - app->scene_controller.switch_to_previous_scene(); - consumed = true; - } else if(event->type == LfRfidApp::EventType::Back) { - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneRetryConfirm::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneRetryConfirm::exit_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneRetryConfirm::stay_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Stay; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h deleted file mode 100644 index 01b7329c..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRetryConfirm : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void exit_callback(void* context); - static void stay_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp deleted file mode 100644 index c2e5ec2a..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "lfrfid_app_scene_rpc.h" -#include -#include -#include - -void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - - popup->set_header("LF RFID", 89, 42, AlignCenter, AlignBottom); - popup->set_text("RPC mode", 89, 44, AlignCenter, AlignTop); - popup->set_icon(0, 12, &I_RFIDDolphinSend_97x61); - - app->view_controller.switch_to(); - - notification_message(app->notification, &sequence_display_backlight_on); -} - -bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - UNUSED(app); - UNUSED(event); - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Exit) { - consumed = true; - LfRfidApp::Event view_event; - view_event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&view_event); - rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true); - } else if(event->type == LfRfidApp::EventType::RpcSessionClose) { - consumed = true; - LfRfidApp::Event view_event; - view_event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&view_event); - } else if(event->type == LfRfidApp::EventType::RpcLoadFile) { - const char* arg = rpc_system_app_get_data(app->rpc_ctx); - consumed = true; - bool result = false; - if(arg && !emulating) { - string_set_str(app->file_path, arg); - if(app->load_key_data(app->file_path, false)) { - lfrfid_worker_start_thread(app->lfworker); - lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); - emulating = true; - - auto popup = app->view_controller.get(); - app->text_store.set("emulating\n%s", string_get_cstr(app->file_name)); - popup->set_text(app->text_store.text, 89, 44, AlignCenter, AlignTop); - - notification_message(app->notification, &sequence_blink_start_magenta); - result = true; - } - } - rpc_system_app_confirm(app->rpc_ctx, RpcAppEventLoadFile, result); - } - - return consumed; -} - -void LfRfidAppSceneRpc::on_exit(LfRfidApp* app) { - if(emulating) { - lfrfid_worker_stop(app->lfworker); - lfrfid_worker_stop_thread(app->lfworker); - notification_message(app->notification, &sequence_blink_stop); - } - app->view_controller.get()->clean(); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.h b/applications/lfrfid/scene/lfrfid_app_scene_rpc.h deleted file mode 100644 index f630dfd3..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneRpc : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - bool emulating = false; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_data.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_data.cpp deleted file mode 100644 index c506cd72..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_data.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "lfrfid_app_scene_save_data.h" -#include - -void LfRfidAppSceneSaveData::on_enter(LfRfidApp* app, bool need_restore) { - auto byte_input = app->view_controller.get(); - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - - if(need_restore) { - protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); - } else { - 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); - - byte_input->set_header_text("Enter the data in hex"); - - byte_input->set_result_callback(save_callback, NULL, app, app->new_key_data, size); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneSaveData::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size); - DOLPHIN_DEED(DolphinDeedRfidAdd); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveName); - } - - return consumed; -} - -void LfRfidAppSceneSaveData::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneSaveData::save_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_data.h b/applications/lfrfid/scene/lfrfid_app_scene_save_data.h deleted file mode 100644 index d03cae12..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_data.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSaveData : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void save_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp deleted file mode 100644 index ed58b645..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "lfrfid_app_scene_save_name.h" -#include "m-string.h" -#include -#include - -void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool /* need_restore */) { - const char* key_name = string_get_cstr(app->file_name); - - bool key_name_empty = (string_size(app->file_name) == 0); - if(key_name_empty) { - string_set_str(app->file_path, app->app_folder); - set_random_name(app->text_store.text, app->text_store.text_size); - } else { - app->text_store.set("%s", key_name); - } - - auto text_input = app->view_controller.get(); - text_input->set_header_text("Name the card"); - - text_input->set_result_callback( - save_callback, app, app->text_store.text, LFRFID_KEY_NAME_SIZE, key_name_empty); - - string_t folder_path; - string_init(folder_path); - - path_extract_dirname(string_get_cstr(app->file_path), folder_path); - - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(folder_path), app->app_extension, key_name); - text_input->set_validator(validator_is_file_callback, validator_is_file); - - string_clear(folder_path); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneSaveName::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Next) { - if(string_size(app->file_name) > 0) { - app->delete_key(); - } - - string_set_str(app->file_name, app->text_store.text); - - if(app->save_key()) { - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveSuccess); - } else { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadKeyMenu}); - } - } - - return consumed; -} - -void LfRfidAppSceneSaveName::on_exit(LfRfidApp* app) { - void* validator_context = - app->view_controller.get()->get_validator_callback_context(); - app->view_controller.get()->set_validator(NULL, NULL); - validator_is_file_free((ValidatorIsFile*)validator_context); - - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneSaveName::save_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Next; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.h b/applications/lfrfid/scene/lfrfid_app_scene_save_name.h deleted file mode 100644 index ced42cc0..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSaveName : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void save_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp deleted file mode 100644 index 64efafa7..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "lfrfid_app_scene_save_success.h" -#include -#include -#include - -void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - - DOLPHIN_DEED(DolphinDeedRfidSave); - popup->set_icon(32, 5, &I_DolphinNice_96x59); - popup->set_header("Saved!", 5, 7, AlignLeft, AlignTop); - popup->set_context(app); - popup->set_callback(LfRfidAppSceneSaveSuccess::timeout_callback); - popup->set_timeout(1500); - popup->enable_timeout(); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneSaveSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Back) { - bool result = app->scene_controller.has_previous_scene( - {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); - - if(result) { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); - } else { - app->scene_controller.search_and_switch_to_another_scene( - {LfRfidApp::SceneType::SaveType}, LfRfidApp::SceneType::SelectKey); - } - - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneSaveSuccess::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneSaveSuccess::timeout_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_success.h b/applications/lfrfid/scene/lfrfid_app_scene_save_success.h deleted file mode 100644 index 62273a76..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_success.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSaveSuccess : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void timeout_callback(void* context); -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_type.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_type.cpp deleted file mode 100644 index b017e7b0..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_type.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "lfrfid_app_scene_save_type.h" - -void LfRfidAppSceneSaveType::on_enter(LfRfidApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - - for(uint8_t i = 0; i < keys_count; i++) { - string_init_printf( - submenu_name[i], - "%s %s", - protocol_dict_get_manufacturer(app->dict, i), - protocol_dict_get_name(app->dict, i)); - submenu->add_item(string_get_cstr(submenu_name[i]), i, submenu_callback, app); - } - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - - app->view_controller.switch_to(); - - // clear key name - string_reset(app->file_name); -} - -bool LfRfidAppSceneSaveType::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.signed_int; - app->protocol_id = event->payload.signed_int; - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveData); - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneSaveType::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - for(uint8_t i = 0; i < keys_count; i++) { - string_clear(submenu_name[i]); - } -} - -void LfRfidAppSceneSaveType::submenu_callback(void* context, uint32_t index) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - - event.type = LfRfidApp::EventType::MenuSelected; - event.payload.signed_int = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_type.h b/applications/lfrfid/scene/lfrfid_app_scene_save_type.h deleted file mode 100644 index e4c1be3e..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_type.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSaveType : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; - static const uint8_t keys_count = static_cast(LFRFIDProtocol::LFRFIDProtocolMax); - string_t submenu_name[keys_count]; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp deleted file mode 100644 index 614dd505..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "lfrfid_app_scene_saved_info.h" -#include "../view/elements/button_element.h" -#include "../view/elements/icon_element.h" -#include "../view/elements/string_element.h" - -void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool /* need_restore */) { - string_init(string_info); - - string_printf( - string_info, - "%s [%s]\r\n", - 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); - 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 != 0) { - string_cat_printf(string_info, " "); - } - - string_cat_printf(string_info, "%02X", data[i]); - } - free(data); - - string_t render_data; - string_init(render_data); - protocol_dict_render_data(app->dict, render_data, app->protocol_id); - string_cat_printf(string_info, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); - - auto container = app->view_controller.get(); - - auto line_1 = container->add(); - line_1->set_text(string_get_cstr(string_info), 0, 1, 0, AlignLeft, AlignTop, FontSecondary); - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneSavedInfo::on_event(LfRfidApp* /* app */, LfRfidApp::Event* /* event */) { - return false; -} - -void LfRfidAppSceneSavedInfo::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); - string_clear(string_info); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h deleted file mode 100644 index b0b588bc..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSavedInfo : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - string_t string_info; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.cpp b/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.cpp deleted file mode 100644 index e7a38d8a..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "lfrfid_app_scene_saved_key_menu.h" - -typedef enum { - SubmenuEmulate, - SubmenuWrite, - SubmenuEdit, - SubmenuDelete, - SubmenuInfo, -} SubmenuIndex; - -void LfRfidAppSceneSavedKeyMenu::on_enter(LfRfidApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - - submenu->add_item("Emulate", SubmenuEmulate, submenu_callback, app); - submenu->add_item("Write", SubmenuWrite, submenu_callback, app); - submenu->add_item("Edit", SubmenuEdit, submenu_callback, app); - submenu->add_item("Delete", SubmenuDelete, submenu_callback, app); - submenu->add_item("Info", SubmenuInfo, submenu_callback, app); - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - - app->view_controller.switch_to(); -} - -bool LfRfidAppSceneSavedKeyMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.signed_int; - switch(event->payload.signed_int) { - case SubmenuEmulate: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Emulate); - break; - case SubmenuWrite: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Write); - break; - case SubmenuEdit: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveData); - break; - case SubmenuDelete: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::DeleteConfirm); - break; - case SubmenuInfo: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SavedInfo); - break; - } - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneSavedKeyMenu::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneSavedKeyMenu::submenu_callback(void* context, uint32_t index) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - - event.type = LfRfidApp::EventType::MenuSelected; - event.payload.signed_int = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h b/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h deleted file mode 100644 index 69a6e5e5..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSavedKeyMenu : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp b/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp deleted file mode 100644 index 6d5df73c..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "lfrfid_app_scene_select_key.h" - -void LfRfidAppSceneSelectKey::on_enter(LfRfidApp* app, bool need_restore) { - if(app->load_key_from_file_select(need_restore)) { - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SavedKeyMenu); - } else { - app->scene_controller.switch_to_previous_scene(); - } -} - -bool LfRfidAppSceneSelectKey::on_event(LfRfidApp* /* app */, LfRfidApp::Event* /* event */) { - return false; -} - -void LfRfidAppSceneSelectKey::on_exit(LfRfidApp* /* app */) { -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_select_key.h b/applications/lfrfid/scene/lfrfid_app_scene_select_key.h deleted file mode 100644 index be565a91..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_select_key.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneSelectKey : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_start.cpp b/applications/lfrfid/scene/lfrfid_app_scene_start.cpp deleted file mode 100644 index 5005c9af..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_start.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "lfrfid_app_scene_start.h" - -typedef enum { - SubmenuRead, - SubmenuSaved, - SubmenuAddManually, - SubmenuExtraActions, -} SubmenuIndex; - -void LfRfidAppSceneStart::on_enter(LfRfidApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - - submenu->add_item("Read", SubmenuRead, submenu_callback, app); - submenu->add_item("Saved", SubmenuSaved, submenu_callback, app); - submenu->add_item("Add Manually", SubmenuAddManually, submenu_callback, app); - submenu->add_item("Extra Actions", SubmenuExtraActions, submenu_callback, app); - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - - app->view_controller.switch_to(); - - // clear key - string_reset(app->file_name); - app->protocol_id = PROTOCOL_NO; - app->read_type = LFRFIDWorkerReadTypeAuto; -} - -bool LfRfidAppSceneStart::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.signed_int; - switch(event->payload.signed_int) { - case SubmenuRead: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Read); - break; - case SubmenuSaved: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SelectKey); - break; - case SubmenuAddManually: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveType); - break; - case SubmenuExtraActions: - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ExtraActions); - break; - } - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneStart::on_exit(LfRfidApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneStart::submenu_callback(void* context, uint32_t index) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - - event.type = LfRfidApp::EventType::MenuSelected; - event.payload.signed_int = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_start.h b/applications/lfrfid/scene/lfrfid_app_scene_start.h deleted file mode 100644 index 255590d6..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_start.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneStart : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp deleted file mode 100644 index 39e0630e..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "lfrfid_app_scene_write.h" - -static void lfrfid_write_callback(LFRFIDWorkerWriteResult result, void* ctx) { - LfRfidApp* app = static_cast(ctx); - LfRfidApp::Event event; - - switch(result) { - case LFRFIDWorkerWriteOK: - event.type = LfRfidApp::EventType::WriteEventOK; - break; - case LFRFIDWorkerWriteProtocolCannotBeWritten: - event.type = LfRfidApp::EventType::WriteEventProtocolCannotBeWritten; - break; - case LFRFIDWorkerWriteFobCannotBeWritten: - event.type = LfRfidApp::EventType::WriteEventFobCannotBeWritten; - break; - case LFRFIDWorkerWriteTooLongToWrite: - event.type = LfRfidApp::EventType::WriteEventTooLongToWrite; - break; - } - - app->view_controller.send_event(&event); -} - -void LfRfidAppSceneWrite::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - - popup->set_header("Writing", 89, 30, AlignCenter, AlignTop); - if(string_size(app->file_name)) { - popup->set_text(string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); - } else { - popup->set_text( - protocol_dict_get_name(app->dict, app->protocol_id), 89, 43, AlignCenter, AlignTop); - } - popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61); - - app->view_controller.switch_to(); - - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - app->old_key_data = (uint8_t*)malloc(size); - protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); - - lfrfid_worker_start_thread(app->lfworker); - lfrfid_worker_write_start( - app->lfworker, (LFRFIDProtocol)app->protocol_id, lfrfid_write_callback, app); - notification_message(app->notification, &sequence_blink_start_magenta); -} - -bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = true; - auto popup = app->view_controller.get(); - - switch(event->type) { - case LfRfidApp::EventType::WriteEventOK: - notification_message(app->notification, &sequence_success); - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::WriteSuccess); - break; - case LfRfidApp::EventType::WriteEventProtocolCannotBeWritten: - popup->set_icon(72, 17, &I_DolphinCommon_56x48); - popup->set_header("Error", 64, 3, AlignCenter, AlignTop); - popup->set_text("This protocol\ncannot be written", 3, 17, AlignLeft, AlignTop); - notification_message(app->notification, &sequence_blink_start_red); - break; - case LfRfidApp::EventType::WriteEventFobCannotBeWritten: - case LfRfidApp::EventType::WriteEventTooLongToWrite: - popup->set_icon(72, 17, &I_DolphinCommon_56x48); - popup->set_header("Still trying to write...", 64, 3, AlignCenter, AlignTop); - popup->set_text( - "Make sure this\ncard is writable\nand not\nprotected.", 3, 17, AlignLeft, AlignTop); - notification_message(app->notification, &sequence_blink_start_yellow); - break; - default: - consumed = false; - } - - return consumed; -} - -void LfRfidAppSceneWrite::on_exit(LfRfidApp* app) { - notification_message(app->notification, &sequence_blink_stop); - app->view_controller.get()->clean(); - lfrfid_worker_stop(app->lfworker); - lfrfid_worker_stop_thread(app->lfworker); - - 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); - free(app->old_key_data); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.h b/applications/lfrfid/scene/lfrfid_app_scene_write.h deleted file mode 100644 index 7564eff9..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_write.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneWrite : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; -}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp deleted file mode 100644 index 3cf00183..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "lfrfid_app_scene_write_success.h" - -void LfRfidAppSceneWriteSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { - auto popup = app->view_controller.get(); - popup->set_header("Successfully\nwritten!", 94, 3, AlignCenter, AlignTop); - popup->set_icon(0, 6, &I_RFIDDolphinSuccess_108x57); - popup->set_context(app); - popup->set_callback(LfRfidAppSceneWriteSuccess::timeout_callback); - popup->set_timeout(1500); - popup->enable_timeout(); - - app->view_controller.switch_to(); - notification_message_block(app->notification, &sequence_set_green_255); -} - -bool LfRfidAppSceneWriteSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); - consumed = true; - } - - return consumed; -} - -void LfRfidAppSceneWriteSuccess::on_exit(LfRfidApp* app) { - notification_message_block(app->notification, &sequence_reset_green); - app->view_controller.get()->clean(); -} - -void LfRfidAppSceneWriteSuccess::timeout_callback(void* context) { - LfRfidApp* app = static_cast(context); - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write_success.h b/applications/lfrfid/scene/lfrfid_app_scene_write_success.h deleted file mode 100644 index 4ac9f089..00000000 --- a/applications/lfrfid/scene/lfrfid_app_scene_write_success.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../lfrfid_app.h" - -class LfRfidAppSceneWriteSuccess : public GenericScene { -public: - void on_enter(LfRfidApp* app, bool need_restore) final; - bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; - void on_exit(LfRfidApp* app) final; - -private: - static void timeout_callback(void* context); -}; diff --git a/applications/lfrfid/scenes/lfrfid_scene.c b/applications/lfrfid/scenes/lfrfid_scene.c new file mode 100644 index 00000000..0de5ec36 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene.c @@ -0,0 +1,30 @@ +#include "lfrfid_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const lfrfid_on_enter_handlers[])(void*) = { +#include "lfrfid_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const lfrfid_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "lfrfid_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const lfrfid_on_exit_handlers[])(void* context) = { +#include "lfrfid_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers lfrfid_scene_handlers = { + .on_enter_handlers = lfrfid_on_enter_handlers, + .on_event_handlers = lfrfid_on_event_handlers, + .on_exit_handlers = lfrfid_on_exit_handlers, + .scene_num = LfRfidSceneNum, +}; diff --git a/applications/lfrfid/scenes/lfrfid_scene.h b/applications/lfrfid/scenes/lfrfid_scene.h new file mode 100644 index 00000000..8ce7da09 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) LfRfidScene##id, +typedef enum { +#include "lfrfid_scene_config.h" + LfRfidSceneNum, +} LfRfidScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers lfrfid_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "lfrfid_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "lfrfid_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "lfrfid_scene_config.h" +#undef ADD_SCENE diff --git a/applications/lfrfid/scenes/lfrfid_scene_config.h b/applications/lfrfid/scenes/lfrfid_scene_config.h new file mode 100644 index 00000000..b77ade82 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_config.h @@ -0,0 +1,24 @@ +ADD_SCENE(lfrfid, start, Start) +ADD_SCENE(lfrfid, read, Read) +ADD_SCENE(lfrfid, read_success, ReadSuccess) +ADD_SCENE(lfrfid, retry_confirm, RetryConfirm) +ADD_SCENE(lfrfid, exit_confirm, ExitConfirm) +ADD_SCENE(lfrfid, delete_confirm, DeleteConfirm) +ADD_SCENE(lfrfid, read_key_menu, ReadKeyMenu) +ADD_SCENE(lfrfid, write, Write) +ADD_SCENE(lfrfid, write_success, WriteSuccess) +ADD_SCENE(lfrfid, emulate, Emulate) +ADD_SCENE(lfrfid, save_name, SaveName) +ADD_SCENE(lfrfid, save_success, SaveSuccess) +ADD_SCENE(lfrfid, select_key, SelectKey) +ADD_SCENE(lfrfid, saved_key_menu, SavedKeyMenu) +ADD_SCENE(lfrfid, save_data, SaveData) +ADD_SCENE(lfrfid, save_type, SaveType) +ADD_SCENE(lfrfid, saved_info, SavedInfo) +ADD_SCENE(lfrfid, delete_success, DeleteSuccess) +ADD_SCENE(lfrfid, extra_actions, ExtraActions) +ADD_SCENE(lfrfid, raw_info, RawInfo) +ADD_SCENE(lfrfid, raw_name, RawName) +ADD_SCENE(lfrfid, raw_read, RawRead) +ADD_SCENE(lfrfid, raw_success, RawSuccess) +ADD_SCENE(lfrfid, rpc, Rpc) diff --git a/applications/lfrfid/scenes/lfrfid_scene_delete_confirm.c b/applications/lfrfid/scenes/lfrfid_scene_delete_confirm.c new file mode 100644 index 00000000..dc1c3df2 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_delete_confirm.c @@ -0,0 +1,68 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_delete_confirm_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + string_t tmp_string; + string_init(tmp_string); + + 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)); + widget_add_string_element( + widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(tmp_string)); + + 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, " "); + } + + 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_add_string_element( + widget, + 64, + 49, + AlignCenter, + AlignBottom, + FontSecondary, + protocol_dict_get_name(app->dict, app->protocol_id)); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); + string_clear(tmp_string); +} + +bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; // Ignore Back button presses + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_previous_scene(scene_manager); + } else if(event.event == GuiButtonTypeRight) { + lfrfid_delete_key(app); + scene_manager_next_scene(scene_manager, LfRfidSceneDeleteSuccess); + } + } + + return consumed; +} + +void lfrfid_scene_delete_confirm_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_delete_success.c b/applications/lfrfid/scenes/lfrfid_scene_delete_success.c new file mode 100644 index 00000000..f940b9bd --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_delete_success.c @@ -0,0 +1,35 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_delete_success_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); + popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); + popup_set_context(popup, app); + popup_set_callback(popup, lfrfid_popup_timeout_callback); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); +} + +bool lfrfid_scene_delete_success_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if((event.type == SceneManagerEventTypeBack) || + ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { + scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, LfRfidSceneSelectKey); + consumed = true; + } + + return consumed; +} + +void lfrfid_scene_delete_success_on_exit(void* context) { + LfRfid* app = context; + + popup_reset(app->popup); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/lfrfid/scenes/lfrfid_scene_emulate.c new file mode 100644 index 00000000..70cc2418 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_emulate.c @@ -0,0 +1,44 @@ +#include "../lfrfid_i.h" +#include + +void lfrfid_scene_emulate_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + 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); + } else { + popup_set_text( + popup, + protocol_dict_get_name(app->dict, app->protocol_id), + 89, + 43, + AlignCenter, + AlignTop); + } + popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); + + lfrfid_worker_start_thread(app->lfworker); + lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); + notification_message(app->notifications, &sequence_blink_start_magenta); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); +} + +bool lfrfid_scene_emulate_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void lfrfid_scene_emulate_on_exit(void* context) { + LfRfid* app = context; + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_exit_confirm.c b/applications/lfrfid/scenes/lfrfid_scene_exit_confirm.c new file mode 100644 index 00000000..e8ab481c --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_exit_confirm.c @@ -0,0 +1,39 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_exit_confirm_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to RFID Menu?"); + widget_add_string_element( + widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!"); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); +} + +bool lfrfid_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; // Ignore Back button presses + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneStart); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void lfrfid_scene_exit_confirm_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/lfrfid/scenes/lfrfid_scene_extra_actions.c new file mode 100644 index 00000000..43e3de99 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -0,0 +1,79 @@ +#include "../lfrfid_i.h" + +typedef enum { + SubmenuIndexASK, + SubmenuIndexPSK, + SubmenuIndexRAW, +} SubmenuIndex; + +static void lfrfid_scene_extra_actions_submenu_callback(void* context, uint32_t index) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_scene_extra_actions_on_enter(void* context) { + LfRfid* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, + "Read ASK (Animal, Ordinary Card)", + SubmenuIndexASK, + lfrfid_scene_extra_actions_submenu_callback, + app); + submenu_add_item( + submenu, + "Read PSK (Indala)", + SubmenuIndexPSK, + lfrfid_scene_extra_actions_submenu_callback, + app); + + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + submenu_add_item( + submenu, + "Read RAW RFID data", + SubmenuIndexRAW, + lfrfid_scene_extra_actions_submenu_callback, + app); + } + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions)); + + // clear key + string_reset(app->file_name); + app->protocol_id = PROTOCOL_NO; + app->read_type = LFRFIDWorkerReadTypeAuto; + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); +} + +bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexASK) { + app->read_type = LFRFIDWorkerReadTypeASKOnly; + scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); + consumed = true; + } else if(event.event == SubmenuIndexPSK) { + app->read_type = LFRFIDWorkerReadTypePSKOnly; + scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); + consumed = true; + } else if(event.event == SubmenuIndexRAW) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, event.event); + } + + return consumed; +} + +void lfrfid_scene_extra_actions_on_exit(void* context) { + LfRfid* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_raw_info.c b/applications/lfrfid/scenes/lfrfid_scene_raw_info.c new file mode 100644 index 00000000..f60dd624 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_raw_info.c @@ -0,0 +1,64 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_raw_info_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + // string_t tmp_string; + // string_init(tmp_string); + + bool sd_exist = storage_sd_status(app->storage) == FSE_OK; + if(!sd_exist) { + widget_add_icon_element(widget, 0, 0, &I_SDQuestion_35x43); + widget_add_string_multiline_element( + widget, + 81, + 4, + AlignCenter, + AlignTop, + FontSecondary, + "No SD card found.\nThis function will not\nwork without\nSD card."); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app); + } else { + widget_add_string_multiline_element( + widget, + 0, + 1, + AlignLeft, + AlignTop, + FontSecondary, + "RAW RFID data reader\n1) Put the Flipper on your card\n2) Press OK\n3) Wait until data is read"); + + widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app); + } + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); + //string_clear(tmp_string); +} + +bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneExtraActions); + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeCenter) { + scene_manager_next_scene(scene_manager, LfRfidSceneRawRead); + } else if(event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene( + scene_manager, LfRfidSceneExtraActions); + } + } + + return consumed; +} + +void lfrfid_scene_raw_info_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_raw_name.c b/applications/lfrfid/scenes/lfrfid_scene_raw_name.c new file mode 100644 index 00000000..512f9ee4 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_raw_name.c @@ -0,0 +1,58 @@ +#include "../lfrfid_i.h" + +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); + + bool key_name_is_empty = string_empty_p(app->file_name); + if(key_name_is_empty) { + lfrfid_text_store_set(app, "RfidRecord"); + } else { + lfrfid_text_store_set(app, "%s", key_name); + } + + text_input_set_header_text(text_input, "Name the raw file"); + + text_input_set_result_callback( + text_input, + lfrfid_text_input_callback, + app, + app->text_store, + LFRFID_KEY_NAME_SIZE, + key_name_is_empty); + + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(LFRFID_SD_FOLDER, LFRFID_APP_RAW_ASK_EXTENSION, NULL); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput); +} + +bool lfrfid_scene_raw_name_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventNext) { + consumed = true; + string_set_str(app->raw_file_name, app->text_store); + scene_manager_next_scene(scene_manager, LfRfidSceneRawInfo); + } + } + + return consumed; +} + +void lfrfid_scene_raw_name_on_exit(void* context) { + LfRfid* app = context; + TextInput* text_input = app->text_input; + + void* validator_context = text_input_get_validator_callback_context(text_input); + text_input_set_validator(text_input, NULL, NULL); + validator_is_file_free((ValidatorIsFile*)validator_context); + + text_input_reset(text_input); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_raw_read.c b/applications/lfrfid/scenes/lfrfid_scene_raw_read.c new file mode 100644 index 00000000..d0c03ffa --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_raw_read.c @@ -0,0 +1,126 @@ +#include "../lfrfid_i.h" + +#define RAW_READ_TIME 5000 + +typedef struct { + string_t string_file_name; + FuriTimer* timer; + bool is_psk; + bool error; +} LfRfidReadRawState; + +static void lfrfid_read_callback(LFRFIDWorkerReadRawResult result, void* context) { + LfRfid* app = context; + + if(result == LFRFIDWorkerReadRawFileError) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadError); + } else if(result == LFRFIDWorkerReadRawOverrun) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadOverrun); + } +} + +static void timer_callback(void* context) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadDone); +} + +void lfrfid_scene_raw_read_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); + string_init(state->string_file_name); + + popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + lfrfid_worker_start_thread(app->lfworker); + lfrfid_make_app_folder(app); + + state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app); + furi_timer_start(state->timer, RAW_READ_TIME); + string_printf( + state->string_file_name, + "%s/%s%s", + LFRFID_SD_FOLDER, + 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), + LFRFIDWorkerReadTypeASKOnly, + lfrfid_read_callback, + app); + + notification_message(app->notifications, &sequence_blink_start_cyan); + + state->is_psk = false; + state->error = false; +} + +bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + Popup* popup = app->popup; + LfRfidReadRawState* state = + (LfRfidReadRawState*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneRawRead); + bool consumed = false; + + furi_assert(state); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventReadError) { + consumed = true; + state->error = true; + popup_set_header( + popup, "Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_blink_start_red); + furi_timer_stop(state->timer); + } else if(event.event == LfRfidEventReadDone) { + consumed = true; + if(!state->error) { + if(state->is_psk) { + notification_message(app->notifications, &sequence_success); + scene_manager_next_scene(app->scene_manager, LfRfidSceneRawSuccess); + } else { + popup_set_header( + popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_blink_start_yellow); + lfrfid_worker_stop(app->lfworker); + string_printf( + state->string_file_name, + "%s/%s%s", + LFRFID_SD_FOLDER, + 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), + LFRFIDWorkerReadTypePSKOnly, + lfrfid_read_callback, + app); + furi_timer_start(state->timer, RAW_READ_TIME); + state->is_psk = true; + } + } + } + } + + return consumed; +} + +void lfrfid_scene_raw_read_on_exit(void* context) { + LfRfid* app = context; + LfRfidReadRawState* state = + (LfRfidReadRawState*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneRawRead); + + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + furi_timer_free(state->timer); + + string_clear(state->string_file_name); + free(state); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_raw_success.c b/applications/lfrfid/scenes/lfrfid_scene_raw_success.c new file mode 100644 index 00000000..09a00529 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_raw_success.c @@ -0,0 +1,39 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_raw_success_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app); + + widget_add_string_multiline_element( + widget, + 0, + 1, + AlignLeft, + AlignTop, + FontSecondary, + "RAW RFID read success!\nNow you can analyze files\nOr send them to developers"); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); +} + +bool lfrfid_scene_raw_success_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeCenter) { + scene_manager_search_and_switch_to_previous_scene( + scene_manager, LfRfidSceneExtraActions); + } + } + return consumed; +} + +void lfrfid_scene_raw_success_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_read.c b/applications/lfrfid/scenes/lfrfid_scene_read.c new file mode 100644 index 00000000..66168038 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_read.c @@ -0,0 +1,109 @@ +#include "../lfrfid_i.h" +#include + +static const NotificationSequence sequence_blink_set_yellow = { + &message_blink_set_color_yellow, + NULL, +}; + +static const NotificationSequence sequence_blink_set_green = { + &message_blink_set_color_green, + NULL, +}; + +static const NotificationSequence sequence_blink_set_cyan = { + &message_blink_set_color_cyan, + NULL, +}; + +static void + lfrfid_read_callback(LFRFIDWorkerReadResult result, ProtocolId protocol, void* context) { + LfRfid* app = context; + uint32_t event = 0; + + if(result == LFRFIDWorkerReadSenseStart) { + event = LfRfidEventReadSenseStart; + } else if(result == LFRFIDWorkerReadSenseEnd) { + event = LfRfidEventReadSenseEnd; + } else if(result == LFRFIDWorkerReadSenseCardStart) { + event = LfRfidEventReadSenseCardStart; + } else if(result == LFRFIDWorkerReadSenseCardEnd) { + event = LfRfidEventReadSenseCardEnd; + } else if(result == LFRFIDWorkerReadDone) { + event = LfRfidEventReadDone; + app->protocol_id_next = protocol; + } else if(result == LFRFIDWorkerReadStartASK) { + event = LfRfidEventReadStartASK; + } else if(result == LFRFIDWorkerReadStartPSK) { + event = LfRfidEventReadStartPSK; + } else { + return; + } + + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void lfrfid_scene_read_on_enter(void* context) { + LfRfid* app = context; + + DOLPHIN_DEED(DolphinDeedRfidRead); + if(app->read_type == LFRFIDWorkerReadTypePSKOnly) { + lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPskOnly); + } else if(app->read_type == LFRFIDWorkerReadTypeASKOnly) { + lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadAskOnly); + } + + lfrfid_worker_start_thread(app->lfworker); + lfrfid_worker_read_start(app->lfworker, app->read_type, lfrfid_read_callback, app); + + notification_message(app->notifications, &sequence_blink_start_cyan); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewRead); +} + +bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventReadSenseStart) { + notification_message(app->notifications, &sequence_blink_set_yellow); + consumed = true; + } else if(event.event == LfRfidEventReadSenseCardStart) { + notification_message(app->notifications, &sequence_blink_set_green); + consumed = true; + } else if( + (event.event == LfRfidEventReadSenseEnd) || + (event.event == LfRfidEventReadSenseCardEnd)) { + notification_message(app->notifications, &sequence_blink_set_cyan); + consumed = true; + } else if(event.event == LfRfidEventReadDone) { + app->protocol_id = app->protocol_id_next; + DOLPHIN_DEED(DolphinDeedRfidReadSuccess); + notification_message(app->notifications, &sequence_success); + string_reset(app->file_name); + scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess); + consumed = true; + } else if(event.event == LfRfidEventReadStartPSK) { + if(app->read_type == LFRFIDWorkerReadTypeAuto) { + lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPsk); + } + consumed = true; + } else if(event.event == LfRfidEventReadStartASK) { + if(app->read_type == LFRFIDWorkerReadTypeAuto) { + lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadAsk); + } + consumed = true; + } + } + + return consumed; +} + +void lfrfid_scene_read_on_exit(void* context) { + LfRfid* app = context; + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_read_key_menu.c b/applications/lfrfid/scenes/lfrfid_scene_read_key_menu.c new file mode 100644 index 00000000..221cc008 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_read_key_menu.c @@ -0,0 +1,58 @@ +#include "../lfrfid_i.h" + +typedef enum { + SubmenuIndexSave, + SubmenuIndexEmulate, + SubmenuIndexWrite, +} SubmenuIndex; + +void lfrfid_scene_read_key_menu_submenu_callback(void* context, uint32_t index) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_scene_read_key_menu_on_enter(void* context) { + LfRfid* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, "Save", SubmenuIndexSave, lfrfid_scene_read_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Emulate", SubmenuIndexEmulate, lfrfid_scene_read_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Write", SubmenuIndexWrite, lfrfid_scene_read_key_menu_submenu_callback, app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu)); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); +} + +bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite); + consumed = true; + } else if(event.event == SubmenuIndexSave) { + string_reset(app->file_name); + scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveName); + consumed = true; + } else if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event); + } + + return consumed; +} + +void lfrfid_scene_read_key_menu_on_exit(void* context) { + LfRfid* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_read_success.c b/applications/lfrfid/scenes/lfrfid_scene_read_success.c new file mode 100644 index 00000000..6761dcfe --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_read_success.c @@ -0,0 +1,79 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_read_success_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + string_t tmp_string; + string_init(tmp_string); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); + + 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)); + + 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 != 0) { + string_cat_printf(tmp_string, " "); + } + + if(i >= 9) { + string_cat_printf(tmp_string, "..."); + break; + } else { + string_cat_printf(tmp_string, "%02X", data[i]); + } + } + free(data); + + string_t render_data; + string_init(render_data); + 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); + + widget_add_string_element( + widget, 0, 16, AlignLeft, AlignTop, FontSecondary, 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); +} + +bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(scene_manager, LfRfidSceneExitConfirm); + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_next_scene(scene_manager, LfRfidSceneRetryConfirm); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_next_scene(scene_manager, LfRfidSceneReadKeyMenu); + } + } + + return consumed; +} + +void lfrfid_scene_read_success_on_exit(void* context) { + LfRfid* app = context; + notification_message_block(app->notifications, &sequence_reset_green); + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_retry_confirm.c b/applications/lfrfid/scenes/lfrfid_scene_retry_confirm.c new file mode 100644 index 00000000..f639f0ae --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_retry_confirm.c @@ -0,0 +1,39 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_retry_confirm_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!"); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); +} + +bool lfrfid_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; // Ignore Back button presses + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneRead); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void lfrfid_scene_retry_confirm_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/lfrfid/scenes/lfrfid_scene_rpc.c new file mode 100644 index 00000000..a69d6453 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_rpc.c @@ -0,0 +1,67 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_rpc_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 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); + + app->rpc_state = LfRfidRpcStateIdle; +} + +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) { + consumed = true; + if(event.event == LfRfidEventExit) { + rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true); + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } else if(event.event == LfRfidEventRpcSessionClose) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } else if(event.event == LfRfidEventRpcLoadFile) { + 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); + 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)); + popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); + + notification_message(app->notifications, &sequence_blink_start_magenta); + result = true; + } + } + rpc_system_app_confirm(app->rpc_ctx, RpcAppEventLoadFile, result); + } + } + return consumed; +} + +void lfrfid_scene_rpc_on_exit(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + if(app->rpc_state == LfRfidRpcStateEmulating) { + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + notification_message(app->notifications, &sequence_blink_stop); + } + + popup_reset(popup); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_save_data.c b/applications/lfrfid/scenes/lfrfid_scene_save_data.c new file mode 100644 index 00000000..2ca1bb43 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_save_data.c @@ -0,0 +1,51 @@ +#include "../lfrfid_i.h" +#include + +void lfrfid_scene_save_data_on_enter(void* context) { + LfRfid* app = context; + ByteInput* byte_input = app->byte_input; + + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + + 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 { + 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); + + byte_input_set_header_text(byte_input, "Enter the data in hex"); + + byte_input_set_result_callback( + byte_input, lfrfid_text_input_callback, NULL, app, app->new_key_data, size); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewByteInput); +} + +bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventNext) { + consumed = true; + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size); + DOLPHIN_DEED(DolphinDeedRfidAdd); + scene_manager_next_scene(scene_manager, LfRfidSceneSaveName); + scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 1); + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 0); + } + + return consumed; +} + +void lfrfid_scene_save_data_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_save_name.c b/applications/lfrfid/scenes/lfrfid_scene_save_name.c new file mode 100644 index 00000000..febf30a4 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_save_name.c @@ -0,0 +1,76 @@ +#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); + + bool key_name_is_empty = string_empty_p(app->file_name); + if(key_name_is_empty) { + string_set_str(app->file_path, LFRFID_APP_FOLDER); + set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE); + string_set_str(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); + } + + text_input_set_header_text(text_input, "Name the card"); + text_input_set_result_callback( + text_input, + lfrfid_text_input_callback, + app, + app->text_store, + LFRFID_KEY_NAME_SIZE, + key_name_is_empty); + + FURI_LOG_I("", "%s %s", 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)); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + string_clear(folder_path); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput); +} + +bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + SceneManager* scene_manager = app->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventNext) { + consumed = true; + if(!string_empty_p(app->file_name)) { + lfrfid_delete_key(app); + } + + string_set_str(app->file_name, app->text_store); + + if(lfrfid_save_key(app)) { + scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess); + } else { + scene_manager_search_and_switch_to_previous_scene( + scene_manager, LfRfidSceneReadKeyMenu); + } + } + } + + return consumed; +} + +void lfrfid_scene_save_name_on_exit(void* context) { + LfRfid* app = context; + TextInput* text_input = app->text_input; + + void* validator_context = text_input_get_validator_callback_context(text_input); + text_input_set_validator(text_input, NULL, NULL); + validator_is_file_free((ValidatorIsFile*)validator_context); + + text_input_reset(text_input); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/lfrfid/scenes/lfrfid_scene_save_success.c new file mode 100644 index 00000000..830ef336 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_save_success.c @@ -0,0 +1,43 @@ +#include "../lfrfid_i.h" +#include + +void lfrfid_scene_save_success_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + DOLPHIN_DEED(DolphinDeedRfidSave); + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); + popup_set_context(popup, app); + popup_set_callback(popup, lfrfid_popup_timeout_callback); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); +} + +bool lfrfid_scene_save_success_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey}; + + if((event.type == SceneManagerEventTypeBack) || + ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { + bool result = scene_manager_search_and_switch_to_previous_scene_one_of( + app->scene_manager, prev_scenes, COUNT_OF(prev_scenes)); + if(!result) { + scene_manager_search_and_switch_to_another_scene( + app->scene_manager, LfRfidSceneSelectKey); + } + consumed = true; + } + + return consumed; +} + +void lfrfid_scene_save_success_on_exit(void* context) { + LfRfid* app = context; + + popup_reset(app->popup); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_save_type.c b/applications/lfrfid/scenes/lfrfid_scene_save_type.c new file mode 100644 index 00000000..4c111600 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_save_type.c @@ -0,0 +1,86 @@ +#include "../lfrfid_i.h" + +typedef struct { + string_t menu_item_name[LFRFIDProtocolMax]; + uint32_t line_sel; +} SaveTypeCtx; + +static void lfrfid_scene_save_type_submenu_callback(void* context, uint32_t index) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_scene_save_type_on_enter(void* context) { + LfRfid* app = context; + Submenu* submenu = app->submenu; + + SaveTypeCtx* state = malloc(sizeof(SaveTypeCtx)); + for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) { + 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], + "%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)); + } + submenu_add_item( + submenu, + string_get_cstr(state->menu_item_name[i]), + i, + lfrfid_scene_save_type_submenu_callback, + app); + } + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType)); + + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, (uint32_t)state); + + // clear key name + string_reset(app->file_name); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); +} + +bool lfrfid_scene_save_type_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + SaveTypeCtx* state = + (SaveTypeCtx*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType); + furi_check(state); + + if(event.type == SceneManagerEventTypeCustom) { + app->protocol_id = event.event; + state->line_sel = event.event; + scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveData); + consumed = true; + } + + return consumed; +} + +void lfrfid_scene_save_type_on_exit(void* context) { + LfRfid* app = context; + SaveTypeCtx* state = + (SaveTypeCtx*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType); + furi_check(state); + + submenu_reset(app->submenu); + + for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) { + string_clear(state->menu_item_name[i]); + } + + uint32_t line_sel = state->line_sel; + + free(state); + + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, line_sel); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_saved_info.c b/applications/lfrfid/scenes/lfrfid_scene_saved_info.c new file mode 100644 index 00000000..1496c6b4 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_saved_info.c @@ -0,0 +1,51 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_saved_info_on_enter(void* context) { + LfRfid* app = context; + Widget* widget = app->widget; + + string_t tmp_string; + string_init(tmp_string); + + string_printf( + tmp_string, + "%s [%s]\r\n", + 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); + 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 != 0) { + string_cat_printf(tmp_string, " "); + } + + string_cat_printf(tmp_string, "%02X", data[i]); + } + free(data); + + string_t render_data; + string_init(render_data); + 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); + + widget_add_string_multiline_element( + widget, 0, 1, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); + string_clear(tmp_string); +} + +bool lfrfid_scene_saved_info_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void lfrfid_scene_saved_info_on_exit(void* context) { + LfRfid* app = context; + widget_reset(app->widget); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_saved_key_menu.c b/applications/lfrfid/scenes/lfrfid_scene_saved_key_menu.c new file mode 100644 index 00000000..040b31f1 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_saved_key_menu.c @@ -0,0 +1,69 @@ +#include "../lfrfid_i.h" + +typedef enum { + SubmenuIndexEmulate, + SubmenuIndexWrite, + SubmenuIndexEdit, + SubmenuIndexDelete, + SubmenuIndexInfo, +} SubmenuIndex; + +static void lfrfid_scene_saved_key_menu_submenu_callback(void* context, uint32_t index) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_scene_saved_key_menu_on_enter(void* context) { + LfRfid* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, "Emulate", SubmenuIndexEmulate, lfrfid_scene_saved_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Write", SubmenuIndexWrite, lfrfid_scene_saved_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Edit", SubmenuIndexEdit, lfrfid_scene_saved_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Delete", SubmenuIndexDelete, lfrfid_scene_saved_key_menu_submenu_callback, app); + submenu_add_item( + submenu, "Info", SubmenuIndexInfo, lfrfid_scene_saved_key_menu_submenu_callback, app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu)); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); +} + +bool lfrfid_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); + consumed = true; + } else if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite); + consumed = true; + } else if(event.event == SubmenuIndexEdit) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveData); + consumed = true; + } else if(event.event == SubmenuIndexDelete) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneDeleteConfirm); + consumed = true; + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSavedInfo); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu, event.event); + } + + return consumed; +} + +void lfrfid_scene_saved_key_menu_on_exit(void* context) { + LfRfid* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_select_key.c b/applications/lfrfid/scenes/lfrfid_scene_select_key.c new file mode 100644 index 00000000..2a9cc1c6 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_select_key.c @@ -0,0 +1,22 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_select_key_on_enter(void* context) { + LfRfid* app = context; + + if(lfrfid_load_key_from_file_select(app)) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSavedKeyMenu); + } else { + scene_manager_previous_scene(app->scene_manager); + } +} + +bool lfrfid_scene_select_key_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void lfrfid_scene_select_key_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_start.c b/applications/lfrfid/scenes/lfrfid_scene_start.c new file mode 100644 index 00000000..9074e859 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_start.c @@ -0,0 +1,72 @@ +#include "../lfrfid_i.h" + +typedef enum { + SubmenuIndexRead, + SubmenuIndexSaved, + SubmenuIndexAddManually, + SubmenuIndexExtraActions, +} SubmenuIndex; + +static void lfrfid_scene_start_submenu_callback(void* context, uint32_t index) { + LfRfid* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_scene_start_on_enter(void* context) { + LfRfid* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item(submenu, "Read", SubmenuIndexRead, lfrfid_scene_start_submenu_callback, app); + submenu_add_item( + submenu, "Saved", SubmenuIndexSaved, lfrfid_scene_start_submenu_callback, app); + submenu_add_item( + submenu, "Add Manually", SubmenuIndexAddManually, lfrfid_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Extra Actions", + SubmenuIndexExtraActions, + lfrfid_scene_start_submenu_callback, + app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneStart)); + + // clear key + string_reset(app->file_name); + app->protocol_id = PROTOCOL_NO; + app->read_type = LFRFIDWorkerReadTypeAuto; + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); +} + +bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexRead) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); + consumed = true; + } else if(event.event == SubmenuIndexSaved) { + string_set_str(app->file_path, LFRFID_APP_FOLDER); + scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectKey); + consumed = true; + } else if(event.event == SubmenuIndexAddManually) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveType); + consumed = true; + } else if(event.event == SubmenuIndexExtraActions) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneExtraActions); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneStart, event.event); + } + + return consumed; +} + +void lfrfid_scene_start_on_exit(void* context) { + LfRfid* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_write.c b/applications/lfrfid/scenes/lfrfid_scene_write.c new file mode 100644 index 00000000..4b03bac1 --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_write.c @@ -0,0 +1,96 @@ +#include "../lfrfid_i.h" + +static void lfrfid_write_callback(LFRFIDWorkerWriteResult result, void* context) { + LfRfid* app = context; + uint32_t event = 0; + + if(result == LFRFIDWorkerWriteOK) { + event = LfRfidEventWriteOK; + } else if(result == LFRFIDWorkerWriteProtocolCannotBeWritten) { + event = LfRfidEventWriteProtocolCannotBeWritten; + } else if(result == LFRFIDWorkerWriteFobCannotBeWritten) { + event = LfRfidEventWriteFobCannotBeWritten; + } else if(result == LFRFIDWorkerWriteTooLongToWrite) { + event = LfRfidEventWriteTooLongToWrite; + } + + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void lfrfid_scene_write_on_enter(void* context) { + LfRfid* app = 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); + } else { + popup_set_text( + popup, + protocol_dict_get_name(app->dict, app->protocol_id), + 89, + 43, + AlignCenter, + AlignTop); + } + popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + app->old_key_data = (uint8_t*)malloc(size); + protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); + + lfrfid_worker_start_thread(app->lfworker); + lfrfid_worker_write_start( + app->lfworker, (LFRFIDProtocol)app->protocol_id, lfrfid_write_callback, app); + notification_message(app->notifications, &sequence_blink_start_magenta); +} + +bool lfrfid_scene_write_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + Popup* popup = app->popup; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventWriteOK) { + notification_message(app->notifications, &sequence_success); + scene_manager_next_scene(app->scene_manager, LfRfidSceneWriteSuccess); + consumed = true; + } else if(event.event == LfRfidEventWriteProtocolCannotBeWritten) { + popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48); + popup_set_header(popup, "Error", 64, 3, AlignCenter, AlignTop); + popup_set_text(popup, "This protocol\ncannot be written", 3, 17, AlignLeft, AlignTop); + notification_message(app->notifications, &sequence_blink_start_red); + consumed = true; + } else if( + (event.event == LfRfidEventWriteFobCannotBeWritten) || + (event.event == LfRfidEventWriteTooLongToWrite)) { + popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48); + popup_set_header(popup, "Still trying to write...", 64, 3, AlignCenter, AlignTop); + popup_set_text( + popup, + "Make sure this\ncard is writable\nand not\nprotected.", + 3, + 17, + AlignLeft, + AlignTop); + notification_message(app->notifications, &sequence_blink_start_yellow); + consumed = true; + } + } + + return consumed; +} + +void lfrfid_scene_write_on_exit(void* context) { + LfRfid* app = context; + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + + 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); + free(app->old_key_data); +} diff --git a/applications/lfrfid/scenes/lfrfid_scene_write_success.c b/applications/lfrfid/scenes/lfrfid_scene_write_success.c new file mode 100644 index 00000000..52e30d6b --- /dev/null +++ b/applications/lfrfid/scenes/lfrfid_scene_write_success.c @@ -0,0 +1,38 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_write_success_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + popup_set_header(popup, "Successfully\nwritten!", 94, 3, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57); + popup_set_context(popup, app); + popup_set_callback(popup, lfrfid_popup_timeout_callback); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + notification_message_block(app->notifications, &sequence_set_green_255); +} + +bool lfrfid_scene_write_success_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + bool consumed = false; + + const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey}; + + if((event.type == SceneManagerEventTypeBack) || + ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { + scene_manager_search_and_switch_to_previous_scene_one_of( + app->scene_manager, prev_scenes, COUNT_OF(prev_scenes)); + consumed = true; + } + + return consumed; +} + +void lfrfid_scene_write_success_on_exit(void* context) { + LfRfid* app = context; + notification_message_block(app->notifications, &sequence_reset_green); + popup_reset(app->popup); +} diff --git a/applications/lfrfid/view/container_vm.cpp b/applications/lfrfid/view/container_vm.cpp deleted file mode 100644 index 3c01ba30..00000000 --- a/applications/lfrfid/view/container_vm.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "container_vm.h" -#include "elements/generic_element.h" -#include "elements/string_element.h" -#include "elements/icon_element.h" -#include "elements/button_element.h" -#include - -class ContainerVMData { -public: - ContainerVMData(){}; - - ~ContainerVMData() { - for(auto& it : elements) delete it; - }; - - std::list elements; - - template T add(const T element, View* view) { - elements.push_back(element); - element->set_parent_view(view); - return element; - } - - void clean() { - for(auto& it : elements) delete it; - elements.clear(); - } -}; - -struct ContainerVMModel { - ContainerVMData* data; -}; - -ContainerVM::ContainerVM() { - view = view_alloc(); - view_set_context(view, this); - view_allocate_model(view, ViewModelTypeLocking, sizeof(ContainerVMModel)); - - with_view_model_cpp(view, ContainerVMModel, model, { - model->data = new ContainerVMData(); - return true; - }); - - view_set_draw_callback(view, view_draw_callback); - view_set_input_callback(view, view_input_callback); -} - -ContainerVM::~ContainerVM() { - with_view_model_cpp(view, ContainerVMModel, model, { - delete model->data; - model->data = NULL; - return false; - }); - - view_free(view); -} - -View* ContainerVM::get_view() { - return view; -} - -void ContainerVM::clean() { - with_view_model_cpp(view, ContainerVMModel, model, { - model->data->clean(); - return true; - }); -} - -template T* ContainerVM::add() { - T* element = new T(); - - with_view_model_cpp(view, ContainerVMModel, model, { - model->data->add(element, view); - return true; - }); - - return element; -} - -void ContainerVM::view_draw_callback(Canvas* canvas, void* model) { - ContainerVMData* data = static_cast(model)->data; - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - - for(const auto& element : data->elements) { - element->draw(canvas); - } -} - -bool ContainerVM::view_input_callback(InputEvent* event, void* context) { - bool consumed = false; - View* view = static_cast(context)->view; - - with_view_model_cpp(view, ContainerVMModel, model, { - for(const auto& element : model->data->elements) { - if(element->input(event)) { - consumed = true; - } - - if(consumed) { - break; - } - } - - return consumed; - }); - - return consumed; -} - -template StringElement* ContainerVM::add(); -template IconElement* ContainerVM::add(); -template ButtonElement* ContainerVM::add(); diff --git a/applications/lfrfid/view/container_vm.h b/applications/lfrfid/view/container_vm.h deleted file mode 100644 index 011baa2e..00000000 --- a/applications/lfrfid/view/container_vm.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include - -class ContainerVM : public GenericViewModule { -public: - ContainerVM(); - ~ContainerVM() final; - View* get_view() final; - void clean() final; - - template T* add(); - -private: - View* view; - static void view_draw_callback(Canvas* canvas, void* model); - static bool view_input_callback(InputEvent* event, void* context); -}; diff --git a/applications/lfrfid/view/elements/button_element.cpp b/applications/lfrfid/view/elements/button_element.cpp deleted file mode 100644 index 58e1ac3e..00000000 --- a/applications/lfrfid/view/elements/button_element.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "button_element.h" -#include - -ButtonElement::ButtonElement() { -} - -ButtonElement::~ButtonElement() { -} - -void ButtonElement::draw(Canvas* canvas) { - if(text != nullptr) { - canvas_set_font(canvas, FontSecondary); - switch(type) { - case Type::Left: - elements_button_left(canvas, text); - break; - case Type::Center: - elements_button_center(canvas, text); - break; - case Type::Right: - elements_button_right(canvas, text); - break; - } - } -} - -bool ButtonElement::input(InputEvent* event) { - bool consumed = false; - if(event->type == InputTypeShort && callback != nullptr) { - switch(type) { - case Type::Left: - if(event->key == InputKeyLeft) { - callback(context); - consumed = true; - } - break; - case Type::Center: - if(event->key == InputKeyOk) { - callback(context); - consumed = true; - } - break; - case Type::Right: - if(event->key == InputKeyRight) { - callback(context); - consumed = true; - } - break; - } - } - - return consumed; -} - -void ButtonElement::set_type(Type _type, const char* _text) { - lock_model(); - type = _type; - text = _text; - unlock_model(true); -} - -void ButtonElement::set_callback(void* _context, ButtonElementCallback _callback) { - context = _context; - callback = _callback; -} diff --git a/applications/lfrfid/view/elements/button_element.h b/applications/lfrfid/view/elements/button_element.h deleted file mode 100644 index eb964427..00000000 --- a/applications/lfrfid/view/elements/button_element.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "generic_element.h" - -typedef void (*ButtonElementCallback)(void* context); - -class ButtonElement : public GenericElement { -public: - ButtonElement(); - ~ButtonElement() final; - void draw(Canvas* canvas) final; - bool input(InputEvent* event) final; - - enum class Type : uint8_t { - Left, - Center, - Right, - }; - - void set_type(Type type, const char* text); - void set_callback(void* context, ButtonElementCallback callback); - -private: - Type type = Type::Left; - const char* text = nullptr; - - void* context = nullptr; - ButtonElementCallback callback = nullptr; -}; diff --git a/applications/lfrfid/view/elements/generic_element.cpp b/applications/lfrfid/view/elements/generic_element.cpp deleted file mode 100644 index e0f08d15..00000000 --- a/applications/lfrfid/view/elements/generic_element.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "generic_element.h" - -void GenericElement::lock_model() { - furi_assert(view != nullptr); - view_get_model(view); -} - -void GenericElement::unlock_model(bool need_redraw) { - furi_assert(view != nullptr); - view_commit_model(view, need_redraw); -} - -void GenericElement::set_parent_view(View* _view) { - view = _view; -} diff --git a/applications/lfrfid/view/elements/generic_element.h b/applications/lfrfid/view/elements/generic_element.h deleted file mode 100644 index f5a58b2d..00000000 --- a/applications/lfrfid/view/elements/generic_element.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include -#include - -class GenericElement { -public: - GenericElement(){}; - virtual ~GenericElement(){}; - virtual void draw(Canvas* canvas) = 0; - virtual bool input(InputEvent* event) = 0; - - // TODO that must be accessible only to ContainerVMData - void set_parent_view(View* view); - - // TODO that must be accessible only to inheritors - void lock_model(); - void unlock_model(bool need_redraw); - -private: - View* view = nullptr; -}; diff --git a/applications/lfrfid/view/elements/icon_element.cpp b/applications/lfrfid/view/elements/icon_element.cpp deleted file mode 100644 index 0b6fba7d..00000000 --- a/applications/lfrfid/view/elements/icon_element.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "icon_element.h" - -IconElement::IconElement() { -} - -IconElement::~IconElement() { -} - -void IconElement::draw(Canvas* canvas) { - if(icon != NULL) { - canvas_draw_icon(canvas, x, y, icon); - } -} - -bool IconElement::input(InputEvent* /* event */) { - return false; -} - -void IconElement::set_icon(uint8_t _x, uint8_t _y, const Icon* _icon) { - lock_model(); - icon = _icon; - x = _x; - y = _y; - unlock_model(true); -} diff --git a/applications/lfrfid/view/elements/icon_element.h b/applications/lfrfid/view/elements/icon_element.h deleted file mode 100644 index a0820274..00000000 --- a/applications/lfrfid/view/elements/icon_element.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "generic_element.h" - -class IconElement : public GenericElement { -public: - IconElement(); - ~IconElement() final; - void draw(Canvas* canvas) final; - bool input(InputEvent* event) final; - - void set_icon(uint8_t x = 0, uint8_t y = 0, const Icon* icon = NULL); - -private: - const Icon* icon = NULL; - uint8_t x = 0; - uint8_t y = 0; -}; diff --git a/applications/lfrfid/view/elements/string_element.cpp b/applications/lfrfid/view/elements/string_element.cpp deleted file mode 100644 index 44c11e01..00000000 --- a/applications/lfrfid/view/elements/string_element.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "string_element.h" -#include - -StringElement::StringElement() { -} - -StringElement::~StringElement() { -} - -void StringElement::draw(Canvas* canvas) { - if(text) { - string_t line; - string_init(line); - string_set_str(line, text); - - canvas_set_font(canvas, font); - if(fit_width != 0) { - elements_string_fit_width(canvas, line, fit_width); - } - elements_multiline_text_aligned(canvas, x, y, horizontal, vertical, string_get_cstr(line)); - - string_clear(line); - } -} - -bool StringElement::input(InputEvent* /* event */) { - return false; -} - -void StringElement::set_text( - const char* _text, - uint8_t _x, - uint8_t _y, - uint8_t _fit_w, - Align _horizontal, - Align _vertical, - Font _font) { - lock_model(); - text = _text; - x = _x; - y = _y; - fit_width = _fit_w; - horizontal = _horizontal; - vertical = _vertical; - font = _font; - unlock_model(true); -} diff --git a/applications/lfrfid/view/elements/string_element.h b/applications/lfrfid/view/elements/string_element.h deleted file mode 100644 index 173fdd60..00000000 --- a/applications/lfrfid/view/elements/string_element.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "generic_element.h" - -class StringElement : public GenericElement { -public: - StringElement(); - ~StringElement() final; - void draw(Canvas* canvas) final; - bool input(InputEvent* event) final; - - void set_text( - const char* text = NULL, - uint8_t x = 0, - uint8_t y = 0, - uint8_t fit_width = 0, - Align horizontal = AlignLeft, - Align vertical = AlignTop, - Font font = FontPrimary); - -private: - const char* text = NULL; - uint8_t x = 0; - uint8_t y = 0; - uint8_t fit_width = 0; - Align horizontal = AlignLeft; - Align vertical = AlignTop; - Font font = FontPrimary; -}; diff --git a/applications/lfrfid/views/lfrfid_view_read.c b/applications/lfrfid/views/lfrfid_view_read.c new file mode 100644 index 00000000..2b63175d --- /dev/null +++ b/applications/lfrfid/views/lfrfid_view_read.c @@ -0,0 +1,117 @@ +#include "lfrfid_view_read.h" +#include + +#define TEMP_STR_LEN 128 + +struct LfRfidReadView { + View* view; +}; + +typedef struct { + IconAnimation* icon; + LfRfidReadViewMode read_mode; +} LfRfidReadViewModel; + +static void lfrfid_view_read_draw_callback(Canvas* canvas, void* _model) { + LfRfidReadViewModel* model = _model; + canvas_set_color(canvas, ColorBlack); + + canvas_draw_icon(canvas, 0, 8, &I_NFC_manual); + + canvas_set_font(canvas, FontPrimary); + + if(model->read_mode == LfRfidReadAsk) { + canvas_draw_str(canvas, 70, 16, "Reading 1/2"); + + canvas_draw_str(canvas, 77, 29, "ASK"); + canvas_draw_icon(canvas, 70, 22, &I_ButtonRight_4x7); + canvas_draw_icon_animation(canvas, 102, 21, model->icon); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 77, 43, "PSK"); + } else if(model->read_mode == LfRfidReadPsk) { + canvas_draw_str(canvas, 70, 16, "Reading 2/2"); + + canvas_draw_str(canvas, 77, 43, "PSK"); + canvas_draw_icon(canvas, 70, 36, &I_ButtonRight_4x7); + canvas_draw_icon_animation(canvas, 102, 35, model->icon); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 77, 29, "ASK"); + } else { + canvas_draw_str(canvas, 72, 16, "Reading"); + + if(model->read_mode == LfRfidReadAskOnly) { + canvas_draw_str(canvas, 77, 35, "ASK"); + } else { + canvas_draw_str(canvas, 77, 35, "PSK"); + } + canvas_draw_icon_animation(canvas, 102, 27, model->icon); + } + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 61, 56, "Don't move card"); +} + +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; + }); +} + +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; + }); +} + +LfRfidReadView* lfrfid_view_read_alloc() { + LfRfidReadView* read_view = malloc(sizeof(LfRfidReadView)); + read_view->view = view_alloc(); + view_set_context(read_view->view, read_view); + view_allocate_model(read_view->view, ViewModelTypeLocking, sizeof(LfRfidReadViewModel)); + + with_view_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; + }); + + view_set_draw_callback(read_view->view, lfrfid_view_read_draw_callback); + view_set_enter_callback(read_view->view, lfrfid_view_read_enter); + view_set_exit_callback(read_view->view, lfrfid_view_read_exit); + + return read_view; +} + +void lfrfid_view_read_free(LfRfidReadView* read_view) { + with_view_model( + read_view->view, (LfRfidReadViewModel * model) { + icon_animation_free(model->icon); + return false; + }); + + view_free(read_view->view); + free(read_view); +} + +View* lfrfid_view_read_get_view(LfRfidReadView* read_view) { + return read_view->view; +} + +void lfrfid_view_read_set_read_mode(LfRfidReadView* read_view, LfRfidReadViewMode mode) { + with_view_model( + read_view->view, (LfRfidReadViewModel * model) { + icon_animation_stop(model->icon); + icon_animation_start(model->icon); + model->read_mode = mode; + return true; + }); +} diff --git a/applications/lfrfid/views/lfrfid_view_read.h b/applications/lfrfid/views/lfrfid_view_read.h new file mode 100644 index 00000000..55bb1f23 --- /dev/null +++ b/applications/lfrfid/views/lfrfid_view_read.h @@ -0,0 +1,19 @@ +#pragma once +#include + +typedef enum { + LfRfidReadAsk, + LfRfidReadPsk, + LfRfidReadAskOnly, + LfRfidReadPskOnly +} LfRfidReadViewMode; + +typedef struct LfRfidReadView LfRfidReadView; + +LfRfidReadView* lfrfid_view_read_alloc(); + +void lfrfid_view_read_free(LfRfidReadView* read_view); + +View* lfrfid_view_read_get_view(LfRfidReadView* read_view); + +void lfrfid_view_read_set_read_mode(LfRfidReadView* read_view, LfRfidReadViewMode mode); diff --git a/applications/lfrfid_debug/lfrfid_debug.c b/applications/lfrfid_debug/lfrfid_debug.c new file mode 100644 index 00000000..63d66b68 --- /dev/null +++ b/applications/lfrfid_debug/lfrfid_debug.c @@ -0,0 +1,81 @@ +#include "lfrfid_debug_i.h" + +static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + LfRfidDebug* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool lfrfid_debug_back_event_callback(void* context) { + furi_assert(context); + LfRfidDebug* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static LfRfidDebug* lfrfid_debug_alloc() { + LfRfidDebug* app = malloc(sizeof(LfRfidDebug)); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&lfrfid_debug_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, lfrfid_debug_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, lfrfid_debug_back_event_callback); + + // Open GUI record + app->gui = furi_record_open(RECORD_GUI); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // Submenu + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, LfRfidDebugViewSubmenu, submenu_get_view(app->submenu)); + + // Tune view + app->tune_view = lfrfid_debug_view_tune_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + LfRfidDebugViewTune, + lfrfid_debug_view_tune_get_view(app->tune_view)); + + return app; +} + +static void lfrfid_debug_free(LfRfidDebug* app) { + furi_assert(app); + + // Submenu + view_dispatcher_remove_view(app->view_dispatcher, LfRfidDebugViewSubmenu); + submenu_free(app->submenu); + + // Tune view + view_dispatcher_remove_view(app->view_dispatcher, LfRfidDebugViewTune); + lfrfid_debug_view_tune_free(app->tune_view); + + // View Dispatcher + view_dispatcher_free(app->view_dispatcher); + + // Scene Manager + scene_manager_free(app->scene_manager); + + // GUI + furi_record_close(RECORD_GUI); + app->gui = NULL; + + free(app); +} + +int32_t lfrfid_debug_app(void* p) { + UNUSED(p); + LfRfidDebug* app = lfrfid_debug_alloc(); + + scene_manager_next_scene(app->scene_manager, LfRfidDebugSceneStart); + + view_dispatcher_run(app->view_dispatcher); + + lfrfid_debug_free(app); + + return 0; +} \ No newline at end of file diff --git a/applications/lfrfid_debug/lfrfid_debug_app.cpp b/applications/lfrfid_debug/lfrfid_debug_app.cpp deleted file mode 100644 index ef970e36..00000000 --- a/applications/lfrfid_debug/lfrfid_debug_app.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "lfrfid_debug_app.h" -#include "scene/lfrfid_debug_app_scene_start.h" -#include "scene/lfrfid_debug_app_scene_tune.h" - -LfRfidDebugApp::LfRfidDebugApp() - : scene_controller{this} { -} - -LfRfidDebugApp::~LfRfidDebugApp() { -} - -void LfRfidDebugApp::run() { - view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); - scene_controller.add_scene(SceneType::Start, new LfRfidDebugAppSceneStart()); - scene_controller.add_scene(SceneType::TuneScene, new LfRfidDebugAppSceneTune()); - scene_controller.process(100); -} diff --git a/applications/lfrfid_debug/lfrfid_debug_app.h b/applications/lfrfid_debug/lfrfid_debug_app.h deleted file mode 100644 index fee183ae..00000000 --- a/applications/lfrfid_debug/lfrfid_debug_app.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include -#include - -#include -#include -#include - -#include -#include "view_modules/lfrfid_view_tune_vm.h" - -class LfRfidDebugApp { -public: - enum class EventType : uint8_t { - GENERIC_EVENT_ENUM_VALUES, - MenuSelected, - }; - - enum class SceneType : uint8_t { - GENERIC_SCENE_ENUM_VALUES, - TuneScene, - }; - - class Event { - public: - union { - int32_t menu_index; - } payload; - - EventType type; - }; - - SceneController, LfRfidDebugApp> scene_controller; - ViewController view_controller; - - ~LfRfidDebugApp(); - LfRfidDebugApp(); - - void run(); -}; diff --git a/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp b/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp deleted file mode 100644 index 4551a17c..00000000 --- a/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "lfrfid_debug_app.h" - -// app enter function -extern "C" int32_t lfrfid_debug_app(void* p) { - UNUSED(p); - LfRfidDebugApp* app = new LfRfidDebugApp(); - app->run(); - delete app; - - return 0; -} diff --git a/applications/lfrfid_debug/lfrfid_debug_i.h b/applications/lfrfid_debug/lfrfid_debug_i.h new file mode 100644 index 00000000..368f1f15 --- /dev/null +++ b/applications/lfrfid_debug/lfrfid_debug_i.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +typedef struct LfRfidDebug LfRfidDebug; + +struct LfRfidDebug { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + // Common Views + Submenu* submenu; + LfRfidTuneView* tune_view; +}; + +typedef enum { + LfRfidDebugViewSubmenu, + LfRfidDebugViewTune, +} LfRfidDebugView; diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.cpp b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.cpp deleted file mode 100644 index 873e152a..00000000 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "lfrfid_debug_app_scene_start.h" - -typedef enum { - SubmenuTune, -} SubmenuIndex; - -void LfRfidDebugAppSceneStart::on_enter(LfRfidDebugApp* app, bool need_restore) { - auto submenu = app->view_controller.get(); - auto callback = cbc::obtain_connector(this, &LfRfidDebugAppSceneStart::submenu_callback); - - submenu->add_item("Tune", SubmenuTune, callback, app); - - if(need_restore) { - submenu->set_selected_item(submenu_item_selected); - } - app->view_controller.switch_to(); -} - -bool LfRfidDebugAppSceneStart::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) { - bool consumed = false; - - if(event->type == LfRfidDebugApp::EventType::MenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuTune: - app->scene_controller.switch_to_next_scene(LfRfidDebugApp::SceneType::TuneScene); - break; - } - consumed = true; - } - - return consumed; -} - -void LfRfidDebugAppSceneStart::on_exit(LfRfidDebugApp* app) { - app->view_controller.get()->clean(); -} - -void LfRfidDebugAppSceneStart::submenu_callback(void* context, uint32_t index) { - LfRfidDebugApp* app = static_cast(context); - LfRfidDebugApp::Event event; - - event.type = LfRfidDebugApp::EventType::MenuSelected; - event.payload.menu_index = index; - - app->view_controller.send_event(&event); -} diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h deleted file mode 100644 index 7fc0b07d..00000000 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../lfrfid_debug_app.h" - -class LfRfidDebugAppSceneStart : public GenericScene { -public: - void on_enter(LfRfidDebugApp* app, bool need_restore) final; - bool on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) final; - void on_exit(LfRfidDebugApp* app) final; - -private: - void submenu_callback(void* context, uint32_t index); - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h deleted file mode 100644 index 53399efc..00000000 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../lfrfid_debug_app.h" - -class LfRfidDebugAppSceneTune : public GenericScene { -public: - void on_enter(LfRfidDebugApp* app, bool need_restore) final; - bool on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) final; - void on_exit(LfRfidDebugApp* app) final; -}; diff --git a/applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c b/applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c new file mode 100644 index 00000000..2fc6706e --- /dev/null +++ b/applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c @@ -0,0 +1,44 @@ +#include "../lfrfid_debug_i.h" + +typedef enum { + SubmenuIndexTune, +} SubmenuIndex; + +static void lfrfid_debug_scene_start_submenu_callback(void* context, uint32_t index) { + LfRfidDebug* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void lfrfid_debug_scene_start_on_enter(void* context) { + LfRfidDebug* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, "Tune", SubmenuIndexTune, lfrfid_debug_scene_start_submenu_callback, app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidDebugSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewSubmenu); +} + +bool lfrfid_debug_scene_start_on_event(void* context, SceneManagerEvent event) { + LfRfidDebug* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexTune) { + scene_manager_next_scene(app->scene_manager, LfRfidDebugSceneTune); + consumed = true; + } + } + + return consumed; +} + +void lfrfid_debug_scene_start_on_exit(void* context) { + LfRfidDebug* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp b/applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c similarity index 53% rename from applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp rename to applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c index 4b627649..c7f3bf24 100644 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp +++ b/applications/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c @@ -1,4 +1,4 @@ -#include "lfrfid_debug_app_scene_tune.h" +#include "../lfrfid_debug_i.h" #include static void comparator_trigger_callback(bool level, void* comp_ctx) { @@ -6,32 +6,38 @@ static void comparator_trigger_callback(bool level, void* comp_ctx) { furi_hal_gpio_write(&gpio_ext_pa7, !level); } -void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool /* need_restore */) { - app->view_controller.switch_to(); +void lfrfid_debug_scene_tune_on_enter(void* context) { + LfRfidDebug* app = context; + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); - furi_hal_rfid_comp_set_callback(comparator_trigger_callback, this); + furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app); furi_hal_rfid_comp_start(); furi_hal_rfid_pins_read(); furi_hal_rfid_tim_read(125000, 0.5); furi_hal_rfid_tim_read_start(); + + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune); } -bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* /* event */) { +bool lfrfid_debug_scene_tune_on_event(void* context, SceneManagerEvent event) { + UNUSED(event); + + LfRfidDebug* app = context; bool consumed = false; - LfRfidViewTuneVM* tune = app->view_controller; - - if(tune->is_dirty()) { - furi_hal_rfid_set_read_period(tune->get_ARR()); - furi_hal_rfid_set_read_pulse(tune->get_CCR()); + if(lfrfid_debug_view_tune_is_dirty(app->tune_view)) { + furi_hal_rfid_set_read_period(lfrfid_debug_view_tune_get_arr(app->tune_view)); + furi_hal_rfid_set_read_pulse(lfrfid_debug_view_tune_get_ccr(app->tune_view)); } return consumed; } -void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* /* app */) { +void lfrfid_debug_scene_tune_on_exit(void* context) { + UNUSED(context); + furi_hal_rfid_comp_stop(); furi_hal_rfid_comp_set_callback(NULL, NULL); diff --git a/applications/lfrfid_debug/scenes/lfrfid_debug_scene.c b/applications/lfrfid_debug/scenes/lfrfid_debug_scene.c new file mode 100644 index 00000000..e6288e92 --- /dev/null +++ b/applications/lfrfid_debug/scenes/lfrfid_debug_scene.c @@ -0,0 +1,30 @@ +#include "lfrfid_debug_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const lfrfid_debug_on_enter_handlers[])(void*) = { +#include "lfrfid_debug_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const lfrfid_debug_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "lfrfid_debug_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const lfrfid_debug_on_exit_handlers[])(void* context) = { +#include "lfrfid_debug_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers lfrfid_debug_scene_handlers = { + .on_enter_handlers = lfrfid_debug_on_enter_handlers, + .on_event_handlers = lfrfid_debug_on_event_handlers, + .on_exit_handlers = lfrfid_debug_on_exit_handlers, + .scene_num = LfRfidDebugSceneNum, +}; diff --git a/applications/lfrfid_debug/scenes/lfrfid_debug_scene.h b/applications/lfrfid_debug/scenes/lfrfid_debug_scene.h new file mode 100644 index 00000000..8fc74f72 --- /dev/null +++ b/applications/lfrfid_debug/scenes/lfrfid_debug_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) LfRfidDebugScene##id, +typedef enum { +#include "lfrfid_debug_scene_config.h" + LfRfidDebugSceneNum, +} LfRfidDebugScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers lfrfid_debug_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "lfrfid_debug_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "lfrfid_debug_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "lfrfid_debug_scene_config.h" +#undef ADD_SCENE diff --git a/applications/lfrfid_debug/scenes/lfrfid_debug_scene_config.h b/applications/lfrfid_debug/scenes/lfrfid_debug_scene_config.h new file mode 100644 index 00000000..f3cca47b --- /dev/null +++ b/applications/lfrfid_debug/scenes/lfrfid_debug_scene_config.h @@ -0,0 +1,2 @@ +ADD_SCENE(lfrfid_debug, start, Start) +ADD_SCENE(lfrfid_debug, tune, Tune) diff --git a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp b/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp deleted file mode 100644 index 5c244b92..00000000 --- a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "lfrfid_view_tune_vm.h" -#include -#include - -struct LfRfidViewTuneVMModel { - bool dirty; - bool fine; - uint32_t ARR; - uint32_t CCR; - int pos; -}; - -void LfRfidViewTuneVM::view_draw_callback(Canvas* canvas, void* _model) { - LfRfidViewTuneVMModel* model = reinterpret_cast(_model); - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - if(model->fine) { - canvas_draw_box( - canvas, - 128 - canvas_string_width(canvas, "Fine") - 4, - 0, - canvas_string_width(canvas, "Fine") + 4, - canvas_current_font_height(canvas) + 1); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_str_aligned(canvas, 128 - 2, 2, AlignRight, AlignTop, "Fine"); - canvas_set_color(canvas, ColorBlack); - - constexpr uint8_t buffer_size = 128; - char buffer[buffer_size + 1]; - double freq = ((float)SystemCoreClock / ((float)model->ARR + 1)); - double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f; - snprintf( - buffer, - buffer_size, - "%sARR: %lu\n" - "freq = %.4f\n" - "%sCCR: %lu\n" - "duty = %.4f", - model->pos == 0 ? ">" : "", - model->ARR, - freq, - model->pos == 1 ? ">" : "", - model->CCR, - duty); - elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer); -} - -bool LfRfidViewTuneVM::view_input_callback(InputEvent* event, void* context) { - LfRfidViewTuneVM* _this = reinterpret_cast(context); - bool consumed = false; - - // Process key presses only - if(event->type == InputTypeShort || event->type == InputTypeRepeat) { - consumed = true; - - switch(event->key) { - case InputKeyLeft: - _this->button_left(); - break; - case InputKeyRight: - _this->button_right(); - break; - case InputKeyUp: - _this->button_up(); - break; - case InputKeyDown: - _this->button_down(); - break; - case InputKeyOk: - _this->button_ok(); - break; - default: - consumed = false; - break; - } - } - - return consumed; -} - -void LfRfidViewTuneVM::button_up() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - if(model->pos > 0) model->pos--; - return true; - }); -} - -void LfRfidViewTuneVM::button_down() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - if(model->pos < 1) model->pos++; - return true; - }); -} - -void LfRfidViewTuneVM::button_left() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - if(model->pos == 0) { - if(model->fine) { - model->ARR -= 1; - } else { - model->ARR -= 10; - } - } else if(model->pos == 1) { - if(model->fine) { - model->CCR -= 1; - } else { - model->CCR -= 10; - } - } - - model->dirty = true; - return true; - }); -} - -void LfRfidViewTuneVM::button_right() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - if(model->pos == 0) { - if(model->fine) { - model->ARR += 1; - } else { - model->ARR += 10; - } - } else if(model->pos == 1) { - if(model->fine) { - model->CCR += 1; - } else { - model->CCR += 10; - } - } - - model->dirty = true; - return true; - }); -} - -void LfRfidViewTuneVM::button_ok() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - model->fine = !model->fine; - return true; - }); -} - -LfRfidViewTuneVM::LfRfidViewTuneVM() { - view = view_alloc(); - view_set_context(view, this); - view_allocate_model(view, ViewModelTypeLocking, sizeof(LfRfidViewTuneVMModel)); - - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - model->dirty = true; - model->fine = false; - model->ARR = 511; - model->CCR = 255; - model->pos = 0; - return true; - }); - - view_set_draw_callback( - view, cbc::obtain_connector(this, &LfRfidViewTuneVM::view_draw_callback)); - view_set_input_callback( - view, cbc::obtain_connector(this, &LfRfidViewTuneVM::view_input_callback)); -} - -LfRfidViewTuneVM::~LfRfidViewTuneVM() { - view_free(view); -} - -View* LfRfidViewTuneVM::get_view() { - return view; -} - -void LfRfidViewTuneVM::clean() { - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - model->dirty = true; - model->fine = false; - model->ARR = 511; - model->CCR = 255; - model->pos = 0; - return true; - }); -} - -bool LfRfidViewTuneVM::is_dirty() { - bool result; - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - result = model->dirty; - model->dirty = false; - return false; - }); - - return result; -} - -uint32_t LfRfidViewTuneVM::get_ARR() { - uint32_t result; - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - result = model->ARR; - return false; - }); - - return result; -} - -uint32_t LfRfidViewTuneVM::get_CCR() { - uint32_t result; - with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { - result = model->CCR; - return false; - }); - - return result; -} diff --git a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.h b/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.h deleted file mode 100644 index 7fb18565..00000000 --- a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include -#include - -class LfRfidViewTuneVM : public GenericViewModule { -public: - LfRfidViewTuneVM(); - ~LfRfidViewTuneVM() final; - View* get_view() final; - void clean() final; - - bool is_dirty(); - uint32_t get_ARR(); - uint32_t get_CCR(); - -private: - View* view; - void view_draw_callback(Canvas* canvas, void* _model); - bool view_input_callback(InputEvent* event, void* context); - - void button_up(); - void button_down(); - void button_left(); - void button_right(); - void button_ok(); -}; diff --git a/applications/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/lfrfid_debug/views/lfrfid_debug_view_tune.c new file mode 100644 index 00000000..38fe3603 --- /dev/null +++ b/applications/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -0,0 +1,229 @@ +#include "lfrfid_debug_view_tune.h" +#include + +#define TEMP_STR_LEN 128 + +struct LfRfidTuneView { + View* view; +}; + +typedef struct { + bool dirty; + bool fine; + uint32_t ARR; + uint32_t CCR; + int pos; +} LfRfidTuneViewModel; + +static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) { + LfRfidTuneViewModel* model = _model; + canvas_set_color(canvas, ColorBlack); + + if(model->fine) { + canvas_draw_box( + canvas, + 128 - canvas_string_width(canvas, "Fine") - 4, + 0, + canvas_string_width(canvas, "Fine") + 4, + canvas_current_font_height(canvas) + 1); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_str_aligned(canvas, 128 - 2, 2, AlignRight, AlignTop, "Fine"); + canvas_set_color(canvas, ColorBlack); + + char buffer[TEMP_STR_LEN + 1]; + double freq = ((float)SystemCoreClock / ((float)model->ARR + 1)); + double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f; + snprintf( + buffer, + TEMP_STR_LEN, + "%sARR: %lu\n" + "freq = %.4f\n" + "%sCCR: %lu\n" + "duty = %.4f", + model->pos == 0 ? ">" : "", + model->ARR, + freq, + model->pos == 1 ? ">" : "", + model->CCR, + duty); + elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer); +} + +static void lfrfid_debug_view_tune_button_up(LfRfidTuneView* tune_view) { + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + if(model->pos > 0) model->pos--; + return true; + }); +} + +static void lfrfid_debug_view_tune_button_down(LfRfidTuneView* tune_view) { + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + if(model->pos < 1) model->pos++; + return true; + }); +} + +static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) { + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + if(model->pos == 0) { + if(model->fine) { + model->ARR -= 1; + } else { + model->ARR -= 10; + } + } else if(model->pos == 1) { + if(model->fine) { + model->CCR -= 1; + } else { + model->CCR -= 10; + } + } + + model->dirty = true; + return true; + }); +} + +static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) { + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + if(model->pos == 0) { + if(model->fine) { + model->ARR += 1; + } else { + model->ARR += 10; + } + } else if(model->pos == 1) { + if(model->fine) { + model->CCR += 1; + } else { + model->CCR += 10; + } + } + + model->dirty = true; + return 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; + }); +} + +static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* context) { + LfRfidTuneView* tune_view = context; + bool consumed = false; + + // Process key presses only + if(event->type == InputTypeShort || event->type == InputTypeRepeat) { + consumed = true; + + switch(event->key) { + case InputKeyLeft: + lfrfid_debug_view_tune_button_left(tune_view); + break; + case InputKeyRight: + lfrfid_debug_view_tune_button_right(tune_view); + break; + case InputKeyUp: + lfrfid_debug_view_tune_button_up(tune_view); + break; + case InputKeyDown: + lfrfid_debug_view_tune_button_down(tune_view); + break; + case InputKeyOk: + lfrfid_debug_view_tune_button_ok(tune_view); + break; + default: + consumed = false; + break; + } + } + + return consumed; +} + +LfRfidTuneView* lfrfid_debug_view_tune_alloc() { + LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView)); + tune_view->view = view_alloc(); + view_set_context(tune_view->view, tune_view); + view_allocate_model(tune_view->view, ViewModelTypeLocking, sizeof(LfRfidTuneViewModel)); + + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + model->dirty = true; + model->fine = false; + model->ARR = 511; + model->CCR = 255; + model->pos = 0; + return 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); + + return tune_view; +} + +void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view) { + view_free(tune_view->view); + free(tune_view); +} + +View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view) { + return tune_view->view; +} + +void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view) { + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + model->dirty = true; + model->fine = false; + model->ARR = 511; + model->CCR = 255; + model->pos = 0; + return true; + }); +} + +bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) { + bool result = false; + with_view_model( + tune_view->view, (LfRfidTuneViewModel * model) { + result = model->dirty; + model->dirty = false; + return false; + }); + + return result; +} + +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; + }); + + return result; +} + +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; + }); + + return result; +} diff --git a/applications/lfrfid_debug/views/lfrfid_debug_view_tune.h b/applications/lfrfid_debug/views/lfrfid_debug_view_tune.h new file mode 100644 index 00000000..fd6d0b1f --- /dev/null +++ b/applications/lfrfid_debug/views/lfrfid_debug_view_tune.h @@ -0,0 +1,18 @@ +#pragma once +#include + +typedef struct LfRfidTuneView LfRfidTuneView; + +LfRfidTuneView* lfrfid_debug_view_tune_alloc(); + +void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view); + +View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view); + +void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view); + +bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view); + +uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view); + +uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view); diff --git a/assets/icons/Common/Round_loader_8x8/frame_01.png b/assets/icons/Common/Round_loader_8x8/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..a5dc239d85e8a02c44786475069a9b683bda5aba GIT binary patch literal 7324 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 TxH*)9T8IUCC+Rm6uZaH!P{_=Z literal 0 HcmV?d00001 diff --git a/assets/icons/Common/Round_loader_8x8/frame_02.png b/assets/icons/Common/Round_loader_8x8/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..162d8a8f42a9492ace7717662ec13d525ee90f95 GIT binary patch literal 3606 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 W0R@kPHAx&eU}I@-QEKLS@qYkZZBH2h literal 0 HcmV?d00001 diff --git a/assets/icons/Common/Round_loader_8x8/frame_03.png b/assets/icons/Common/Round_loader_8x8/frame_03.png new file mode 100644 index 0000000000000000000000000000000000000000..5483e47345687cbb9bdca56f6c9a946ebed1b542 GIT binary patch literal 3603 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 MS=gADnz>*8AMz7TL;wH) literal 0 HcmV?d00001 diff --git a/assets/icons/Common/Round_loader_8x8/frame_rate b/assets/icons/Common/Round_loader_8x8/frame_rate new file mode 100644 index 00000000..d8263ee9 --- /dev/null +++ b/assets/icons/Common/Round_loader_8x8/frame_rate @@ -0,0 +1 @@ +2 \ No newline at end of file