Selaa lähdekoodia

working on saving reads

frux-c 2 vuotta sitten
vanhempi
commit
1b300fcb68

+ 71 - 0
scenes/uhf_scene_card_menu.c

@@ -0,0 +1,71 @@
+#include "../uhf_app_i.h"
+
+enum SubmenuIndex {
+    SubmenuIndexSave,
+    SubmenuIndexChangeKey,
+};
+
+void uhf_scene_card_menu_submenu_callback(void* context, uint32_t index) {
+    UHFApp* uhf_app = context;
+    view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index);
+}
+
+void uhf_scene_card_menu_on_enter(void* context) {
+    UHFApp* uhf_app = context;
+
+    Submenu* submenu = uhf_app->submenu;
+
+    submenu_add_item(
+        submenu, "Save", SubmenuIndexSave, uhf_scene_card_menu_submenu_callback, uhf_app);
+    // if(picopass->dev->dev_data.pacs.record.valid) {
+    //     submenu_add_item(
+    //         submenu,
+    //         "Save as LF",
+    //         SubmenuIndexSaveAsLF,
+    //         picopass_scene_card_menu_submenu_callback,
+    //         picopass);
+    // }
+    submenu_add_item(
+        submenu,
+        "Change Key",
+        SubmenuIndexChangeKey,
+        uhf_scene_card_menu_submenu_callback,
+        uhf_app);
+
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneCardMenu));
+
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu);
+}
+
+bool uhf_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
+    UHFApp* uhf_app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        FURI_LOG_E("LOG", "%lu", event.event);
+        if(event.event == SubmenuIndexSave) {
+            scene_manager_set_scene_state(
+                uhf_app->scene_manager, UHFSceneCardMenu, SubmenuIndexSave);
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveName);
+            consumed = true;
+        }
+        // else if(event.event == SubmenuIndexChangeKey) {
+        //     scene_manager_set_scene_state(
+        //         picopass->scene_manager, UHFSceneCardMenu, SubmenuIndexChangeKey);
+        //     scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu);
+        //     consumed = true;
+        // }
+    } else if(event.type == SceneManagerEventTypeBack) {
+        consumed = scene_manager_search_and_switch_to_previous_scene(
+            uhf_app->scene_manager, UHFSceneStart);
+    }
+
+    return consumed;
+}
+
+void uhf_scene_card_menu_on_exit(void* context) {
+    UHFApp* uhf_app = context;
+
+    submenu_reset(uhf_app->submenu);
+}

+ 3 - 3
scenes/uhf_scene_config.h

@@ -1,9 +1,9 @@
 ADD_SCENE(uhf, start, Start)
 ADD_SCENE(uhf, start, Start)
 ADD_SCENE(uhf, read_tag, ReadTag)
 ADD_SCENE(uhf, read_tag, ReadTag)
 ADD_SCENE(uhf, read_tag_success, ReadTagSuccess)
 ADD_SCENE(uhf, read_tag_success, ReadTagSuccess)
-// ADD_SCENE(uhf, card_menu, CardMenu)
-// ADD_SCENE(uhf, save_name, SaveName)
-// ADD_SCENE(uhf, save_success, SaveSuccess)
+ADD_SCENE(uhf, card_menu, CardMenu)
+ADD_SCENE(uhf, save_name, SaveName)
+ADD_SCENE(uhf, save_success, SaveSuccess)
 // ADD_SCENE(uhf, saved_menu, SavedMenu)
 // ADD_SCENE(uhf, saved_menu, SavedMenu)
 // ADD_SCENE(uhf, file_select, FileSelect)
 // ADD_SCENE(uhf, file_select, FileSelect)
 // ADD_SCENE(uhf, device_info, DeviceInfo)
 // ADD_SCENE(uhf, device_info, DeviceInfo)

+ 2 - 4
scenes/uhf_scene_read_tag_success.c

@@ -87,8 +87,8 @@ bool uhf_scene_read_tag_success_on_event(void* ctx, SceneManagerEvent event) {
             consumed = scene_manager_search_and_switch_to_previous_scene(
             consumed = scene_manager_search_and_switch_to_previous_scene(
                 uhf_app->scene_manager, UHFSceneStart);
                 uhf_app->scene_manager, UHFSceneStart);
         } else if(event.event == GuiButtonTypeRight) {
         } else if(event.event == GuiButtonTypeRight) {
-            // scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu);
-            // consumed = true;
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneCardMenu);
+            consumed = true;
         } else if(event.event == GuiButtonTypeCenter) {
         } else if(event.event == GuiButtonTypeCenter) {
             // consumed = scene_manager_search_and_switch_to_another_scene(
             // consumed = scene_manager_search_and_switch_to_another_scene(
             //     picopass->scene_manager, PicopassSceneStart);
             //     picopass->scene_manager, PicopassSceneStart);
@@ -106,6 +106,4 @@ void uhf_scene_read_tag_success_on_exit(void* ctx) {
     popup_reset(uhf_app->popup);
     popup_reset(uhf_app->popup);
     // clear widget
     // clear widget
     widget_reset(uhf_app->widget);
     widget_reset(uhf_app->widget);
-
-    // uhf_blink_stop(uhf_app);
 }
 }

