From 5171a6ad145a4042cc86e9f953594174b0dfc637 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Fri, 6 May 2022 19:48:39 +0300 Subject: [PATCH] [FL-2514] Port iButton application to C (#1198) * Initial C iButton app setup * Add more scenes * Add even more scenes * Add even more scenes again * More scenes... * Add key info scene * Add delete success scene * Use scene state to store internal data * Add parameter parsing * Add emulate scene * Add write scene * Add write success scene * Add Read scene * Add read success scene * Add exit confirm scene * Add retry confirm scene * Add CRC error scene * Add not key scene * Add read key menu scene * Rename some scenes * Refactor conditionals * Remove unneeded custom events * Remove the old iButton app * Correct formatting * Remove rogue comments and function prototypes * iButton: cleanup merge artifacts and fix warnings Co-authored-by: Aleksandr Kutuzov --- applications/ibutton/ibutton.c | 349 ++++++++++++++++++ applications/ibutton/ibutton.cpp | 10 - applications/ibutton/ibutton.h | 3 + applications/ibutton/ibutton_app.cpp | 342 ----------------- applications/ibutton/ibutton_app.h | 144 -------- applications/ibutton/ibutton_custom_event.h | 12 + applications/ibutton/ibutton_event.h | 36 -- applications/ibutton/ibutton_i.h | 86 +++++ applications/ibutton/ibutton_view_manager.cpp | 140 ------- applications/ibutton/ibutton_view_manager.h | 51 --- .../ibutton/scene/ibutton_scene_add_type.cpp | 66 ---- .../ibutton/scene/ibutton_scene_add_type.h | 12 - .../ibutton/scene/ibutton_scene_add_value.cpp | 53 --- .../ibutton/scene/ibutton_scene_add_value.h | 13 - .../scene/ibutton_scene_delete_confirm.cpp | 86 ----- .../scene/ibutton_scene_delete_confirm.h | 9 - .../scene/ibutton_scene_delete_success.cpp | 47 --- .../scene/ibutton_scene_delete_success.h | 9 - .../ibutton/scene/ibutton_scene_emulate.h | 9 - .../scene/ibutton_scene_exit_confirm.cpp | 51 --- .../scene/ibutton_scene_exit_confirm.h | 9 - .../ibutton/scene/ibutton_scene_generic.h | 14 - .../ibutton/scene/ibutton_scene_info.cpp | 58 --- .../ibutton/scene/ibutton_scene_info.h | 9 - .../ibutton/scene/ibutton_scene_read.cpp | 72 ---- .../ibutton/scene/ibutton_scene_read.h | 9 - .../scene/ibutton_scene_read_crc_error.cpp | 74 ---- .../scene/ibutton_scene_read_crc_error.h | 9 - .../scene/ibutton_scene_read_key_menu.cpp | 65 ---- .../scene/ibutton_scene_read_key_menu.h | 12 - .../ibutton_scene_read_not_key_error.cpp | 74 ---- .../scene/ibutton_scene_read_not_key_error.h | 9 - .../scene/ibutton_scene_read_success.cpp | 86 ----- .../scene/ibutton_scene_read_success.h | 9 - .../scene/ibutton_scene_retry_confirm.cpp | 51 --- .../scene/ibutton_scene_retry_confirm.h | 9 - .../ibutton/scene/ibutton_scene_save_name.cpp | 70 ---- .../ibutton/scene/ibutton_scene_save_name.h | 9 - .../scene/ibutton_scene_save_success.cpp | 52 --- .../scene/ibutton_scene_save_success.h | 9 - .../scene/ibutton_scene_saved_key_menu.cpp | 73 ---- .../scene/ibutton_scene_saved_key_menu.h | 12 - .../scene/ibutton_scene_select_key.cpp | 18 - .../ibutton/scene/ibutton_scene_select_key.h | 9 - .../ibutton/scene/ibutton_scene_start.cpp | 60 --- .../ibutton/scene/ibutton_scene_start.h | 12 - .../ibutton/scene/ibutton_scene_write.cpp | 111 ------ .../ibutton/scene/ibutton_scene_write.h | 12 - .../scene/ibutton_scene_write_success.cpp | 52 --- .../scene/ibutton_scene_write_success.h | 9 - applications/ibutton/scenes/ibutton_scene.c | 30 ++ applications/ibutton/scenes/ibutton_scene.h | 29 ++ .../ibutton/scenes/ibutton_scene_add_type.c | 58 +++ .../ibutton/scenes/ibutton_scene_add_value.c | 57 +++ .../ibutton/scenes/ibutton_scene_config.h | 20 + .../scenes/ibutton_scene_delete_confirm.c | 91 +++++ .../scenes/ibutton_scene_delete_success.c | 48 +++ .../ibutton_scene_emulate.c} | 66 ++-- .../scenes/ibutton_scene_exit_confirm.c | 51 +++ .../ibutton/scenes/ibutton_scene_info.c | 61 +++ .../ibutton/scenes/ibutton_scene_read.c | 72 ++++ .../scenes/ibutton_scene_read_crc_error.c | 71 ++++ .../scenes/ibutton_scene_read_key_menu.c | 61 +++ .../scenes/ibutton_scene_read_not_key_error.c | 72 ++++ .../scenes/ibutton_scene_read_success.c | 87 +++++ .../scenes/ibutton_scene_retry_confirm.c | 51 +++ .../ibutton/scenes/ibutton_scene_save_name.c | 68 ++++ .../scenes/ibutton_scene_save_success.c | 52 +++ .../scenes/ibutton_scene_saved_key_menu.c | 75 ++++ .../ibutton/scenes/ibutton_scene_select_key.c | 22 ++ .../ibutton/scenes/ibutton_scene_start.c | 51 +++ .../ibutton/scenes/ibutton_scene_write.c | 121 ++++++ .../scenes/ibutton_scene_write_success.c | 52 +++ 73 files changed, 1785 insertions(+), 2186 deletions(-) create mode 100644 applications/ibutton/ibutton.c delete mode 100644 applications/ibutton/ibutton.cpp create mode 100644 applications/ibutton/ibutton.h delete mode 100644 applications/ibutton/ibutton_app.cpp delete mode 100644 applications/ibutton/ibutton_app.h create mode 100644 applications/ibutton/ibutton_custom_event.h delete mode 100644 applications/ibutton/ibutton_event.h create mode 100644 applications/ibutton/ibutton_i.h delete mode 100755 applications/ibutton/ibutton_view_manager.cpp delete mode 100644 applications/ibutton/ibutton_view_manager.h delete mode 100644 applications/ibutton/scene/ibutton_scene_add_type.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_add_type.h delete mode 100755 applications/ibutton/scene/ibutton_scene_add_value.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_add_value.h delete mode 100755 applications/ibutton/scene/ibutton_scene_delete_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_emulate.h delete mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_generic.h delete mode 100755 applications/ibutton/scene/ibutton_scene_info.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_info.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_crc_error.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_crc_error.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_key_menu.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_key_menu.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_not_key_error.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_save_name.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_save_name.h delete mode 100644 applications/ibutton/scene/ibutton_scene_save_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_save_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_saved_key_menu.h delete mode 100644 applications/ibutton/scene/ibutton_scene_select_key.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_select_key.h delete mode 100644 applications/ibutton/scene/ibutton_scene_start.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_start.h delete mode 100644 applications/ibutton/scene/ibutton_scene_write.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_write.h delete mode 100644 applications/ibutton/scene/ibutton_scene_write_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_write_success.h create mode 100644 applications/ibutton/scenes/ibutton_scene.c create mode 100644 applications/ibutton/scenes/ibutton_scene.h create mode 100644 applications/ibutton/scenes/ibutton_scene_add_type.c create mode 100644 applications/ibutton/scenes/ibutton_scene_add_value.c create mode 100644 applications/ibutton/scenes/ibutton_scene_config.h create mode 100644 applications/ibutton/scenes/ibutton_scene_delete_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_delete_success.c rename applications/ibutton/{scene/ibutton_scene_emulate.cpp => scenes/ibutton_scene_emulate.c} (50%) create mode 100644 applications/ibutton/scenes/ibutton_scene_exit_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_info.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_crc_error.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_key_menu.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_not_key_error.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_success.c create mode 100644 applications/ibutton/scenes/ibutton_scene_retry_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_save_name.c create mode 100644 applications/ibutton/scenes/ibutton_scene_save_success.c create mode 100644 applications/ibutton/scenes/ibutton_scene_saved_key_menu.c create mode 100644 applications/ibutton/scenes/ibutton_scene_select_key.c create mode 100644 applications/ibutton/scenes/ibutton_scene_start.c create mode 100644 applications/ibutton/scenes/ibutton_scene_write.c create mode 100644 applications/ibutton/scenes/ibutton_scene_write_success.c diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c new file mode 100644 index 00000000..a38f077f --- /dev/null +++ b/applications/ibutton/ibutton.c @@ -0,0 +1,349 @@ +#include "ibutton.h" +#include "ibutton_i.h" +#include "ibutton/scenes/ibutton_scene.h" + +#include +#include + +static const NotificationSequence* ibutton_notification_sequences[] = { + &sequence_error, + &sequence_success, + &sequence_blink_cyan_10, + &sequence_blink_magenta_10, + &sequence_blink_yellow_10, + &sequence_set_red_255, + &sequence_reset_red, + &sequence_set_green_255, + &sequence_reset_green, +}; + +static void ibutton_make_app_folder(iButton* ibutton) { + if(!storage_simply_mkdir(ibutton->storage, IBUTTON_APP_FOLDER)) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot create\napp folder"); + } +} + +static bool ibutton_load_key_data(iButton* ibutton, string_t key_path) { + FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); + bool result = false; + string_t data; + string_init(data); + + do { + if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; + + // header + uint32_t version; + if(!flipper_format_read_header(file, data, &version)) break; + if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; + if(version != 1) break; + + // key type + iButtonKeyType type; + if(!flipper_format_read_string(file, "Key type", data)) break; + if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; + + // key data + uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; + if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type))) + break; + + ibutton_key_set_type(ibutton->key, type); + ibutton_key_set_data(ibutton->key, key_data, IBUTTON_KEY_DATA_SIZE); + + result = true; + } while(false); + + flipper_format_free(file); + string_clear(data); + + if(!result) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file"); + } + + return result; +} + +bool ibutton_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + iButton* ibutton = context; + return scene_manager_handle_custom_event(ibutton->scene_manager, event); +} + +bool ibutton_back_event_callback(void* context) { + furi_assert(context); + iButton* ibutton = context; + return scene_manager_handle_back_event(ibutton->scene_manager); +} + +void ibutton_tick_event_callback(void* context) { + furi_assert(context); + iButton* ibutton = context; + scene_manager_handle_tick_event(ibutton->scene_manager); +} + +iButton* ibutton_alloc() { + iButton* ibutton = malloc(sizeof(iButton)); + + ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton); + + ibutton->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(ibutton->view_dispatcher); + view_dispatcher_set_event_callback_context(ibutton->view_dispatcher, ibutton); + view_dispatcher_set_custom_event_callback( + ibutton->view_dispatcher, ibutton_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + ibutton->view_dispatcher, ibutton_back_event_callback); + view_dispatcher_set_tick_event_callback( + ibutton->view_dispatcher, ibutton_tick_event_callback, 100); + + ibutton->gui = furi_record_open("gui"); + view_dispatcher_attach_to_gui( + ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen); + + ibutton->storage = furi_record_open("storage"); + ibutton->dialogs = furi_record_open("dialogs"); + ibutton->notifications = furi_record_open("notification"); + + ibutton->key = ibutton_key_alloc(); + ibutton->key_worker = ibutton_worker_alloc(); + ibutton_worker_start_thread(ibutton->key_worker); + + ibutton->submenu = submenu_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewSubmenu, submenu_get_view(ibutton->submenu)); + + ibutton->byte_input = byte_input_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewByteInput, byte_input_get_view(ibutton->byte_input)); + + ibutton->text_input = text_input_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewTextInput, text_input_get_view(ibutton->text_input)); + + ibutton->popup = popup_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewPopup, popup_get_view(ibutton->popup)); + + ibutton->widget = widget_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewWidget, widget_get_view(ibutton->widget)); + + ibutton->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewDialogEx, dialog_ex_get_view(ibutton->dialog_ex)); + + return ibutton; +} + +void ibutton_free(iButton* ibutton) { + furi_assert(ibutton); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewDialogEx); + dialog_ex_free(ibutton->dialog_ex); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewWidget); + widget_free(ibutton->widget); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewPopup); + popup_free(ibutton->popup); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewTextInput); + text_input_free(ibutton->text_input); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewByteInput); + byte_input_free(ibutton->byte_input); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewSubmenu); + submenu_free(ibutton->submenu); + + view_dispatcher_free(ibutton->view_dispatcher); + scene_manager_free(ibutton->scene_manager); + + furi_record_close("storage"); + ibutton->storage = NULL; + + furi_record_close("notification"); + ibutton->notifications = NULL; + + furi_record_close("dialogs"); + ibutton->dialogs = NULL; + + furi_record_close("gui"); + ibutton->gui = NULL; + + ibutton_worker_stop_thread(ibutton->key_worker); + ibutton_worker_free(ibutton->key_worker); + ibutton_key_free(ibutton->key); + + free(ibutton); +} + +bool ibutton_file_select(iButton* ibutton) { + bool success = dialog_file_select_show( + ibutton->dialogs, + IBUTTON_APP_FOLDER, + IBUTTON_APP_EXTENSION, + ibutton->file_name, + IBUTTON_FILE_NAME_SIZE, + ibutton_key_get_name_p(ibutton->key)); + + if(success) { + string_t key_str; + string_init_printf( + key_str, "%s/%s%s", IBUTTON_APP_FOLDER, ibutton->file_name, IBUTTON_APP_EXTENSION); + success = ibutton_load_key_data(ibutton, key_str); + + if(success) { + ibutton_key_set_name(ibutton->key, ibutton->file_name); + } + + string_clear(key_str); + } + + return success; +} + +bool ibutton_load_key(iButton* ibutton, const char* key_name) { + string_t key_path; + string_init_set_str(key_path, key_name); + + const bool success = ibutton_load_key_data(ibutton, key_path); + + if(success) { + path_extract_filename_no_ext(key_name, key_path); + ibutton_key_set_name(ibutton->key, string_get_cstr(key_path)); + } + + string_clear(key_path); + return success; +} + +bool ibutton_save_key(iButton* ibutton, const char* key_name) { + // Create ibutton directory if necessary + ibutton_make_app_folder(ibutton); + + FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); + iButtonKey* key = ibutton->key; + + string_t key_file_name; + bool result = false; + string_init(key_file_name); + + do { + // First remove key if it was saved (we rename the key) + if(!ibutton_delete_key(ibutton)) break; + + // Save the key + ibutton_key_set_name(key, key_name); + + // Set full file name, for new key + string_printf( + key_file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(key), + IBUTTON_APP_EXTENSION); + + // Open file for write + if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; + + // Write header + if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break; + + // Write key type + if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom")) + break; + const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key)); + if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break; + + // Write data + if(!flipper_format_write_comment_cstr( + file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8")) + break; + + if(!flipper_format_write_hex( + file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key))) + break; + result = true; + + } while(false); + + flipper_format_free(file); + + string_clear(key_file_name); + + if(!result) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot save\nkey file"); + } + + return result; +} + +bool ibutton_delete_key(iButton* ibutton) { + string_t file_name; + bool result = false; + + string_init_printf( + file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(ibutton->key), + IBUTTON_APP_EXTENSION); + result = storage_simply_remove(ibutton->storage, string_get_cstr(file_name)); + string_clear(file_name); + + return result; +} + +void ibutton_text_store_set(iButton* ibutton, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE, text, args); + + va_end(args); +} + +void ibutton_text_store_clear(iButton* ibutton) { + memset(ibutton->text_store, 0, IBUTTON_TEXT_STORE_SIZE); +} + +void ibutton_switch_to_previous_scene_one_of( + iButton* ibutton, + const uint32_t* scene_ids, + size_t scene_ids_size) { + furi_assert(scene_ids_size); + SceneManager* scene_manager = ibutton->scene_manager; + + for(size_t i = 0; i < scene_ids_size; ++i) { + const uint32_t scene_id = scene_ids[i]; + if(scene_manager_has_previous_scene(scene_manager, scene_id)) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, scene_id); + return; + } + } +} + +void ibutton_notification_message(iButton* ibutton, uint32_t message) { + furi_assert(message < sizeof(ibutton_notification_sequences) / sizeof(NotificationSequence*)); + notification_message(ibutton->notifications, ibutton_notification_sequences[message]); +} + +int32_t ibutton_app(void* p) { + iButton* ibutton = ibutton_alloc(); + + ibutton_make_app_folder(ibutton); + + if(p && ibutton_load_key(ibutton, (const char*)p)) { + // TODO: Display an error if the key from p could not be loaded + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); + } + + view_dispatcher_run(ibutton->view_dispatcher); + + ibutton_free(ibutton); + return 0; +} diff --git a/applications/ibutton/ibutton.cpp b/applications/ibutton/ibutton.cpp deleted file mode 100644 index aae0d317..00000000 --- a/applications/ibutton/ibutton.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "ibutton_app.h" - -// app enter function -extern "C" int32_t ibutton_app(void* p) { - iButtonApp* app = new iButtonApp(); - app->run(p); - delete app; - - return 255; -} diff --git a/applications/ibutton/ibutton.h b/applications/ibutton/ibutton.h new file mode 100644 index 00000000..56d6e3b6 --- /dev/null +++ b/applications/ibutton/ibutton.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct iButton iButton; diff --git a/applications/ibutton/ibutton_app.cpp b/applications/ibutton/ibutton_app.cpp deleted file mode 100644 index 43eb3692..00000000 --- a/applications/ibutton/ibutton_app.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "ibutton_app.h" -#include -#include -#include -#include -#include - -const char* iButtonApp::app_folder = "/any/ibutton"; -const char* iButtonApp::app_extension = ".ibtn"; -const char* iButtonApp::app_filetype = "Flipper iButton key"; - -void iButtonApp::run(void* args) { - iButtonEvent event; - bool consumed; - bool exit = false; - - make_app_folder(); - - if(args && load_key((const char*)args)) { - current_scene = Scene::SceneEmulate; - } - - scenes[current_scene]->on_enter(this); - - while(!exit) { - view.receive_event(&event); - - consumed = scenes[current_scene]->on_event(this, &event); - - if(!consumed) { - if(event.type == iButtonEvent::Type::EventTypeBack) { - exit = switch_to_previous_scene(); - } - } - }; - - scenes[current_scene]->on_exit(this); -} - -iButtonApp::iButtonApp() - : notification{"notification"} - , storage{"storage"} - , dialogs{"dialogs"} { - key = ibutton_key_alloc(); - key_worker = ibutton_worker_alloc(); - ibutton_worker_start_thread(key_worker); -} - -iButtonApp::~iButtonApp() { - for(std::map::iterator it = scenes.begin(); it != scenes.end(); ++it) { - delete it->second; - } - scenes.clear(); - - ibutton_worker_stop_thread(key_worker); - ibutton_worker_free(key_worker); - ibutton_key_free(key); -} - -iButtonAppViewManager* iButtonApp::get_view_manager() { - return &view; -} - -void iButtonApp::switch_to_next_scene(Scene next_scene) { - previous_scenes_list.push_front(current_scene); - - if(next_scene != Scene::SceneExit) { - scenes[current_scene]->on_exit(this); - current_scene = next_scene; - scenes[current_scene]->on_enter(this); - } -} - -void iButtonApp::search_and_switch_to_previous_scene(std::initializer_list scenes_list) { - Scene previous_scene = Scene::SceneStart; - bool scene_found = false; - - while(!scene_found) { - previous_scene = get_previous_scene(); - for(Scene element : scenes_list) { - if(previous_scene == element || previous_scene == Scene::SceneStart) { - scene_found = true; - break; - } - } - } - - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); -} - -bool iButtonApp::switch_to_previous_scene(uint8_t count) { - Scene previous_scene = Scene::SceneStart; - - for(uint8_t i = 0; i < count; i++) { - previous_scene = get_previous_scene(); - if(previous_scene == Scene::SceneExit) break; - } - - if(previous_scene == Scene::SceneExit) { - return true; - } else { - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); - return false; - } -} - -iButtonApp::Scene iButtonApp::get_previous_scene() { - Scene scene = previous_scenes_list.front(); - previous_scenes_list.pop_front(); - return scene; -} - -iButtonWorker* iButtonApp::get_key_worker() { - return key_worker; -} - -iButtonKey* iButtonApp::get_key() { - return key; -} - -char* iButtonApp::get_file_name() { - return file_name; -} - -uint8_t iButtonApp::get_file_name_size() { - return file_name_size; -} - -void iButtonApp::notify_read() { - notification_message(notification, &sequence_blink_cyan_10); -} - -void iButtonApp::notify_emulate() { - notification_message(notification, &sequence_blink_magenta_10); -} - -void iButtonApp::notify_yellow_blink() { - notification_message(notification, &sequence_blink_yellow_10); -} - -void iButtonApp::notify_error() { - notification_message(notification, &sequence_error); -} - -void iButtonApp::notify_success() { - notification_message(notification, &sequence_success); -} - -void iButtonApp::notify_green_on() { - notification_message_block(notification, &sequence_set_green_255); -} - -void iButtonApp::notify_green_off() { - notification_message(notification, &sequence_reset_green); -} - -void iButtonApp::notify_red_on() { - notification_message_block(notification, &sequence_set_red_255); -} - -void iButtonApp::notify_red_off() { - notification_message(notification, &sequence_reset_red); -} - -void iButtonApp::set_text_store(const char* text...) { - va_list args; - va_start(args, text); - - vsnprintf(text_store, text_store_size, text, args); - - va_end(args); -} - -char* iButtonApp::get_text_store() { - return text_store; -} - -uint8_t iButtonApp::get_text_store_size() { - return text_store_size; -} - -// file managment -bool iButtonApp::save_key(const char* key_name) { - // Create ibutton directory if necessary - make_app_folder(); - - FlipperFormat* file = flipper_format_file_alloc(storage); - string_t key_file_name; - bool result = false; - string_init(key_file_name); - - do { - // First remove key if it was saved (we rename the key) - if(!delete_key()) break; - - // Save the key - ibutton_key_set_name(key, key_name); - - // Set full file name, for new key - string_printf( - key_file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); - - // Open file for write - if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; - - // Write header - if(!flipper_format_write_header_cstr(file, iButtonApp::app_filetype, 1)) break; - - // Write key type - if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom")) - break; - const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key)); - if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break; - - // Write data - if(!flipper_format_write_comment_cstr( - file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8")) - break; - - if(!flipper_format_write_hex( - file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key))) - break; - result = true; - - } while(false); - - flipper_format_free(file); - - string_clear(key_file_name); - - if(!result) { - dialog_message_show_storage_error(dialogs, "Cannot save\nkey file"); - } - - return result; -} - -bool iButtonApp::load_key_data(string_t key_path) { - FlipperFormat* file = flipper_format_file_alloc(storage); - bool result = false; - string_t data; - string_init(data); - - do { - if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; - - // header - uint32_t version; - if(!flipper_format_read_header(file, data, &version)) break; - if(string_cmp_str(data, iButtonApp::app_filetype) != 0) break; - if(version != 1) break; - - // key type - iButtonKeyType type; - if(!flipper_format_read_string(file, "Key type", data)) break; - if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; - - // key data - uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; - if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type))) - break; - - ibutton_key_set_type(key, type); - ibutton_key_set_data(key, key_data, IBUTTON_KEY_DATA_SIZE); - - result = true; - } while(false); - - flipper_format_free(file); - string_clear(data); - - if(!result) { - dialog_message_show_storage_error(dialogs, "Cannot load\nkey file"); - } - - return result; -} - -bool iButtonApp::load_key(const char* key_name) { - bool result = false; - string_t key_path; - - string_init_set_str(key_path, key_name); - - result = load_key_data(key_path); - if(result) { - path_extract_filename_no_ext(key_name, key_path); - ibutton_key_set_name(key, string_get_cstr(key_path)); - } - string_clear(key_path); - return result; -} - -bool iButtonApp::load_key() { - bool result = false; - - // Input events and views are managed by file_select - bool res = dialog_file_select_show( - dialogs, - app_folder, - app_extension, - get_file_name(), - get_file_name_size(), - ibutton_key_get_name_p(key)); - - if(res) { - string_t key_str; - - // Get key file path - string_init_printf(key_str, "%s/%s%s", app_folder, get_file_name(), app_extension); - - result = load_key_data(key_str); - if(result) { - ibutton_key_set_name(key, get_file_name()); - } - string_clear(key_str); - } - - return result; -} - -bool iButtonApp::delete_key() { - string_t file_name; - bool result = false; - - string_init_printf( - file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); - result = storage_simply_remove(storage, string_get_cstr(file_name)); - string_clear(file_name); - - return result; -} - -void iButtonApp::make_app_folder() { - if(!storage_simply_mkdir(storage, app_folder)) { - dialog_message_show_storage_error(dialogs, "Cannot create\napp folder"); - } -} diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h deleted file mode 100644 index 08af3857..00000000 --- a/applications/ibutton/ibutton_app.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once -#include -#include - -#include "ibutton_view_manager.h" -#include "scene/ibutton_scene_generic.h" -#include "scene/ibutton_scene_start.h" -#include "scene/ibutton_scene_read.h" -#include "scene/ibutton_scene_read_crc_error.h" -#include "scene/ibutton_scene_read_not_key_error.h" -#include "scene/ibutton_scene_read_success.h" -#include "scene/ibutton_scene_retry_confirm.h" -#include "scene/ibutton_scene_exit_confirm.h" -#include "scene/ibutton_scene_read_key_menu.h" -#include "scene/ibutton_scene_write.h" -#include "scene/ibutton_scene_write_success.h" -#include "scene/ibutton_scene_saved_key_menu.h" -#include "scene/ibutton_scene_delete_confirm.h" -#include "scene/ibutton_scene_delete_success.h" -#include "scene/ibutton_scene_emulate.h" -#include "scene/ibutton_scene_save_name.h" -#include "scene/ibutton_scene_save_success.h" -#include "scene/ibutton_scene_info.h" -#include "scene/ibutton_scene_select_key.h" -#include "scene/ibutton_scene_add_type.h" -#include "scene/ibutton_scene_add_value.h" -#include -#include -#include -#include -#include - -class iButtonApp { -public: - void run(void* args); - - iButtonApp(); - ~iButtonApp(); - - enum class Scene : uint8_t { - SceneExit, - SceneStart, - SceneRead, - SceneReadNotKeyError, - SceneReadCRCError, - SceneReadSuccess, - SceneRetryConfirm, - SceneExitConfirm, - SceneReadKeyMenu, - SceneWrite, - SceneWriteSuccess, - SceneEmulate, - SceneSavedKeyMenu, - SceneDeleteConfirm, - SceneDeleteSuccess, - SceneSaveName, - SceneSaveSuccess, - SceneInfo, - SceneSelectKey, - SceneAddType, - SceneAddValue, - }; - - static const char* app_folder; - static const char* app_extension; - static const char* app_filetype; - - iButtonAppViewManager* get_view_manager(); - void switch_to_next_scene(Scene index); - void search_and_switch_to_previous_scene(std::initializer_list scenes_list); - bool switch_to_previous_scene(uint8_t count = 1); - Scene get_previous_scene(); - - const GpioPin* get_ibutton_pin(); - iButtonWorker* get_key_worker(); - iButtonKey* get_key(); - - void notify_read(); - void notify_yellow_blink(); - void notify_emulate(); - - void notify_error(); - void notify_success(); - void notify_green_on(); - void notify_green_off(); - void notify_red_on(); - void notify_red_off(); - - void set_text_store(const char* text...); - char* get_text_store(); - uint8_t get_text_store_size(); - - char* get_file_name(); - uint8_t get_file_name_size(); - - bool save_key(const char* key_name); - bool load_key(); - bool load_key(const char* key_name); - bool delete_key(); - -private: - std::list previous_scenes_list = {Scene::SceneExit}; - Scene current_scene = Scene::SceneStart; - iButtonAppViewManager view; - - std::map scenes = { - {Scene::SceneStart, new iButtonSceneStart()}, - {Scene::SceneRead, new iButtonSceneRead()}, - {Scene::SceneReadCRCError, new iButtonSceneReadCRCError()}, - {Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()}, - {Scene::SceneReadSuccess, new iButtonSceneReadSuccess()}, - {Scene::SceneRetryConfirm, new iButtonSceneRetryConfirm()}, - {Scene::SceneExitConfirm, new iButtonSceneExitConfirm()}, - {Scene::SceneReadKeyMenu, new iButtonSceneReadKeyMenu()}, - {Scene::SceneWrite, new iButtonSceneWrite()}, - {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, - {Scene::SceneEmulate, new iButtonSceneEmulate()}, - {Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()}, - {Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()}, - {Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()}, - {Scene::SceneSaveName, new iButtonSceneSaveName()}, - {Scene::SceneSaveSuccess, new iButtonSceneSaveSuccess()}, - {Scene::SceneInfo, new iButtonSceneInfo()}, - {Scene::SceneSelectKey, new iButtonSceneSelectKey()}, - {Scene::SceneAddType, new iButtonSceneAddType()}, - {Scene::SceneAddValue, new iButtonSceneAddValue()}, - }; - - iButtonWorker* key_worker; - iButtonKey* key; - - RecordController notification; - RecordController storage; - RecordController dialogs; - - static const uint8_t file_name_size = 100; - char file_name[file_name_size]; - - static const uint8_t text_store_size = 128; - char text_store[text_store_size + 1]; - - bool load_key_data(string_t key_path); - void make_app_folder(); -}; diff --git a/applications/ibutton/ibutton_custom_event.h b/applications/ibutton/ibutton_custom_event.h new file mode 100644 index 00000000..2be42d66 --- /dev/null +++ b/applications/ibutton/ibutton_custom_event.h @@ -0,0 +1,12 @@ +#pragma once + +enum iButtonCustomEvent { + // Reserve first 100 events for button types and indexes, starting from 0 + iButtonCustomEventReserved = 100, + + iButtonCustomEventBack, + iButtonCustomEventTextEditResult, + iButtonCustomEventByteEditResult, + iButtonCustomEventWorkerEmulated, + iButtonCustomEventWorkerRead, +}; diff --git a/applications/ibutton/ibutton_event.h b/applications/ibutton/ibutton_event.h deleted file mode 100644 index 8b1775c1..00000000 --- a/applications/ibutton/ibutton_event.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include -#include -#include - -class iButtonApp; - -class iButtonEvent { -public: - // events enum - enum class Type : uint8_t { - EventTypeTick, - EventTypeBack, - EventTypeMenuSelected, - EventTypeDialogResult, - EventTypeTextEditResult, - EventTypeByteEditResult, - EventTypeWidgetButtonResult, - EventTypeWorkerEmulated, - EventTypeWorkerRead, - EventTypeWorkerWrite, - }; - - // payload - union { - uint32_t dummy; - uint32_t menu_index; - DialogExResult dialog_result; - GuiButtonType widget_button_result; - iButtonWorkerWriteResult worker_write_result; - } payload; - - // event type - Type type; -}; diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h new file mode 100644 index 00000000..36857fd6 --- /dev/null +++ b/applications/ibutton/ibutton_i.h @@ -0,0 +1,86 @@ +#pragma once + +#include "ibutton.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ibutton_custom_event.h" +#include "scenes/ibutton_scene.h" + +#define IBUTTON_FILE_NAME_SIZE 100 +#define IBUTTON_TEXT_STORE_SIZE 128 + +#define IBUTTON_APP_FOLDER "/any/ibutton" +#define IBUTTON_APP_EXTENSION ".ibtn" +#define IBUTTON_APP_FILE_TYPE "Flipper iButton key" + +struct iButton { + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + Gui* gui; + Storage* storage; + DialogsApp* dialogs; + NotificationApp* notifications; + + iButtonWorker* key_worker; + iButtonKey* key; + + char file_name[IBUTTON_FILE_NAME_SIZE]; + char text_store[IBUTTON_TEXT_STORE_SIZE + 1]; + + Submenu* submenu; + ByteInput* byte_input; + TextInput* text_input; + Popup* popup; + Widget* widget; + DialogEx* dialog_ex; +}; + +typedef enum { + iButtonViewSubmenu, + iButtonViewByteInput, + iButtonViewTextInput, + iButtonViewPopup, + iButtonViewWidget, + iButtonViewDialogEx, +} iButtonView; + +typedef enum { + iButtonNotificationMessageError, + iButtonNotificationMessageSuccess, + iButtonNotificationMessageRead, + iButtonNotificationMessageEmulate, + iButtonNotificationMessageYellowBlink, + iButtonNotificationMessageRedOn, + iButtonNotificationMessageRedOff, + iButtonNotificationMessageGreenOn, + iButtonNotificationMessageGreenOff, +} iButtonNotificationMessage; + +bool ibutton_file_select(iButton* ibutton); +bool ibutton_load_key(iButton* ibutton, const char* key_name); +bool ibutton_save_key(iButton* ibutton, const char* key_name); +bool ibutton_delete_key(iButton* ibutton); +void ibutton_text_store_set(iButton* ibutton, const char* text, ...); +void ibutton_text_store_clear(iButton* ibutton); +void ibutton_switch_to_previous_scene_one_of( + iButton* ibutton, + const uint32_t* scene_ids, + size_t scene_ids_size); +void ibutton_notification_message(iButton* ibutton, uint32_t message); diff --git a/applications/ibutton/ibutton_view_manager.cpp b/applications/ibutton/ibutton_view_manager.cpp deleted file mode 100755 index 5a2c94f1..00000000 --- a/applications/ibutton/ibutton_view_manager.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "ibutton_view_manager.h" -#include "ibutton_event.h" -#include - -iButtonAppViewManager::iButtonAppViewManager() { - event_queue = osMessageQueueNew(10, sizeof(iButtonEvent), NULL); - - view_dispatcher = view_dispatcher_alloc(); - auto callback = cbc::obtain_connector(this, &iButtonAppViewManager::previous_view_callback); - - dialog_ex = dialog_ex_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewDialogEx), - dialog_ex_get_view(dialog_ex)); - - submenu = submenu_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewSubmenu), - submenu_get_view(submenu)); - - text_input = text_input_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewTextInput), - text_input_get_view(text_input)); - - byte_input = byte_input_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewByteInput), - byte_input_get_view(byte_input)); - - popup = popup_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewPopup), - popup_get_view(popup)); - - widget = widget_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewWidget), - widget_get_view(widget)); - - gui = static_cast(furi_record_open("gui")); - view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - //TODO think about that method, seems unsafe and over-engineered - view_set_previous_callback(dialog_ex_get_view(dialog_ex), callback); - view_set_previous_callback(submenu_get_view(submenu), callback); - view_set_previous_callback(text_input_get_view(text_input), callback); - view_set_previous_callback(byte_input_get_view(byte_input), callback); - view_set_previous_callback(popup_get_view(popup), callback); - view_set_previous_callback(widget_get_view(widget), callback); -} - -iButtonAppViewManager::~iButtonAppViewManager() { - // remove views - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewDialogEx)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewSubmenu)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewTextInput)); - view_dispatcher_remove_view( - view_dispatcher, static_cast(iButtonAppViewManager::Type::iButtonAppViewPopup)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewByteInput)); - view_dispatcher_remove_view( - view_dispatcher, static_cast(iButtonAppViewManager::Type::iButtonAppViewWidget)); - - // free view modules - popup_free(popup); - text_input_free(text_input); - byte_input_free(byte_input); - submenu_free(submenu); - dialog_ex_free(dialog_ex); - widget_free(widget); - - // free dispatcher - view_dispatcher_free(view_dispatcher); - - // free event queue - osMessageQueueDelete(event_queue); -} - -void iButtonAppViewManager::switch_to(Type type) { - view_dispatcher_switch_to_view(view_dispatcher, static_cast(type)); -} - -Submenu* iButtonAppViewManager::get_submenu() { - return submenu; -} - -Popup* iButtonAppViewManager::get_popup() { - return popup; -} - -DialogEx* iButtonAppViewManager::get_dialog_ex() { - return dialog_ex; -} - -TextInput* iButtonAppViewManager::get_text_input() { - return text_input; -} - -ByteInput* iButtonAppViewManager::get_byte_input() { - return byte_input; -} - -Widget* iButtonAppViewManager::get_widget() { - return widget; -} - -void iButtonAppViewManager::receive_event(iButtonEvent* event) { - if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { - event->type = iButtonEvent::Type::EventTypeTick; - } -} - -void iButtonAppViewManager::send_event(iButtonEvent* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); - furi_check(result == osOK); -} - -uint32_t iButtonAppViewManager::previous_view_callback(void*) { - if(event_queue != NULL) { - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - send_event(&event); - } - - return VIEW_IGNORE; -} diff --git a/applications/ibutton/ibutton_view_manager.h b/applications/ibutton/ibutton_view_manager.h deleted file mode 100644 index 336ba6e2..00000000 --- a/applications/ibutton/ibutton_view_manager.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include "ibutton_event.h" - -class iButtonAppViewManager { -public: - enum class Type : uint8_t { - iButtonAppViewTextInput, - iButtonAppViewByteInput, - iButtonAppViewSubmenu, - iButtonAppViewDialogEx, - iButtonAppViewPopup, - iButtonAppViewWidget, - }; - - osMessageQueueId_t event_queue; - - iButtonAppViewManager(); - ~iButtonAppViewManager(); - - void switch_to(Type type); - - Submenu* get_submenu(); - Popup* get_popup(); - DialogEx* get_dialog_ex(); - TextInput* get_text_input(); - ByteInput* get_byte_input(); - Widget* get_widget(); - - void receive_event(iButtonEvent* event); - void send_event(iButtonEvent* event); - -private: - ViewDispatcher* view_dispatcher; - DialogEx* dialog_ex; - Submenu* submenu; - TextInput* text_input; - ByteInput* byte_input; - Popup* popup; - Widget* widget; - Gui* gui; - - uint32_t previous_view_callback(void* context); -}; diff --git a/applications/ibutton/scene/ibutton_scene_add_type.cpp b/applications/ibutton/scene/ibutton_scene_add_type.cpp deleted file mode 100644 index c9537768..00000000 --- a/applications/ibutton/scene/ibutton_scene_add_type.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "ibutton_scene_add_type.h" -#include "../ibutton_app.h" -#include - -typedef enum { - SubmenuIndexCyfral, - SubmenuIndexDallas, - SubmenuIndexMetakom, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneAddType::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, submenu_callback, app); - submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, submenu_callback, app); - submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneAddType::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - iButtonKey* key = app->get_key(); - - switch(event->payload.menu_index) { - case SubmenuIndexCyfral: - ibutton_key_set_type(key, iButtonKeyCyfral); - break; - case SubmenuIndexDallas: - ibutton_key_set_type(key, iButtonKeyDS1990); - break; - case SubmenuIndexMetakom: - ibutton_key_set_type(key, iButtonKeyMetakom); - break; - } - ibutton_key_set_name(key, ""); - ibutton_key_clear_data(key); - app->switch_to_next_scene(iButtonApp::Scene::SceneAddValue); - consumed = true; - } - - return consumed; -} - -void iButtonSceneAddType::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_add_type.h b/applications/ibutton/scene/ibutton_scene_add_type.h deleted file mode 100644 index 6a3d07e5..00000000 --- a/applications/ibutton/scene/ibutton_scene_add_type.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneAddType : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_add_value.cpp b/applications/ibutton/scene/ibutton_scene_add_value.cpp deleted file mode 100755 index d0108ae5..00000000 --- a/applications/ibutton/scene/ibutton_scene_add_value.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "ibutton_scene_add_value.h" -#include "../ibutton_app.h" -#include - -static void byte_input_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeByteEditResult; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneAddValue::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - ByteInput* byte_input = view_manager->get_byte_input(); - iButtonKey* key = app->get_key(); - - memcpy(this->new_key_data, ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)); - - byte_input_set_result_callback( - byte_input, - byte_input_callback, - NULL, - app, - this->new_key_data, - ibutton_key_get_data_size(key)); - - byte_input_set_header_text(byte_input, "Enter the key"); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewByteInput); -} - -bool iButtonSceneAddValue::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeByteEditResult) { - ibutton_key_set_data(app->get_key(), this->new_key_data, IBUTTON_KEY_DATA_SIZE); - DOLPHIN_DEED(DolphinDeedIbuttonAdd); - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); - consumed = true; - } - - return consumed; -} - -void iButtonSceneAddValue::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - ByteInput* byte_input = view_manager->get_byte_input(); - - byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(byte_input, {0}); -} diff --git a/applications/ibutton/scene/ibutton_scene_add_value.h b/applications/ibutton/scene/ibutton_scene_add_value.h deleted file mode 100644 index 7a734160..00000000 --- a/applications/ibutton/scene/ibutton_scene_add_value.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" -#include - -class iButtonSceneAddValue : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint8_t new_key_data[IBUTTON_KEY_DATA_SIZE] = {}; -}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp deleted file mode 100755 index 8e782e33..00000000 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "ibutton_scene_delete_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneDeleteConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - app->set_text_store("\e#Delete %s?\e#", ibutton_key_get_name_p(key)); - widget_add_text_box_element( - widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store(), false); - widget_add_button_element(widget, GuiButtonTypeLeft, "Cancel", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Delete", widget_callback, app); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); - break; - case iButtonKeyCyfral: - app->set_text_store("%02X %02X", key_data[0], key_data[1]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); - break; - case iButtonKeyMetakom: - app->set_text_store( - "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); - break; - } - widget_add_string_element( - widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, app->get_text_store()); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneDeleteConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeRight) { - if(app->delete_key()) { - app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteSuccess); - } - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneDeleteConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - app->set_text_store(""); - - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.h b/applications/ibutton/scene/ibutton_scene_delete_confirm.h deleted file mode 100644 index cacbb7fe..00000000 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneDeleteConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.cpp b/applications/ibutton/scene/ibutton_scene_delete_success.cpp deleted file mode 100644 index ba138161..00000000 --- a/applications/ibutton/scene/ibutton_scene_delete_success.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "ibutton_scene_delete_success.h" -#include "../ibutton_app.h" - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneDeleteSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); -} - -bool iButtonSceneDeleteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneSelectKey}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.h b/applications/ibutton/scene/ibutton_scene_delete_success.h deleted file mode 100644 index 1fbe5230..00000000 --- a/applications/ibutton/scene/ibutton_scene_delete_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneDeleteSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_emulate.h b/applications/ibutton/scene/ibutton_scene_emulate.h deleted file mode 100644 index 61107b94..00000000 --- a/applications/ibutton/scene/ibutton_scene_emulate.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneEmulate : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp b/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp deleted file mode 100644 index 2c9fe94c..00000000 --- a/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "ibutton_scene_exit_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneExitConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Stay", widget_callback, app); - widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); - widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneExitConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeLeft) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); - } else if(event->payload.widget_button_result == GuiButtonTypeRight) { - app->switch_to_previous_scene(); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - consumed = true; - } - - return consumed; -} - -void iButtonSceneExitConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.h b/applications/ibutton/scene/ibutton_scene_exit_confirm.h deleted file mode 100644 index f621a59a..00000000 --- a/applications/ibutton/scene/ibutton_scene_exit_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneExitConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_generic.h b/applications/ibutton/scene/ibutton_scene_generic.h deleted file mode 100644 index 0e2444b5..00000000 --- a/applications/ibutton/scene/ibutton_scene_generic.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "../ibutton_event.h" - -class iButtonApp; - -class iButtonScene { -public: - virtual void on_enter(iButtonApp* app) = 0; - virtual bool on_event(iButtonApp* app, iButtonEvent* event) = 0; - virtual void on_exit(iButtonApp* app) = 0; - virtual ~iButtonScene(){}; - -private: -}; diff --git a/applications/ibutton/scene/ibutton_scene_info.cpp b/applications/ibutton/scene/ibutton_scene_info.cpp deleted file mode 100755 index dd779789..00000000 --- a/applications/ibutton/scene/ibutton_scene_info.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "ibutton_scene_info.h" -#include "../ibutton_app.h" - -void iButtonSceneInfo::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - app->set_text_store("%s", ibutton_key_get_name_p(key)); - widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, app->get_text_store(), false); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); - break; - case iButtonKeyMetakom: - app->set_text_store( - "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); - break; - case iButtonKeyCyfral: - app->set_text_store("%02X %02X", key_data[0], key_data[1]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); - break; - } - widget_add_string_element( - widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, app->get_text_store()); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneInfo::on_event(iButtonApp*, iButtonEvent*) { - return false; -} - -void iButtonSceneInfo::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - app->set_text_store(""); - - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_info.h b/applications/ibutton/scene/ibutton_scene_info.h deleted file mode 100644 index bbfb0c60..00000000 --- a/applications/ibutton/scene/ibutton_scene_info.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneInfo : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read.cpp b/applications/ibutton/scene/ibutton_scene_read.cpp deleted file mode 100644 index 1cfdbfe3..00000000 --- a/applications/ibutton/scene/ibutton_scene_read.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "ibutton_scene_read.h" -#include "../ibutton_app.h" -#include - -static void read_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event = { - .payload = {.dummy = 0}, - .type = iButtonEvent::Type::EventTypeWorkerRead, - }; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneRead::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); - iButtonWorker* worker = app->get_key_worker(); - DOLPHIN_DEED(DolphinDeedIbuttonRead); - - popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); - popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - ibutton_key_set_name(key, ""); - - ibutton_worker_read_set_callback(worker, read_callback, app); - ibutton_worker_read_start(worker, key); -} - -bool iButtonSceneRead::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWorkerRead) { - consumed = true; - - iButtonKey* key = app->get_key(); - bool success = false; - if(ibutton_key_get_type(key) == iButtonKeyDS1990) { - if(!ibutton_key_dallas_crc_is_valid(key)) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadCRCError); - } else if(!ibutton_key_dallas_is_1990_key(key)) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadNotKeyError); - } else { - success = true; - } - } else { - success = true; - } - if(success) { - app->notify_success(); - app->notify_green_on(); - DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); - app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); - } - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - consumed = true; - app->notify_read(); - } - - return consumed; -} - -void iButtonSceneRead::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_read.h b/applications/ibutton/scene/ibutton_scene_read.h deleted file mode 100644 index 56547778..00000000 --- a/applications/ibutton/scene/ibutton_scene_read.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneRead : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp deleted file mode 100644 index d9d3ffd5..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "ibutton_scene_read_crc_error.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); - - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X\nExpected CRC: %X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7], - maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); - - dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - app->notify_error(); - app->notify_red_on(); -} - -bool iButtonSceneReadCRCError::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadCRCError::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - - app->notify_red_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.h b/applications/ibutton/scene/ibutton_scene_read_crc_error.h deleted file mode 100644 index db72d068..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadCRCError : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp deleted file mode 100644 index 215eb76f..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "ibutton_scene_read_key_menu.h" -#include "../ibutton_app.h" - -typedef enum { - SubmenuIndexSave, - SubmenuIndexEmulate, - SubmenuIndexWrite, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadKeyMenu::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Save", SubmenuIndexSave, submenu_callback, app); - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); - if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); - } - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneReadKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexWrite: - app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); - break; - case SubmenuIndexEmulate: - app->switch_to_next_scene(iButtonApp::Scene::SceneEmulate); - break; - case SubmenuIndexSave: - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); - break; - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - app->switch_to_previous_scene(); - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadKeyMenu::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_key_menu.h b/applications/ibutton/scene/ibutton_scene_read_key_menu.h deleted file mode 100644 index d68a4d1d..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_key_menu.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadKeyMenu : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp deleted file mode 100644 index 58ea853c..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "ibutton_scene_read_not_key_error.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); - - app->set_text_store( - "THIS IS NOT A KEY\n%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7], - maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); - - dialog_ex_set_header(dialog_ex, "ERROR:", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - app->notify_error(); - app->notify_red_on(); -} - -bool iButtonSceneReadNotKeyError::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadNotKeyError::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - - app->notify_red_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h deleted file mode 100644 index 30d20033..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadNotKeyError : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_success.cpp b/applications/ibutton/scene/ibutton_scene_read_success.cpp deleted file mode 100644 index c4523904..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_success.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "ibutton_scene_read_success.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "Dallas\n%02X %02X %02X %02X\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - break; - case iButtonKeyCyfral: - app->set_text_store("Cyfral\n%02X %02X", key_data[0], key_data[1]); - break; - case iButtonKeyMetakom: - app->set_text_store( - "Metakom\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - break; - } - - dialog_ex_set_text(dialog_ex, app->get_text_store(), 95, 30, AlignCenter, AlignCenter); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); -} - -bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_next_scene(iButtonApp::Scene::SceneRetryConfirm); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - app->switch_to_next_scene(iButtonApp::Scene::SceneExitConfirm); - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadSuccess::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_right_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - dialog_ex_set_icon(dialog_ex, 0, 0, NULL); - - app->notify_green_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_success.h b/applications/ibutton/scene/ibutton_scene_read_success.h deleted file mode 100644 index bf9003c2..00000000 --- a/applications/ibutton/scene/ibutton_scene_read_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp b/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp deleted file mode 100644 index aa3483b3..00000000 --- a/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "ibutton_scene_retry_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneRetryConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Stay", 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_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneRetryConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeLeft) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneRead}); - } else if(event->payload.widget_button_result == GuiButtonTypeRight) { - app->switch_to_previous_scene(); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - consumed = true; - } - - return consumed; -} - -void iButtonSceneRetryConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.h b/applications/ibutton/scene/ibutton_scene_retry_confirm.h deleted file mode 100644 index 0fa71ad1..00000000 --- a/applications/ibutton/scene/ibutton_scene_retry_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneRetryConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_save_name.cpp b/applications/ibutton/scene/ibutton_scene_save_name.cpp deleted file mode 100644 index 71eee148..00000000 --- a/applications/ibutton/scene/ibutton_scene_save_name.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ibutton_scene_save_name.h" -#include "../ibutton_app.h" -#include - -static void text_input_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeTextEditResult; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSaveName::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - TextInput* text_input = view_manager->get_text_input(); - - const char* key_name = ibutton_key_get_name_p(app->get_key()); - bool key_name_empty = !strcmp(key_name, ""); - - if(key_name_empty) { - set_random_name(app->get_text_store(), app->get_text_store_size()); - } else { - app->set_text_store("%s", key_name); - } - - text_input_set_header_text(text_input, "Name the key"); - text_input_set_result_callback( - text_input, - text_input_callback, - app, - app->get_text_store(), - IBUTTON_KEY_NAME_SIZE, - key_name_empty); - - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(app->app_folder, app->app_extension, key_name); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewTextInput); -} - -bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeTextEditResult) { - if(app->save_key(app->get_text_store())) { - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveSuccess); - } else { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, - iButtonApp::Scene::SceneSavedKeyMenu, - iButtonApp::Scene::SceneAddType}); - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneSaveName::on_exit(iButtonApp* app) { - TextInput* text_input = app->get_view_manager()->get_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/ibutton/scene/ibutton_scene_save_name.h b/applications/ibutton/scene/ibutton_scene_save_name.h deleted file mode 100644 index 2d7f102e..00000000 --- a/applications/ibutton/scene/ibutton_scene_save_name.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSaveName : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_save_success.cpp b/applications/ibutton/scene/ibutton_scene_save_success.cpp deleted file mode 100644 index 92c0e695..00000000 --- a/applications/ibutton/scene/ibutton_scene_save_success.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "ibutton_scene_save_success.h" -#include "../ibutton_app.h" -#include - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSaveSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - DOLPHIN_DEED(DolphinDeedIbuttonSave); - - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); -} - -bool iButtonSceneSaveSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, - iButtonApp::Scene::SceneSavedKeyMenu, - iButtonApp::Scene::SceneAddType}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_save_success.h b/applications/ibutton/scene/ibutton_scene_save_success.h deleted file mode 100644 index 14c7412d..00000000 --- a/applications/ibutton/scene/ibutton_scene_save_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSaveSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp deleted file mode 100644 index d9d042d9..00000000 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "ibutton_scene_saved_key_menu.h" -#include "../ibutton_app.h" -#include - -typedef enum { - SubmenuIndexEmulate, - SubmenuIndexWrite, - SubmenuIndexEdit, - SubmenuIndexDelete, - SubmenuIndexInfo, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSavedKeyMenu::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); - if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); - } - submenu_add_item(submenu, "Edit", SubmenuIndexEdit, submenu_callback, app); - submenu_add_item(submenu, "Delete", SubmenuIndexDelete, submenu_callback, app); - submenu_add_item(submenu, "Info", SubmenuIndexInfo, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneSavedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexWrite: - app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); - break; - case SubmenuIndexEmulate: - app->switch_to_next_scene(iButtonApp::Scene::SceneEmulate); - break; - case SubmenuIndexEdit: - app->switch_to_next_scene(iButtonApp::Scene::SceneAddValue); - break; - case SubmenuIndexDelete: - app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteConfirm); - break; - case SubmenuIndexInfo: - app->switch_to_next_scene(iButtonApp::Scene::SceneInfo); - break; - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneSavedKeyMenu::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h deleted file mode 100644 index 08809779..00000000 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSavedKeyMenu : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_select_key.cpp b/applications/ibutton/scene/ibutton_scene_select_key.cpp deleted file mode 100644 index 6a1246a4..00000000 --- a/applications/ibutton/scene/ibutton_scene_select_key.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ibutton_scene_select_key.h" -#include "../ibutton_app.h" - -void iButtonSceneSelectKey::on_enter(iButtonApp* app) { - // Process file_select return - if(app->load_key()) { - app->switch_to_next_scene(iButtonApp::Scene::SceneSavedKeyMenu); - } else { - app->switch_to_previous_scene(); - } -} - -bool iButtonSceneSelectKey::on_event(iButtonApp*, iButtonEvent*) { - return false; -} - -void iButtonSceneSelectKey::on_exit(iButtonApp*) { -} diff --git a/applications/ibutton/scene/ibutton_scene_select_key.h b/applications/ibutton/scene/ibutton_scene_select_key.h deleted file mode 100644 index d6819909..00000000 --- a/applications/ibutton/scene/ibutton_scene_select_key.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSelectKey : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_start.cpp b/applications/ibutton/scene/ibutton_scene_start.cpp deleted file mode 100644 index f7465459..00000000 --- a/applications/ibutton/scene/ibutton_scene_start.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "ibutton_scene_start.h" -#include "../ibutton_app.h" - -typedef enum { - SubmenuIndexRead, - SubmenuIndexSaved, - SubmenuIndexAdd, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneStart::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Read", SubmenuIndexRead, submenu_callback, app); - submenu_add_item(submenu, "Saved", SubmenuIndexSaved, submenu_callback, app); - submenu_add_item(submenu, "Add Manually", SubmenuIndexAdd, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneStart::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexRead: - app->switch_to_next_scene(iButtonApp::Scene::SceneRead); - break; - case SubmenuIndexSaved: - app->switch_to_next_scene(iButtonApp::Scene::SceneSelectKey); - break; - case SubmenuIndexAdd: - app->switch_to_next_scene(iButtonApp::Scene::SceneAddType); - break; - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneStart::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_start.h b/applications/ibutton/scene/ibutton_scene_start.h deleted file mode 100644 index 28ef28d3..00000000 --- a/applications/ibutton/scene/ibutton_scene_start.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneStart : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_write.cpp b/applications/ibutton/scene/ibutton_scene_write.cpp deleted file mode 100644 index d4f84e11..00000000 --- a/applications/ibutton/scene/ibutton_scene_write.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "ibutton_scene_write.h" -#include "../ibutton_app.h" - -static void ibutton_worker_write_cb(void* context, iButtonWorkerWriteResult result) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeWorkerWrite; - event.payload.worker_write_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneWrite::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); - iButtonWorker* worker = app->get_key_worker(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - const char* key_name = ibutton_key_get_name_p(key); - uint8_t line_count = 2; - - // check that stored key has name - if(strcmp(key_name, "") != 0) { - app->set_text_store("writing\n%s", key_name); - line_count = 2; - } else { - // if not, show key data - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - line_count = 3; - break; - case iButtonKeyCyfral: - app->set_text_store("writing\n%02X %02X", key_data[0], key_data[1]); - line_count = 2; - break; - case iButtonKeyMetakom: - app->set_text_store( - "writing\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - line_count = 2; - break; - } - } - - switch(line_count) { - case 3: - popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 22, AlignCenter, AlignTop); - break; - - default: - popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 28, AlignCenter, AlignTop); - break; - } - - popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - - blink_yellow = false; - ibutton_worker_write_set_callback(worker, ibutton_worker_write_cb, app); - ibutton_worker_write_start(worker, key); -} - -bool iButtonSceneWrite::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWorkerWrite) { - consumed = true; - - switch(event->payload.worker_write_result) { - case iButtonWorkerWriteOK: - case iButtonWorkerWriteSameKey: - app->switch_to_next_scene(iButtonApp::Scene::SceneWriteSuccess); - break; - case iButtonWorkerWriteNoDetect: - blink_yellow = false; - break; - case iButtonWorkerWriteCannotWrite: - blink_yellow = true; - break; - } - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - if(blink_yellow) { - app->notify_yellow_blink(); - } else { - app->notify_emulate(); - } - } - - return consumed; -} - -void iButtonSceneWrite::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_write.h b/applications/ibutton/scene/ibutton_scene_write.h deleted file mode 100644 index 8b52473a..00000000 --- a/applications/ibutton/scene/ibutton_scene_write.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneWrite : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - bool blink_yellow; -}; diff --git a/applications/ibutton/scene/ibutton_scene_write_success.cpp b/applications/ibutton/scene/ibutton_scene_write_success.cpp deleted file mode 100644 index 3f27c672..00000000 --- a/applications/ibutton/scene/ibutton_scene_write_success.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "ibutton_scene_write_success.h" -#include "../ibutton_app.h" - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); - app->notify_green_off(); -} - -void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - - popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); - popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - - app->notify_success(); - app->notify_green_on(); -} - -bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, iButtonApp::Scene::SceneStart}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_write_success.h b/applications/ibutton/scene/ibutton_scene_write_success.h deleted file mode 100644 index 99680c7d..00000000 --- a/applications/ibutton/scene/ibutton_scene_write_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneWriteSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scenes/ibutton_scene.c b/applications/ibutton/scenes/ibutton_scene.c new file mode 100644 index 00000000..c36a0eb5 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene.c @@ -0,0 +1,30 @@ +#include "ibutton_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const ibutton_on_enter_handlers[])(void*) = { +#include "ibutton_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 ibutton_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "ibutton_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 ibutton_on_exit_handlers[])(void* context) = { +#include "ibutton_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers ibutton_scene_handlers = { + .on_enter_handlers = ibutton_on_enter_handlers, + .on_event_handlers = ibutton_on_event_handlers, + .on_exit_handlers = ibutton_on_exit_handlers, + .scene_num = iButtonSceneNum, +}; diff --git a/applications/ibutton/scenes/ibutton_scene.h b/applications/ibutton/scenes/ibutton_scene.h new file mode 100644 index 00000000..60d2353e --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) iButtonScene##id, +typedef enum { +#include "ibutton_scene_config.h" + iButtonSceneNum, +} iButtonScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers ibutton_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "ibutton_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 "ibutton_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 "ibutton_scene_config.h" +#undef ADD_SCENE diff --git a/applications/ibutton/scenes/ibutton_scene_add_type.c b/applications/ibutton/scenes/ibutton_scene_add_type.c new file mode 100644 index 00000000..db129295 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_add_type.c @@ -0,0 +1,58 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexCyfral, + SubmenuIndexDallas, + SubmenuIndexMetakom, +}; + +void ibutton_scene_add_type_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_add_type_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Cyfral", SubmenuIndexCyfral, ibutton_scene_add_type_submenu_callback, ibutton); + submenu_add_item( + submenu, "Dallas", SubmenuIndexDallas, ibutton_scene_add_type_submenu_callback, ibutton); + submenu_add_item( + submenu, "Metakom", SubmenuIndexMetakom, ibutton_scene_add_type_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexCyfral); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + iButtonKey* key = ibutton->key; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexCyfral) { + ibutton_key_set_type(key, iButtonKeyCyfral); + } else if(event.event == SubmenuIndexDallas) { + ibutton_key_set_type(key, iButtonKeyDS1990); + } else if(event.event == SubmenuIndexMetakom) { + ibutton_key_set_type(key, iButtonKeyMetakom); + } else { + furi_crash("Unknown key type"); + } + + ibutton_key_set_name(key, ""); + ibutton_key_clear_data(key); + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); + } + + return consumed; +} + +void ibutton_scene_add_type_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_add_value.c b/applications/ibutton/scenes/ibutton_scene_add_value.c new file mode 100644 index 00000000..b3ec11a5 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_add_value.c @@ -0,0 +1,57 @@ +#include "../ibutton_i.h" + +#include + +void ibutton_scene_add_type_byte_input_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventByteEditResult); +} + +void ibutton_scene_add_value_on_enter(void* context) { + iButton* ibutton = context; + iButtonKey* key = ibutton->key; + uint8_t* new_key_data = malloc(IBUTTON_KEY_DATA_SIZE); + + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneAddValue, (uint32_t)new_key_data); + memcpy(new_key_data, ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)); + + byte_input_set_result_callback( + ibutton->byte_input, + ibutton_scene_add_type_byte_input_callback, + NULL, + ibutton, + new_key_data, + ibutton_key_get_data_size(key)); + + byte_input_set_header_text(ibutton->byte_input, "Enter the key"); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewByteInput); +} + +bool ibutton_scene_add_value_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + uint8_t* new_key_data = + (uint8_t*)scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddValue); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventByteEditResult) { + ibutton_key_set_data(ibutton->key, new_key_data, IBUTTON_KEY_DATA_SIZE); + DOLPHIN_DEED(DolphinDeedIbuttonAdd); + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); + } + } + + return consumed; +} + +void ibutton_scene_add_value_on_exit(void* context) { + iButton* ibutton = context; + uint8_t* new_key_data = + (uint8_t*)scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddValue); + + byte_input_set_result_callback(ibutton->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(ibutton->byte_input, NULL); + free(new_key_data); +} diff --git a/applications/ibutton/scenes/ibutton_scene_config.h b/applications/ibutton/scenes/ibutton_scene_config.h new file mode 100644 index 00000000..d30b43be --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_config.h @@ -0,0 +1,20 @@ +ADD_SCENE(ibutton, start, Start) +ADD_SCENE(ibutton, emulate, Emulate) +ADD_SCENE(ibutton, write, Write) +ADD_SCENE(ibutton, write_success, WriteSuccess) +ADD_SCENE(ibutton, info, Info) +ADD_SCENE(ibutton, read, Read) +ADD_SCENE(ibutton, read_key_menu, ReadKeyMenu) +ADD_SCENE(ibutton, read_success, ReadSuccess) +ADD_SCENE(ibutton, read_crc_error, ReadCRCError) +ADD_SCENE(ibutton, read_not_key_error, ReadNotKeyError) +ADD_SCENE(ibutton, select_key, SelectKey) +ADD_SCENE(ibutton, add_type, AddType) +ADD_SCENE(ibutton, add_value, AddValue) +ADD_SCENE(ibutton, saved_key_menu, SavedKeyMenu) +ADD_SCENE(ibutton, save_name, SaveName) +ADD_SCENE(ibutton, save_success, SaveSuccess) +ADD_SCENE(ibutton, delete_confirm, DeleteConfirm) +ADD_SCENE(ibutton, delete_success, DeleteSuccess) +ADD_SCENE(ibutton, retry_confirm, RetryConfirm) +ADD_SCENE(ibutton, exit_confirm, ExitConfirm) diff --git a/applications/ibutton/scenes/ibutton_scene_delete_confirm.c b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c new file mode 100644 index 00000000..73ea97cc --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c @@ -0,0 +1,91 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_delete_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_delete_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", ibutton_key_get_name_p(key)); + widget_add_text_box_element( + widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, false); + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", ibutton_scene_delete_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "Delete", + ibutton_scene_delete_confirm_widget_callback, + ibutton); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + break; + + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + break; + + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + break; + } + widget_add_string_element( + widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeRight) { + if(ibutton_delete_key(ibutton)) { + scene_manager_next_scene(scene_manager, iButtonSceneDeleteSuccess); + } + //TODO: What if the key could not be deleted? + } else if(event.event == GuiButtonTypeLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_delete_confirm_on_exit(void* context) { + iButton* ibutton = context; + ibutton_text_store_clear(ibutton); + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_delete_success.c b/applications/ibutton/scenes/ibutton_scene_delete_success.c new file mode 100644 index 00000000..8b7d9dfc --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_delete_success.c @@ -0,0 +1,48 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_delete_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); +} + +void ibutton_scene_delete_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); + popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); + + popup_set_callback(popup, ibutton_scene_delete_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); +} + +bool ibutton_scene_delete_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + scene_manager_search_and_switch_to_previous_scene( + ibutton->scene_manager, iButtonSceneSelectKey); + } + } + + return consumed; +} + +void ibutton_scene_delete_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +} diff --git a/applications/ibutton/scene/ibutton_scene_emulate.cpp b/applications/ibutton/scenes/ibutton_scene_emulate.c similarity index 50% rename from applications/ibutton/scene/ibutton_scene_emulate.cpp rename to applications/ibutton/scenes/ibutton_scene_emulate.c index c00535f8..8ffe73b6 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.cpp +++ b/applications/ibutton/scenes/ibutton_scene_emulate.c @@ -1,37 +1,35 @@ -#include "ibutton_scene_emulate.h" -#include "../ibutton_app.h" +#include "../ibutton_i.h" #include -static void emulate_callback(void* context, bool emulated) { - furi_assert(context); +static void ibutton_scene_emulate_callback(void* context, bool emulated) { + iButton* ibutton = context; if(emulated) { - iButtonApp* app = static_cast(context); - iButtonEvent event = { - .payload = {.worker_write_result = iButtonWorkerWriteOK}, - .type = iButtonEvent::Type::EventTypeWorkerEmulated, - }; - app->get_view_manager()->send_event(&event); + view_dispatcher_send_custom_event( + ibutton->view_dispatcher, iButtonCustomEventWorkerEmulated); } } -void iButtonSceneEmulate::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); +void ibutton_scene_emulate_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); const char* key_name = ibutton_key_get_name_p(key); + uint8_t line_count = 2; DOLPHIN_DEED(DolphinDeedIbuttonEmulate); // check that stored key has name if(strcmp(key_name, "") != 0) { - app->set_text_store("emulating\n%s", key_name); + ibutton_text_store_set(ibutton, "emulating\n%s", key_name); line_count = 2; } else { // if not, show key data switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: - app->set_text_store( + ibutton_text_store_set( + ibutton, "emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], key_data[1], @@ -44,11 +42,12 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { line_count = 3; break; case iButtonKeyCyfral: - app->set_text_store("emulating\n%02X %02X", key_data[0], key_data[1]); + ibutton_text_store_set(ibutton, "emulating\n%02X %02X", key_data[0], key_data[1]); line_count = 2; break; case iButtonKeyMetakom: - app->set_text_store( + ibutton_text_store_set( + ibutton, "emulating\n%02X %02X %02X %02X", key_data[0], key_data[1], @@ -62,40 +61,45 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { switch(line_count) { case 3: popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 22, AlignCenter, AlignTop); + popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); break; default: popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 28, AlignCenter, AlignTop); + popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); break; } popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - ibutton_worker_emulate_set_callback(app->get_key_worker(), emulate_callback, app); - ibutton_worker_emulate_start(app->get_key_worker(), key); + ibutton_worker_emulate_set_callback( + ibutton->key_worker, ibutton_scene_emulate_callback, ibutton); + ibutton_worker_emulate_start(ibutton->key_worker, key); } -bool iButtonSceneEmulate::on_event(iButtonApp* app, iButtonEvent* event) { +bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; bool consumed = false; - if(event->type == iButtonEvent::Type::EventTypeWorkerEmulated) { - app->notify_yellow_blink(); + if(event.type == SceneManagerEventTypeTick) { consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - app->notify_emulate(); + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulate); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; + if(event.event == iButtonCustomEventWorkerEmulated) { + ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink); + } } return consumed; } -void iButtonSceneEmulate::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); +void ibutton_scene_emulate_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); diff --git a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c new file mode 100644 index 00000000..abd171f6 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_exit_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_exit_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", ibutton_scene_exit_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->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, iButtonSceneStart); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_exit_confirm_on_exit(void* context) { + iButton* ibutton = context; + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_info.c b/applications/ibutton/scenes/ibutton_scene_info.c new file mode 100644 index 00000000..5b0af1d8 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_info.c @@ -0,0 +1,61 @@ +#include "../ibutton_i.h" + +void ibutton_scene_info_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + iButtonKey* key = ibutton->key; + + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set(ibutton, "%s", ibutton_key_get_name_p(key)); + widget_add_text_box_element( + widget, 0, 0, 128, 28, AlignCenter, AlignCenter, ibutton->text_store, false); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + break; + + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + break; + + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + break; + } + + widget_add_string_element( + widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, ibutton->text_store); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void ibutton_scene_info_on_exit(void* context) { + iButton* ibutton = context; + ibutton_text_store_clear(ibutton); + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read.c b/applications/ibutton/scenes/ibutton_scene_read.c new file mode 100644 index 00000000..a25f27e6 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read.c @@ -0,0 +1,72 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventWorkerRead); +} + +void ibutton_scene_read_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + iButtonWorker* worker = ibutton->key_worker; + DOLPHIN_DEED(DolphinDeedIbuttonRead); + + popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); + popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_key_set_name(key, ""); + + ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton); + ibutton_worker_read_start(worker, key); +} + +bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeTick) { + consumed = true; + ibutton_notification_message(ibutton, iButtonNotificationMessageRead); + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventWorkerRead) { + bool success = false; + iButtonKey* key = ibutton->key; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + if(!ibutton_key_dallas_crc_is_valid(key)) { + scene_manager_next_scene(scene_manager, iButtonSceneReadCRCError); + } else if(!ibutton_key_dallas_is_1990_key(key)) { + scene_manager_next_scene(scene_manager, iButtonSceneReadNotKeyError); + } else { + success = true; + } + } else { + success = true; + } + + if(success) { + ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn); + DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); + scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess); + } + } + } + + return consumed; +} + +void ibutton_scene_read_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c new file mode 100644 index 00000000..4df96d64 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c @@ -0,0 +1,71 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_crc_error_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_crc_error_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X\nExpected CRC: %X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7], + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); + + dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, ibutton->text_store, 64, 19, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_crc_error_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); + + ibutton_notification_message(ibutton, iButtonNotificationMessageError); + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOn); +} + +bool ibutton_scene_read_crc_error_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_read_crc_error_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c new file mode 100644 index 00000000..7d479a46 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c @@ -0,0 +1,61 @@ +#include "../ibutton_i.h" + +typedef enum { + SubmenuIndexSave, + SubmenuIndexEmulate, + SubmenuIndexWrite, +} SubmenuIndex; + +void ibutton_scene_read_key_menu_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_read_key_menu_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Save", SubmenuIndexSave, ibutton_scene_read_key_menu_submenu_callback, ibutton); + submenu_add_item( + submenu, + "Emulate", + SubmenuIndexEmulate, + ibutton_scene_read_key_menu_submenu_callback, + ibutton); + if(ibutton_key_get_type(ibutton->key) == iButtonKeyDS1990) { + submenu_add_item( + submenu, + "Write", + SubmenuIndexWrite, + ibutton_scene_read_key_menu_submenu_callback, + ibutton); + } + + submenu_set_selected_item(submenu, SubmenuIndexSave); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexSave) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); + } else if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite); + } + } + + return consumed; +} + +void ibutton_scene_read_key_menu_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c new file mode 100644 index 00000000..76f14dae --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c @@ -0,0 +1,72 @@ +#include "../ibutton_i.h" +#include + +static void + ibutton_scene_read_not_key_error_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_not_key_error_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set( + ibutton, + "THIS IS NOT A KEY\n%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7], + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); + + dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, ibutton->text_store, 64, 19, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_not_key_error_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); + + ibutton_notification_message(ibutton, iButtonNotificationMessageError); + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOn); +} + +bool ibutton_scene_read_not_key_error_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_read_not_key_error_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_success.c b/applications/ibutton/scenes/ibutton_scene_read_success.c new file mode 100644 index 00000000..c3a13478 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_success.c @@ -0,0 +1,87 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_success_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_success_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "Dallas\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + break; + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "Cyfral\n%02X %02X", key_data[0], key_data[1]); + break; + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, + "Metakom\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3]); + break; + } + + dialog_ex_set_text(dialog_ex, ibutton->text_store, 95, 30, AlignCenter, AlignCenter); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_success_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); +} + +bool ibutton_scene_read_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_next_scene(scene_manager, iButtonSceneRetryConfirm); + } + } + + return consumed; +} + +void ibutton_scene_read_success_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_retry_confirm.c b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c new file mode 100644 index 00000000..d2778ac1 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_retry_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_retry_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", ibutton_scene_retry_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, GuiButtonTypeRight, "Stay", ibutton_scene_retry_confirm_widget_callback, ibutton); + 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(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->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, iButtonSceneRead); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_retry_confirm_on_exit(void* context) { + iButton* ibutton = context; + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_save_name.c b/applications/ibutton/scenes/ibutton_scene_save_name.c new file mode 100644 index 00000000..b1baf6af --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_save_name.c @@ -0,0 +1,68 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_save_name_text_input_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventTextEditResult); +} + +void ibutton_scene_save_name_on_enter(void* context) { + iButton* ibutton = context; + TextInput* text_input = ibutton->text_input; + + const char* key_name = ibutton_key_get_name_p(ibutton->key); + const bool key_name_is_empty = !strcmp(key_name, ""); + + if(key_name_is_empty) { + set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE); + } else { + ibutton_text_store_set(ibutton, "%s", key_name); + } + + text_input_set_header_text(text_input, "Name the key"); + text_input_set_result_callback( + text_input, + ibutton_scene_save_name_text_input_callback, + ibutton, + ibutton->text_store, + IBUTTON_KEY_NAME_SIZE, + key_name_is_empty); + + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, key_name); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); +} + +bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventTextEditResult) { + if(ibutton_save_key(ibutton, ibutton->text_store)) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess); + } else { + const uint32_t possible_scenes[] = { + iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + } + + return consumed; +} + +void ibutton_scene_save_name_on_exit(void* context) { + iButton* ibutton = context; + TextInput* text_input = ibutton->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/ibutton/scenes/ibutton_scene_save_success.c b/applications/ibutton/scenes/ibutton_scene_save_success.c new file mode 100644 index 00000000..dffda6a0 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_save_success.c @@ -0,0 +1,52 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_save_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); +} + +void ibutton_scene_save_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + DOLPHIN_DEED(DolphinDeedIbuttonSave); + + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); + + popup_set_callback(popup, ibutton_scene_save_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); +} + +bool ibutton_scene_save_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + const uint32_t possible_scenes[] = { + iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + + return consumed; +} + +void ibutton_scene_save_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c new file mode 100644 index 00000000..36529772 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c @@ -0,0 +1,75 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexEmulate, + SubmenuIndexWrite, + SubmenuIndexEdit, + SubmenuIndexDelete, + SubmenuIndexInfo, +}; + +void ibutton_scene_saved_key_menu_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_saved_key_menu_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, + "Emulate", + SubmenuIndexEmulate, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + if(ibutton_key_get_type(ibutton->key) == iButtonKeyDS1990) { + submenu_add_item( + submenu, + "Write", + SubmenuIndexWrite, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + } + submenu_add_item( + submenu, "Edit", SubmenuIndexEdit, ibutton_scene_saved_key_menu_submenu_callback, ibutton); + submenu_add_item( + submenu, + "Delete", + SubmenuIndexDelete, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + submenu_add_item( + submenu, "Info", SubmenuIndexInfo, ibutton_scene_saved_key_menu_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexEmulate); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite); + } else if(event.event == SubmenuIndexEdit) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); + } else if(event.event == SubmenuIndexDelete) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneDeleteConfirm); + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneInfo); + } + } + + return consumed; +} + +void ibutton_scene_saved_key_menu_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_select_key.c b/applications/ibutton/scenes/ibutton_scene_select_key.c new file mode 100644 index 00000000..32169a9c --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_select_key.c @@ -0,0 +1,22 @@ +#include "../ibutton_i.h" + +void ibutton_scene_select_key_on_enter(void* context) { + iButton* ibutton = context; + + if(!ibutton_file_select(ibutton)) { + scene_manager_search_and_switch_to_previous_scene( + ibutton->scene_manager, iButtonSceneStart); + } else { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSavedKeyMenu); + } +} + +bool ibutton_scene_select_key_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void ibutton_scene_select_key_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/ibutton/scenes/ibutton_scene_start.c b/applications/ibutton/scenes/ibutton_scene_start.c new file mode 100644 index 00000000..a3141f5a --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_start.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexRead, + SubmenuIndexSaved, + SubmenuIndexAdd, +}; + +void ibutton_scene_start_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_start_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Read", SubmenuIndexRead, ibutton_scene_start_submenu_callback, ibutton); + submenu_add_item( + submenu, "Saved", SubmenuIndexSaved, ibutton_scene_start_submenu_callback, ibutton); + submenu_add_item( + submenu, "Add Manually", SubmenuIndexAdd, ibutton_scene_start_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexRead); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexRead) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); + } else if(event.event == SubmenuIndexSaved) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey); + } else if(event.event == SubmenuIndexAdd) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType); + } + } + + return consumed; +} + +void ibutton_scene_start_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_write.c b/applications/ibutton/scenes/ibutton_scene_write.c new file mode 100644 index 00000000..35e45d83 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_write.c @@ -0,0 +1,121 @@ +#include "../ibutton_i.h" + +typedef enum { + iButtonSceneWriteStateDefault, + iButtonSceneWriteStateBlinkYellow, +} iButtonSceneWriteState; + +static void ibutton_scene_write_callback(void* context, iButtonWorkerWriteResult result) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_write_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + iButtonWorker* worker = ibutton->key_worker; + + const uint8_t* key_data = ibutton_key_get_data_p(key); + const char* key_name = ibutton_key_get_name_p(key); + + uint8_t line_count = 2; + + // check that stored key has name + if(strcmp(key_name, "") != 0) { + ibutton_text_store_set(ibutton, "writing\n%s", key_name); + line_count = 2; + } else { + // if not, show key data + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + line_count = 3; + break; + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "writing\n%02X %02X", key_data[0], key_data[1]); + line_count = 2; + break; + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, + "writing\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3]); + line_count = 2; + break; + } + } + + switch(line_count) { + case 3: + popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); + popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); + break; + + default: + popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); + popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); + break; + } + + popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); + + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneWrite, iButtonSceneWriteStateDefault); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + + ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton); + ibutton_worker_write_start(worker, key); +} + +bool ibutton_scene_write_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if((event.event == iButtonWorkerWriteOK) || (event.event == iButtonWorkerWriteSameKey)) { + scene_manager_next_scene(scene_manager, iButtonSceneWriteSuccess); + } else if(event.event == iButtonWorkerWriteNoDetect) { + scene_manager_set_scene_state( + scene_manager, iButtonSceneWrite, iButtonSceneWriteStateDefault); + } else if(event.event == iButtonWorkerWriteCannotWrite) { + scene_manager_set_scene_state( + scene_manager, iButtonSceneWrite, iButtonSceneWriteStateBlinkYellow); + } + + } else if(event.type == SceneManagerEventTypeTick) { + consumed = true; + if(scene_manager_get_scene_state(scene_manager, iButtonSceneWrite) == + iButtonSceneWriteStateBlinkYellow) { + ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink); + } else { + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulate); + } + } + + return consumed; +} + +void ibutton_scene_write_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_write_success.c b/applications/ibutton/scenes/ibutton_scene_write_success.c new file mode 100644 index 00000000..6abafbb3 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_write_success.c @@ -0,0 +1,52 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_write_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOff); +} + +void ibutton_scene_write_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); + popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); + + popup_set_callback(popup, ibutton_scene_write_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn); +} + +bool ibutton_scene_write_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + const uint32_t possible_scenes[] = {iButtonSceneReadKeyMenu, iButtonSceneStart}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + + return consumed; +} + +void ibutton_scene_write_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +}