From bbbfda5dcf45ccbfe5a7862e0ca794080843c4d2 Mon Sep 17 00:00:00 2001 From: RogueMaster Date: Sat, 17 Sep 2022 07:08:26 -0400 Subject: [PATCH] name changer? --- .../plugins/dolphinbackup/application.fam | 2 +- .../plugins/dolphinrestorer/application.fam | 2 +- .../plugins/namechanger/application.fam | 21 + .../plugins/namechanger/namechanger.c | 444 ++++++++++++++++++ .../plugins/namechanger/namechanger.h | 3 + .../namechanger/namechanger_custom_event.h | 6 + .../plugins/namechanger/namechanger_i.h | 49 ++ .../namechanger/scenes/namechanger_scene.c | 30 ++ .../namechanger/scenes/namechanger_scene.h | 29 ++ .../scenes/namechanger_scene_config.h | 3 + .../scenes/namechanger_scene_save_failed.c | 50 ++ .../scenes/namechanger_scene_save_name.c | 53 +++ .../scenes/namechanger_scene_save_success.c | 51 ++ .../targets/f7/furi_hal/furi_hal_version.c | 104 +++- .../furi_hal_include/furi_hal_version.h | 8 + 15 files changed, 836 insertions(+), 19 deletions(-) create mode 100644 applications/plugins/namechanger/application.fam create mode 100644 applications/plugins/namechanger/namechanger.c create mode 100644 applications/plugins/namechanger/namechanger.h create mode 100644 applications/plugins/namechanger/namechanger_custom_event.h create mode 100644 applications/plugins/namechanger/namechanger_i.h create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene.c create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene.h create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene_config.h create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene_save_failed.c create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene_save_name.c create mode 100644 applications/plugins/namechanger/scenes/namechanger_scene_save_success.c diff --git a/applications/plugins/dolphinbackup/application.fam b/applications/plugins/dolphinbackup/application.fam index 12fb66a52..2e16f5f8e 100644 --- a/applications/plugins/dolphinbackup/application.fam +++ b/applications/plugins/dolphinbackup/application.fam @@ -8,5 +8,5 @@ App( stack_size=2 * 1024, order=85, fap_icon="bckupIcon.png", - fap_category="Misc", + fap_category="Tools", ) \ No newline at end of file diff --git a/applications/plugins/dolphinrestorer/application.fam b/applications/plugins/dolphinrestorer/application.fam index 2236073ac..d293fa90c 100644 --- a/applications/plugins/dolphinrestorer/application.fam +++ b/applications/plugins/dolphinrestorer/application.fam @@ -8,5 +8,5 @@ App( stack_size= 2 * 1024, order=90, fap_icon="restoreIcon.png", - fap_category="Misc", + fap_category="Tools", ) \ No newline at end of file diff --git a/applications/plugins/namechanger/application.fam b/applications/plugins/namechanger/application.fam new file mode 100644 index 000000000..53053fc32 --- /dev/null +++ b/applications/plugins/namechanger/application.fam @@ -0,0 +1,21 @@ +App( + appid="APPS_NameChanger", + name="Name Changer", + apptype=FlipperAppType.EXTERNAL, + entry_point="namechanger_app", + cdefines=["APP_NAMECHANGER"], + requires=["gui","dialogs","storage",], + provides=["namechanger_start"], + stack_size=2 * 1024, + order=169, + fap_icon="../../../assets/icons/Archive/keyboard_10px.png", + fap_category="Tools", +) + +App( + appid="namechanger_start", + apptype=FlipperAppType.STARTUP, + entry_point="namechanger_on_system_start", + requires=["storage"], + order=130, +) \ No newline at end of file diff --git a/applications/plugins/namechanger/namechanger.c b/applications/plugins/namechanger/namechanger.c new file mode 100644 index 000000000..6c61caf96 --- /dev/null +++ b/applications/plugins/namechanger/namechanger.c @@ -0,0 +1,444 @@ +#include "namechanger.h" +#include "namechanger_i.h" +#include "namechanger/scenes/namechanger_scene.h" +#include "m-string.h" +#include +#include + +bool namechanger_make_app_folder(NameChanger* namechanger) { + bool created = false; + + string_t folderpath; + string_init_set_str(folderpath, "/ext/dolphin"); + + //Make dir if doesn't exist + if(!storage_simply_mkdir(namechanger->storage, string_get_cstr(folderpath))) { + dialog_message_show_storage_error(namechanger->dialogs, "Cannot create\napp folder."); + } else { + created = true; + } + + string_clear(folderpath); + return created; +} + +bool namechanger_name_read_write(NameChanger* namechanger, char* name, uint8_t mode) { + FlipperFormat* file = flipper_format_file_alloc(namechanger->storage); + + string_t file_path; + string_init_set_str(file_path, "/ext/dolphin/name.txt"); + + if(namechanger_make_app_folder(namechanger)) { + if(mode == 2) { + //read + bool result = false; + + string_t data; + string_init(data); + + do { + if(!flipper_format_file_open_existing(file, string_get_cstr(file_path))) { + break; + } + + // header + uint32_t version; + + if(!flipper_format_read_header(file, data, &version)) { + break; + } + + if(string_cmp_str(data, NAMECHANGER_HEADER) != 0) { + break; + } + + if(version != 1) { + break; + } + + // get Name + if(!flipper_format_read_string(file, "Name", data)) { + break; + } + + result = true; + } while(false); + + flipper_format_free(file); + + if(!result) { + FURI_LOG_I(TAG, "Cannot load file."); + } else { + string_strim(data); + FURI_LOG_I(TAG, "data: %s", data); + + namechanger_text_store_set(namechanger, "%s", string_get_cstr(data)); + } + + string_clear(data); + + return result; + } else if(mode == 3) { + //save + FlipperFormat* file = flipper_format_file_alloc(namechanger->storage); + + bool result = false; + + do { + // Open file for write + if(!flipper_format_file_open_always(file, string_get_cstr(file_path))) { + break; + } + + // Write header + if(!flipper_format_write_header_cstr(file, NAMECHANGER_HEADER, 1)) { + break; + } + + // Write comments + if(!flipper_format_write_comment_cstr( + file, + "Changing the value below will change your FlipperZero device name.")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, + "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, "It cannot contain any other characters.")) { + break; + } + + //Write name + if(!flipper_format_write_string_cstr(file, "Name", name)) { + break; + } + + result = true; + } while(false); + + flipper_format_free(file); + + if(!result) { + //dialog_message_show_storage_error(namechanger->dialogs, "Cannot save\nname file"); + FURI_LOG_I(TAG, "Cannot save name file."); + } else { + //set name + furi_hal_version_set_custom_name(name); + } + + return result; + } else { + FURI_LOG_I(TAG, "Something broke."); + return false; + } + } else { + dialog_message_show_storage_error(namechanger->dialogs, "Cannot create\napp folder."); + return false; + } +} + +bool namechanger_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + NameChanger* namechanger = context; + return scene_manager_handle_custom_event(namechanger->scene_manager, event); +} + +bool namechanger_back_event_callback(void* context) { + furi_assert(context); + NameChanger* namechanger = context; + return scene_manager_handle_back_event(namechanger->scene_manager); +} + +void namechanger_tick_event_callback(void* context) { + furi_assert(context); + NameChanger* namechanger = context; + scene_manager_handle_tick_event(namechanger->scene_manager); +} + +NameChanger* namechanger_alloc() { + NameChanger* namechanger = malloc(sizeof(namechanger)); + + namechanger->scene_manager = scene_manager_alloc(&namechanger_scene_handlers, namechanger); + + namechanger->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(namechanger->view_dispatcher); + view_dispatcher_set_event_callback_context(namechanger->view_dispatcher, namechanger); + view_dispatcher_set_custom_event_callback( + namechanger->view_dispatcher, namechanger_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + namechanger->view_dispatcher, namechanger_back_event_callback); + view_dispatcher_set_tick_event_callback( + namechanger->view_dispatcher, namechanger_tick_event_callback, 500); + + namechanger->gui = furi_record_open(RECORD_GUI); + namechanger->storage = furi_record_open(RECORD_STORAGE); + namechanger->dialogs = furi_record_open(RECORD_DIALOGS); + + namechanger->text_input = text_input_alloc(); + view_dispatcher_add_view( + namechanger->view_dispatcher, + NameChangerViewTextInput, + text_input_get_view(namechanger->text_input)); + + namechanger->popup = popup_alloc(); + view_dispatcher_add_view( + namechanger->view_dispatcher, NameChangerViewPopup, popup_get_view(namechanger->popup)); + + namechanger->widget = widget_alloc(); + view_dispatcher_add_view( + namechanger->view_dispatcher, NameChangerViewWidget, widget_get_view(namechanger->widget)); + + namechanger->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + namechanger->view_dispatcher, + NameChangerViewDialogEx, + dialog_ex_get_view(namechanger->dialog_ex)); + + return namechanger; +} + +void namechanger_free(NameChanger* namechanger) { + furi_assert(namechanger); + + view_dispatcher_remove_view(namechanger->view_dispatcher, NameChangerViewDialogEx); + dialog_ex_free(namechanger->dialog_ex); + + view_dispatcher_remove_view(namechanger->view_dispatcher, NameChangerViewWidget); + widget_free(namechanger->widget); + + view_dispatcher_remove_view(namechanger->view_dispatcher, NameChangerViewPopup); + popup_free(namechanger->popup); + + view_dispatcher_remove_view(namechanger->view_dispatcher, NameChangerViewTextInput); + text_input_free(namechanger->text_input); + + view_dispatcher_free(namechanger->view_dispatcher); + scene_manager_free(namechanger->scene_manager); + + furi_record_close(RECORD_STORAGE); + namechanger->storage = NULL; + + furi_record_close(RECORD_DIALOGS); + namechanger->dialogs = NULL; + + furi_record_close(RECORD_GUI); + namechanger->gui = NULL; + + free(namechanger); +} + +bool namechanger_delete_file(NameChanger* namechanger, char* file_path) { + bool result = false; + result = storage_simply_remove(namechanger->storage, file_path); + + return result; +} + +void namechanger_text_store_set(NameChanger* namechanger, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(namechanger->text_store, NAMECHANGER_TEXT_STORE_SIZE, text, args); + + va_end(args); +} + +void namechanger_text_store_clear(NameChanger* namechanger) { + memset(namechanger->text_store, 0, NAMECHANGER_TEXT_STORE_SIZE); +} + +int32_t namechanger_app(void* p) { + UNUSED(p); + FURI_LOG_I(TAG, "app1"); + NameChanger* namechanger = namechanger_alloc(); + + FURI_LOG_I(TAG, "app2"); + view_dispatcher_attach_to_gui( + namechanger->view_dispatcher, namechanger->gui, ViewDispatcherTypeFullscreen); + + scene_manager_next_scene(namechanger->scene_manager, NameChangerSceneSaveName); + + view_dispatcher_run(namechanger->view_dispatcher); + + namechanger_free(namechanger); + return 0; +} + +void namechanger_on_system_start() { + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + string_t NAMEHEADER; + string_init_set_str(NAMEHEADER, "Flipper Name File"); + + string_t folderpath; + string_init_set_str(folderpath, "/ext/dolphin"); + + string_t filepath; + string_init_set_str(filepath, "/ext/dolphin/name.txt"); + + //Make dir if doesn't exist + if(storage_simply_mkdir(storage, string_get_cstr(folderpath))) { + bool result = false; + + string_t data; + string_init(data); + + do { + if(!flipper_format_file_open_existing(file, string_get_cstr(filepath))) { + break; + } + + // header + uint32_t version; + + if(!flipper_format_read_header(file, data, &version)) { + break; + } + + if(string_cmp_str(data, string_get_cstr(NAMEHEADER)) != 0) { + break; + } + + if(version != 1) { + break; + } + + // get Name + if(!flipper_format_read_string(file, "Name", data)) { + break; + } + + result = true; + } while(false); + + flipper_format_free(file); + + if(!result) { + //file not good - write new one + FlipperFormat* file = flipper_format_file_alloc(storage); + + bool res = false; + + string_t name; + string_init_set_str(name, furi_hal_version_get_name_ptr()); + + do { + // Open file for write + if(!flipper_format_file_open_always(file, string_get_cstr(filepath))) { + break; + } + + // Write header + if(!flipper_format_write_header_cstr(file, string_get_cstr(NAMEHEADER), 1)) { + break; + } + + // Write comments + if(!flipper_format_write_comment_cstr( + file, + "Changing the value below will change your FlipperZero device name.")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, + "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, "It can contain other characters but use at your own risk.")) { + break; + } + + //Write name + if(!flipper_format_write_string_cstr(file, "Name", string_get_cstr(name))) { + break; + } + + res = true; + } while(false); + + flipper_format_free(file); + + if(!res) { + FURI_LOG_E(TAG, "Save failed."); + } + + string_clear(name); + } else { + string_strim(data); + FURI_LOG_I(TAG, "data: %s", data); + + if(!string_size(data)) { + //Empty file - get default name and write to file. + FlipperFormat* file = flipper_format_file_alloc(storage); + + bool res = false; + + string_t name; + string_init_set_str(name, furi_hal_version_get_name_ptr()); + + do { + // Open file for write + if(!flipper_format_file_open_always(file, string_get_cstr(filepath))) { + break; + } + + // Write header + if(!flipper_format_write_header_cstr(file, string_get_cstr(NAMEHEADER), 1)) { + break; + } + + // Write comments + if(!flipper_format_write_comment_cstr( + file, + "Changing the value below will change your FlipperZero device name.")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, + "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) { + break; + } + + if(!flipper_format_write_comment_cstr( + file, "It cannot contain any other characters.")) { + break; + } + + //Write name + if(!flipper_format_write_string_cstr(file, "Name", string_get_cstr(name))) { + break; + } + + res = true; + } while(false); + + flipper_format_free(file); + + if(!res) { + FURI_LOG_E(TAG, "Save failed."); + } + + string_clear(name); + } else { + //set name from file + furi_hal_version_set_custom_name(string_get_cstr(data)); + } + } + + string_clear(data); + } + + string_clear(filepath); + string_clear(folderpath); + furi_record_close(RECORD_STORAGE); +} \ No newline at end of file diff --git a/applications/plugins/namechanger/namechanger.h b/applications/plugins/namechanger/namechanger.h new file mode 100644 index 000000000..1519f5814 --- /dev/null +++ b/applications/plugins/namechanger/namechanger.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct NameChanger NameChanger; diff --git a/applications/plugins/namechanger/namechanger_custom_event.h b/applications/plugins/namechanger/namechanger_custom_event.h new file mode 100644 index 000000000..3485c870b --- /dev/null +++ b/applications/plugins/namechanger/namechanger_custom_event.h @@ -0,0 +1,6 @@ +#pragma once + +enum NameChangerCustomEvent { + NameChangerCustomEventBack, + NameChangerCustomEventTextEditResult, +}; diff --git a/applications/plugins/namechanger/namechanger_i.h b/applications/plugins/namechanger/namechanger_i.h new file mode 100644 index 000000000..24fc7ce8d --- /dev/null +++ b/applications/plugins/namechanger/namechanger_i.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "namechanger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "namechanger_custom_event.h" +#include "scenes/namechanger_scene.h" + +#define NAMECHANGER_TEXT_STORE_SIZE 9 +#define NAMECHANGER_HEADER "Flipper Name File" + +#define TAG "NameChanger" + +struct NameChanger { + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + Gui* gui; + Storage* storage; + DialogsApp* dialogs; + + char text_store[NAMECHANGER_TEXT_STORE_SIZE + 1]; + + TextInput* text_input; + Popup* popup; + Widget* widget; + DialogEx* dialog_ex; +}; + +typedef enum { + NameChangerViewTextInput, + NameChangerViewPopup, + NameChangerViewWidget, + NameChangerViewDialogEx, +} NameChangerView; + +bool namechanger_name_read_write(NameChanger* namechanger, char* name, uint8_t mode); +void namechanger_text_store_set(NameChanger* namechanger, const char* text, ...); +void namechanger_text_store_clear(NameChanger* namechanger); diff --git a/applications/plugins/namechanger/scenes/namechanger_scene.c b/applications/plugins/namechanger/scenes/namechanger_scene.c new file mode 100644 index 000000000..82f96e466 --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene.c @@ -0,0 +1,30 @@ +#include "namechanger_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const namechanger_on_enter_handlers[])(void*) = { +#include "namechanger_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 namechanger_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "namechanger_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 namechanger_on_exit_handlers[])(void* context) = { +#include "namechanger_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers namechanger_scene_handlers = { + .on_enter_handlers = namechanger_on_enter_handlers, + .on_event_handlers = namechanger_on_event_handlers, + .on_exit_handlers = namechanger_on_exit_handlers, + .scene_num = NameChangerSceneNum, +}; diff --git a/applications/plugins/namechanger/scenes/namechanger_scene.h b/applications/plugins/namechanger/scenes/namechanger_scene.h new file mode 100644 index 000000000..42071ab98 --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) NameChangerScene##id, +typedef enum { +#include "namechanger_scene_config.h" + NameChangerSceneNum, +} NameChangerScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers namechanger_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "namechanger_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 "namechanger_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 "namechanger_scene_config.h" +#undef ADD_SCENE diff --git a/applications/plugins/namechanger/scenes/namechanger_scene_config.h b/applications/plugins/namechanger/scenes/namechanger_scene_config.h new file mode 100644 index 000000000..9ed77f657 --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(namechanger, save_name, SaveName) +ADD_SCENE(namechanger, save_success, SaveSuccess) +ADD_SCENE(namechanger, save_failed, SaveFailed) \ No newline at end of file diff --git a/applications/plugins/namechanger/scenes/namechanger_scene_save_failed.c b/applications/plugins/namechanger/scenes/namechanger_scene_save_failed.c new file mode 100644 index 000000000..a7442699f --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene_save_failed.c @@ -0,0 +1,50 @@ +#include "../namechanger_i.h" +#include + +static void namechanger_scene_save_failed_popup_callback(void* context) { + NameChanger* namechanger = context; + view_dispatcher_send_custom_event(namechanger->view_dispatcher, NameChangerCustomEventBack); +} + +void namechanger_scene_save_failed_on_enter(void* context) { + NameChanger* namechanger = context; + Popup* popup = namechanger->popup; + + popup_set_icon(popup, 5, 10, &I_Cry_dolph_55x52); + popup_set_header(popup, "Save", 80, 20, AlignLeft, AlignTop); + popup_set_text(popup, "Failed.", 80, 35, AlignLeft, AlignTop); + + popup_set_callback(popup, namechanger_scene_save_failed_popup_callback); + popup_set_context(popup, namechanger); + popup_set_timeout(popup, 5000); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(namechanger->view_dispatcher, NameChangerViewPopup); +} + +bool namechanger_scene_save_failed_on_event(void* context, SceneManagerEvent event) { + NameChanger* namechanger = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == NameChangerCustomEventBack) { + scene_manager_search_and_switch_to_previous_scene( + namechanger->scene_manager, NameChangerSceneSaveName); + } + } + + return consumed; +} + +void namechanger_scene_save_failed_on_exit(void* context) { + NameChanger* namechanger = context; + Popup* popup = namechanger->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/plugins/namechanger/scenes/namechanger_scene_save_name.c b/applications/plugins/namechanger/scenes/namechanger_scene_save_name.c new file mode 100644 index 000000000..d1e4e15e1 --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene_save_name.c @@ -0,0 +1,53 @@ +#include "../namechanger_i.h" +#include "m-string.h" +#include + +static void namechanger_scene_save_name_text_input_callback(void* context) { + NameChanger* namechanger = context; + view_dispatcher_send_custom_event( + namechanger->view_dispatcher, NameChangerCustomEventTextEditResult); +} + +void namechanger_scene_save_name_on_enter(void* context) { + NameChanger* namechanger = context; + TextInput* text_input = namechanger->text_input; + + bool file_exists = namechanger_name_read_write(namechanger, NULL, 2); + + text_input_set_header_text(text_input, "Set Flipper Name"); + text_input_set_result_callback( + text_input, + namechanger_scene_save_name_text_input_callback, + namechanger, + namechanger->text_store, + NAMECHANGER_TEXT_STORE_SIZE, + file_exists); + + view_dispatcher_switch_to_view(namechanger->view_dispatcher, NameChangerViewTextInput); +} + +bool namechanger_scene_save_name_on_event(void* context, SceneManagerEvent event) { + NameChanger* namechanger = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == NameChangerCustomEventTextEditResult) { + if(namechanger_name_read_write(namechanger, namechanger->text_store, 3)) { + scene_manager_next_scene(namechanger->scene_manager, NameChangerSceneSaveSuccess); + } else { + scene_manager_search_and_switch_to_previous_scene( + namechanger->scene_manager, NameChangerSceneSaveFailed); + } + } + } + + return consumed; +} + +void namechanger_scene_save_name_on_exit(void* context) { + NameChanger* namechanger = context; + TextInput* text_input = namechanger->text_input; + + text_input_reset(text_input); +} diff --git a/applications/plugins/namechanger/scenes/namechanger_scene_save_success.c b/applications/plugins/namechanger/scenes/namechanger_scene_save_success.c new file mode 100644 index 000000000..e84913bc2 --- /dev/null +++ b/applications/plugins/namechanger/scenes/namechanger_scene_save_success.c @@ -0,0 +1,51 @@ +#include "../namechanger_i.h" +#include + +static void namechanger_scene_save_success_popup_callback(void* context) { + NameChanger* namechanger = context; + view_dispatcher_send_custom_event(namechanger->view_dispatcher, NameChangerCustomEventBack); +} + +void namechanger_scene_save_success_on_enter(void* context) { + NameChanger* namechanger = context; + Popup* popup = namechanger->popup; + + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); + + popup_set_callback(popup, namechanger_scene_save_success_popup_callback); + popup_set_context(popup, namechanger); + popup_set_timeout(popup, 5000); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(namechanger->view_dispatcher, NameChangerViewPopup); +} + +bool namechanger_scene_save_success_on_event(void* context, SceneManagerEvent event) { + //UNUSED(context); + NameChanger* namechanger = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == NameChangerCustomEventBack) { + scene_manager_search_and_switch_to_previous_scene( + namechanger->scene_manager, NameChangerSceneSaveName); + //furi_hal_power_reset(); + } + } + + return consumed; +} + +void namechanger_scene_save_success_on_exit(void* context) { + NameChanger* namechanger = context; + Popup* popup = namechanger->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/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c index 500317cdc..f90c3da13 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_version.c +++ b/firmware/targets/f7/furi_hal/furi_hal_version.c @@ -86,30 +86,77 @@ typedef struct { char name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; /** \0 terminated name */ char device_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; /** device name for special needs */ uint8_t ble_mac[6]; + const char* cname; + char cname2[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; } FuriHalVersion; static FuriHalVersion furi_hal_version = {0}; -static void furi_hal_version_set_name(const char* name) { - if(name != NULL) { - strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); +void furi_hal_version_set_custom_name(const char* name) { + if((name != NULL) && ((strlen(name) >= 1) && (strlen(name) <= 8))) { + strlcpy(furi_hal_version.cname2, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + snprintf( furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper %s", - furi_hal_version.name); + furi_hal_version.cname2); + + furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; } else { - snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper"); + strcpy(furi_hal_version.cname2, ""); + } +} + +static void furi_hal_version_set_name(const char* name) { + char tmpCname[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; + + strlcpy(tmpCname, furi_hal_version_get_name_ptr(), FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + + if(!((strlen(tmpCname) >= 1) && (strlen(tmpCname) <= 8))) { + strcpy(tmpCname, ""); + } + + if(name != NULL) { + if(strcmp(tmpCname, "") != 0) { + strlcpy(furi_hal_version.name, tmpCname, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper %s", + furi_hal_version.name); + } else { + strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper %s", + furi_hal_version.name); + } + } else { + if(strcmp(tmpCname, "") != 0) { + strlcpy(furi_hal_version.name, tmpCname, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper %s", + furi_hal_version.name); + } else { + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper Dev"); + } } furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; // BLE Mac address uint32_t udn = LL_FLASH_GetUDN(); - if(version_get_custom_name(NULL) != NULL) { - udn = *((uint32_t*)version_get_custom_name(NULL)); - } - + udn = *((uint32_t*)name); uint32_t company_id = LL_FLASH_GetSTCompanyID(); uint32_t device_id = LL_FLASH_GetDeviceID(); furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); @@ -133,8 +180,10 @@ static void furi_hal_version_load_otp_v0() { furi_hal_version.board_body = otp->board_body; furi_hal_version.board_connect = otp->board_connect; - if(version_get_custom_name(NULL) != NULL) { - furi_hal_version_set_name(version_get_custom_name(NULL)); + furi_hal_version.cname = furi_hal_version_get_name_ptr(); + if(furi_hal_version.cname != NULL && strlen(furi_hal_version.cname) >= 1 && + strlen(furi_hal_version.cname) <= 8) { + furi_hal_version_set_name(furi_hal_version.cname); } else { furi_hal_version_set_name(otp->name); } @@ -151,8 +200,10 @@ static void furi_hal_version_load_otp_v1() { furi_hal_version.board_color = otp->board_color; furi_hal_version.board_region = otp->board_region; - if(version_get_custom_name(NULL) != NULL) { - furi_hal_version_set_name(version_get_custom_name(NULL)); + furi_hal_version.cname = furi_hal_version_get_name_ptr(); + if(furi_hal_version.cname != NULL && strlen(furi_hal_version.cname) >= 1 && + strlen(furi_hal_version.cname) <= 8) { + furi_hal_version_set_name(furi_hal_version.cname); } else { furi_hal_version_set_name(otp->name); } @@ -175,8 +226,10 @@ static void furi_hal_version_load_otp_v2() { if(otp->board_color != 0xFF) { furi_hal_version.board_color = otp->board_color; furi_hal_version.board_region = otp->board_region; - if(version_get_custom_name(NULL) != NULL) { - furi_hal_version_set_name(version_get_custom_name(NULL)); + furi_hal_version.cname = furi_hal_version_get_name_ptr(); + if(furi_hal_version.cname != NULL && strlen(furi_hal_version.cname) >= 1 && + strlen(furi_hal_version.cname) <= 8) { + furi_hal_version_set_name(furi_hal_version.cname); } else { furi_hal_version_set_name(otp->name); } @@ -265,6 +318,7 @@ uint8_t furi_hal_version_get_hw_connect() { } FuriHalVersionRegion furi_hal_version_get_hw_region() { + // return furi_hal_version.board_region; return FuriHalVersionRegionUnknown; } @@ -293,6 +347,20 @@ uint32_t furi_hal_version_get_hw_timestamp() { } const char* furi_hal_version_get_name_ptr() { + if((strcmp(furi_hal_version.cname2, "") != 0) && + ((strlen(furi_hal_version.cname2) >= 1) && (strlen(furi_hal_version.cname2) <= 8))) { + return furi_hal_version.cname2; + } + + furi_hal_version.cname = version_get_custom_name(NULL); + + if((furi_hal_version.cname != NULL) && + ((strlen(furi_hal_version.cname) >= 1) && (strlen(furi_hal_version.cname) <= 8))) { + strlcpy( + furi_hal_version.cname2, furi_hal_version.cname, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + return furi_hal_version.cname2; + } + return *furi_hal_version.name == 0x00 ? NULL : furi_hal_version.name; } @@ -317,8 +385,10 @@ size_t furi_hal_version_uid_size() { } const uint8_t* furi_hal_version_uid() { - if(version_get_custom_name(NULL) != NULL) { - return (const uint8_t*)&(*((uint32_t*)version_get_custom_name(NULL))); + furi_hal_version.cname = furi_hal_version_get_name_ptr(); + if(furi_hal_version.cname != NULL && strlen(furi_hal_version.cname) >= 1 && + strlen(furi_hal_version.cname) <= 8) { + return (const uint8_t*)&(*((uint32_t*)furi_hal_version_get_name_ptr())); } return (const uint8_t*)UID64_BASE; } diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h index 720fdfd17..31292f602 100644 --- a/firmware/targets/furi_hal_include/furi_hal_version.h +++ b/firmware/targets/furi_hal_include/furi_hal_version.h @@ -51,6 +51,14 @@ typedef enum { FuriHalVersionDisplayMgg = 0x02, } FuriHalVersionDisplay; +/** Set Flipper Name + */ +//void furi_hal_version_set_name(const char* name); + +/** Set Custom Name + */ +void furi_hal_version_set_custom_name(const char* name); + /** Init flipper version */ void furi_hal_version_init();