+ 74 - 0
scenes/uhf_scene_save_name.c

@@ -0,0 +1,74 @@
+#include "../uhf_app_i.h"
+#include <lib/toolbox/random_name.h>
+#include <gui/modules/validators.h>
+#include <toolbox/path.h>
+
+#define UHF_DEV_NAME_MAX_LEN 22
+#define UHF_APP_EXTENSION ".uhf"
+
+void uhf_scene_save_name_text_input_callback(void* context) {
+    UHFApp* uhf_app = context;
+
+    view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventTextInputDone);
+}
+
+void uhf_scene_save_name_on_enter(void* context) {
+    UHFApp* uhf_app = context;
+
+    // Setup view
+    TextInput* text_input = uhf_app->text_input;
+    bool dev_name_empty = false;
+    set_random_name(uhf_app->text_store, sizeof(uhf_app->text_store));
+    text_input_set_header_text(text_input, "Name the tag");
+    text_input_set_result_callback(
+        text_input,
+        uhf_scene_save_name_text_input_callback,
+        uhf_app,
+        uhf_app->text_store,
+        UHF_DEV_NAME_MAX_LEN,
+        dev_name_empty);
+
+    FuriString* folder_path;
+    folder_path = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX);
+
+    // if(furi_string_end_with(uhf_app->dev->load_path, UHF_APP_EXTENSION)) {
+    //     path_extract_dirname(furi_string_get_cstr(uhf_app->dev->load_path), folder_path);
+    // }
+
+    ValidatorIsFile* validator_is_file =
+        validator_is_file_alloc_init(furi_string_get_cstr(folder_path), UHF_APP_EXTENSION, "test");
+    text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
+
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewTextInput);
+
+    furi_string_free(folder_path);
+}
+
+bool uhf_scene_save_name_on_event(void* context, SceneManagerEvent event) {
+    UHFApp* uhf_app = context;
+    UHFResponseData* uhf_data_save = uhf_app->worker->data;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == UHFCustomEventTextInputDone) {
+            if(uhf_save_data(uhf_data_save, uhf_app->storage, uhf_app->text_store)) {
+                scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveSuccess);
+                consumed = true;
+            } else {
+                consumed = scene_manager_search_and_switch_to_previous_scene(
+                    uhf_app->scene_manager, UHFSceneStart);
+            }
+        }
+    }
+    return consumed;
+}
+
+void uhf_scene_save_name_on_exit(void* context) {
+    UHFApp* uhf_app = context;
+
+    // Clear view
+    void* validator_context = text_input_get_validator_callback_context(uhf_app->text_input);
+    text_input_set_validator(uhf_app->text_input, NULL, NULL);
+    validator_is_file_free(validator_context);
+
+    text_input_reset(uhf_app->text_input);
+}

+ 47 - 0
scenes/uhf_scene_save_success.c

@@ -0,0 +1,47 @@
+#include "../uhf_app_i.h"
+#include <dolphin/dolphin.h>
+
+void uhf_scene_save_success_popup_callback(void* context) {
+    UHFApp* uhf_app = context;
+    view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventViewExit);
+}
+
+void uhf_scene_save_success_on_enter(void* context) {
+    UHFApp* uhf_app = context;
+    dolphin_deed(DolphinDeedNfcSave);
+
+    // Setup view
+    Popup* popup = uhf_app->popup;
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
+    popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
+    popup_set_timeout(popup, 1500);
+    popup_set_context(popup, uhf_app);
+    popup_set_callback(popup, uhf_scene_save_success_popup_callback);
+    popup_enable_timeout(popup);
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewPopup);
+}
+
+bool uhf_scene_save_success_on_event(void* context, SceneManagerEvent event) {
+    UHFApp* uhf_app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == UHFCustomEventViewExit) {
+            if(scene_manager_has_previous_scene(uhf_app->scene_manager, UHFSceneCardMenu)) {
+                consumed = scene_manager_search_and_switch_to_previous_scene(
+                    uhf_app->scene_manager, UHFSceneCardMenu);
+            } else {
+                consumed = scene_manager_search_and_switch_to_previous_scene(
+                    uhf_app->scene_manager, UHFSceneStart);
+            }
+        }
+    }
+    return consumed;
+}
+
+void uhf_scene_save_success_on_exit(void* context) {
+    UHFApp* uhf_app = context;
+
+    // Clear view
+    popup_reset(uhf_app->popup);
+}

+ 38 - 0
uhf_app.c

@@ -23,6 +23,37 @@ char* convertToHexString(const uint8_t* array, size_t length) {
     return hexArray;
     return hexArray;
 }
 }
 
 
+bool uhf_save_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename) {
+    bool saved = false;
+    if(!storage_dir_exists(storage, UHF_APPS_DATA_FOLDER)) {
+        storage_simply_mkdir(storage, UHF_APPS_DATA_FOLDER);
+    }
+    if(!storage_dir_exists(storage, UHF_APPS_STORAGE_FOLDER)) {
+        storage_simply_mkdir(storage, UHF_APPS_STORAGE_FOLDER);
+    }
+
+    File* file = storage_file_alloc(storage);
+    char file_path_result[100];
+    strcpy(file_path_result, UHF_APPS_STORAGE_FOLDER);
+    strcat(file_path_result, "/");
+    strcat(file_path_result, filename);
+    strcat(file_path_result, UHF_FILE_EXTENSION);
+    if(storage_file_open(file, file_path_result, FSAM_WRITE, FSOM_OPEN_ALWAYS)) {
+        storage_file_seek(file, 0, true);
+        storage_file_truncate(file);
+        char* hex_data =
+            convertToHexString(uhf_response_data->data->data, uhf_response_data->data->length);
+        storage_file_write(file, "UHF App Version : ", 19);
+        storage_file_write(file, UHF_DATA_VERSION, 2);
+        storage_file_write(file, "\n", 1);
+        storage_file_write(file, hex_data, strlen(hex_data));
+        storage_file_close(file);
+        storage_file_free(file);
+        saved = true;
+    }
+    return saved;
+}
+
 bool uhf_custom_event_callback(void* ctx, uint32_t event) {
 bool uhf_custom_event_callback(void* ctx, uint32_t event) {
     furi_assert(ctx);
     furi_assert(ctx);
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
@@ -59,6 +90,9 @@ UHFApp* uhf_alloc() {
     view_dispatcher_attach_to_gui(
     view_dispatcher_attach_to_gui(
         uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen);
         uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen);
 
 
+    // Storage
+    uhf_app->storage = furi_record_open(RECORD_STORAGE);
+
     // Open Notification record
     // Open Notification record
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
 
 
@@ -127,6 +161,10 @@ void uhf_free(UHFApp* uhf_app) {
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_GUI);
     uhf_app->gui = NULL;
     uhf_app->gui = NULL;
 
 
+    // Storage
+    furi_record_close(RECORD_STORAGE);
+    uhf_app->storage = NULL;
+
     // Notifications
     // Notifications
     furi_record_close(RECORD_NOTIFICATION);
     furi_record_close(RECORD_NOTIFICATION);
     uhf_app->notifications = NULL;
     uhf_app->notifications = NULL;

+ 12 - 2
uhf_app_i.h

@@ -18,13 +18,21 @@
 #include "scenes/uhf_scene.h"
 #include "scenes/uhf_scene.h"
 
 
 #include <storage/storage.h>
 #include <storage/storage.h>
-#include <lib/toolbox/path.h>
+// #include <lib/toolbox/path.h>
+#include <toolbox/path.h>
+#include <flipper_format/flipper_format.h>
 
 
 #include "uhf_app.h"
 #include "uhf_app.h"
 #include "uhf_worker.h"
 #include "uhf_worker.h"
 #include <uhf_rfid_icons.h>
 #include <uhf_rfid_icons.h>
 
 
+#define UHF_DATA_VERSION "V0"
 #define UHF_TEXT_STORE_SIZE 128
 #define UHF_TEXT_STORE_SIZE 128
+#define UHF_APPS_DATA_FOLDER EXT_PATH("apps_data")
+#define UHF_APPS_STORAGE_FOLDER \
+    UHF_APPS_DATA_FOLDER "/"    \
+                         "uhf_rfid"
+#define UHF_FILE_EXTENSION ".uhf"
 
 
 enum UHFCustomEvent {
 enum UHFCustomEvent {
     // Reserve first 100 events for button types and indexes, starting from 0
     // Reserve first 100 events for button types and indexes, starting from 0
@@ -47,7 +55,7 @@ struct UHFApp {
     Gui* gui;
     Gui* gui;
     NotificationApp* notifications;
     NotificationApp* notifications;
     SceneManager* scene_manager;
     SceneManager* scene_manager;
-    // UHFDevice* dev;
+    Storage* storage;
 
 
     char text_store[UHF_TEXT_STORE_SIZE + 1];
     char text_store[UHF_TEXT_STORE_SIZE + 1];
     FuriString* text_box_store;
     FuriString* text_box_store;
@@ -93,3 +101,5 @@ void uhf_show_loading_popup(void* context, bool show);
 bool uhf_is_memset(const uint8_t* data, const uint8_t pattern, size_t size);
 bool uhf_is_memset(const uint8_t* data, const uint8_t pattern, size_t size);
 
 
 char* convertToHexString(const uint8_t* array, size_t length);
 char* convertToHexString(const uint8_t* array, size_t length);
+
+bool uhf_save_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename);