Browse Source

[FL-1475] iButton emulate shortcat (#535)

* ibutton: run emulation when launched with argument
* app-loader: set NULL context when starting application from menu
* ibutton: change p to argc
* ibutton: fix load key data from file
* ibutton: fix memory leak
gornekich 4 năm trước cách đây
mục cha
commit
8cc0a9a998

+ 1 - 0
applications/app-loader/app-loader.c

@@ -28,6 +28,7 @@ static void app_loader_menu_callback(void* _ctx) {
     FURI_LOG_I(APP_LOADER_TAG, "Starting furi application: %s", state.current_app->name);
     furi_thread_set_name(state.thread, flipper_app->name);
     furi_thread_set_stack_size(state.thread, flipper_app->stack_size);
+    furi_thread_set_context(state.thread, NULL);
     furi_thread_set_callback(state.thread, flipper_app->app);
     furi_thread_start(state.thread);
 }

+ 100 - 68
applications/ibutton/ibutton-app.cpp

@@ -6,11 +6,15 @@
 const char* iButtonApp::app_folder = "ibutton";
 const char* iButtonApp::app_extension = ".ibtn";
 
-void iButtonApp::run(void) {
+void iButtonApp::run(void* args) {
     iButtonEvent event;
     bool consumed;
     bool exit = false;
 
+    if(args && load_key((const char*)args)) {
+        current_scene = Scene::SceneEmulate;
+    }
+
     scenes[current_scene]->on_enter(this);
 
     while(!exit) {
@@ -44,6 +48,7 @@ iButtonApp::~iButtonApp() {
         delete it->second;
         scenes.erase(it);
     }
+    delete key_worker;
 
     api_hal_power_insomnia_exit();
 }
@@ -308,44 +313,48 @@ bool iButtonApp::save_key(const char* key_name) {
     return result;
 }
 
-bool iButtonApp::load_key() {
-    bool result = false;
-
-    // Input events and views are managed by file_select
-    bool res = get_sd_ex_api()->file_select(
-        get_sd_ex_api()->context,
-        app_folder,
-        app_extension,
-        get_file_name(),
-        get_file_name_size(),
-        get_key()->get_name());
+bool iButtonApp::load_key_data(string_t key_path) {
+    File key_file;
+    uint16_t read_count;
 
-    if(res) {
-        string_t key_str;
-        File key_file;
-        uint16_t read_count;
+    // Open key file
+    get_fs_api()->file.open(&key_file, string_get_cstr(key_path), FSAM_READ, FSOM_OPEN_EXISTING);
+    if(key_file.error_id != FSE_OK) {
+        show_file_error_message("Cannot open\nkey file");
+        get_fs_api()->file.close(&key_file);
+        return false;
+    }
 
-        // Get key file path
-        string_init_set_str(key_str, app_folder);
-        string_cat_str(key_str, "/");
-        string_cat_str(key_str, get_file_name());
-        string_cat_str(key_str, app_extension);
+    const uint8_t byte_text_size = 4;
+    char byte_text[byte_text_size] = {0, 0, 0, 0};
 
-        // Open key file
-        get_fs_api()->file.open(
-            &key_file, string_get_cstr(key_str), FSAM_READ, FSOM_OPEN_EXISTING);
-        string_clear(key_str);
+    // load type header
+    read_count = get_fs_api()->file.read(&key_file, byte_text, 1);
+    if(key_file.error_id != FSE_OK || read_count != 1) {
+        show_file_error_message("Cannot read\nkey file");
+        get_fs_api()->file.close(&key_file);
+        return false;
+    }
 
-        if(key_file.error_id != FSE_OK) {
-            show_file_error_message("Cannot open\nkey file");
-            get_fs_api()->file.close(&key_file);
-            return false;
-        }
+    iButtonKeyType key_type = iButtonKeyType::KeyCyfral;
+    if(strcmp(byte_text, "C") == 0) {
+        key_type = iButtonKeyType::KeyCyfral;
+    } else if(strcmp(byte_text, "M") == 0) {
+        key_type = iButtonKeyType::KeyMetakom;
+    } else if(strcmp(byte_text, "D") == 0) {
+        key_type = iButtonKeyType::KeyDallas;
+    } else {
+        show_file_error_message("Cannot parse\nkey file");
+        get_fs_api()->file.close(&key_file);
+        return false;
+    }
 
-        const uint8_t byte_text_size = 4;
-        char byte_text[byte_text_size] = {0, 0, 0, 0};
+    get_key()->set_type(key_type);
 
-        // load type header
+    // load data
+    uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0};
+    for(uint8_t i = 0; i < get_key()->get_type_data_size(); i++) {
+        // space
         read_count = get_fs_api()->file.read(&key_file, byte_text, 1);
         if(key_file.error_id != FSE_OK || read_count != 1) {
             show_file_error_message("Cannot read\nkey file");
@@ -353,51 +362,74 @@ bool iButtonApp::load_key() {
             return false;
         }
 
-        iButtonKeyType key_type = iButtonKeyType::KeyCyfral;
-        if(strcmp(byte_text, "C") == 0) {
-            key_type = iButtonKeyType::KeyCyfral;
-        } else if(strcmp(byte_text, "M") == 0) {
-            key_type = iButtonKeyType::KeyMetakom;
-        } else if(strcmp(byte_text, "D") == 0) {
-            key_type = iButtonKeyType::KeyDallas;
-        } else {
-            show_file_error_message("Cannot parse\nkey file");
+        // value
+        read_count = get_fs_api()->file.read(&key_file, byte_text, 2);
+        if(key_file.error_id != FSE_OK || read_count != 2) {
+            show_file_error_message("Cannot read\nkey file");
             get_fs_api()->file.close(&key_file);
             return false;
         }
 
-        get_key()->set_type(key_type);
+        // convert hex value to byte
+        key_data[i] = strtol(byte_text, NULL, 16);
+    }
 
-        // load data
-        uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0};
-        for(uint8_t i = 0; i < get_key()->get_type_data_size(); i++) {
-            // space
-            read_count = get_fs_api()->file.read(&key_file, byte_text, 1);
-            if(key_file.error_id != FSE_OK || read_count != 1) {
-                show_file_error_message("Cannot read\nkey file");
-                get_fs_api()->file.close(&key_file);
-                return false;
-            }
+    get_fs_api()->file.close(&key_file);
 
-            // value
-            read_count = get_fs_api()->file.read(&key_file, byte_text, 2);
-            if(key_file.error_id != FSE_OK || read_count != 2) {
-                show_file_error_message("Cannot read\nkey file");
-                get_fs_api()->file.close(&key_file);
-                return false;
-            }
+    get_key()->set_type(key_type);
+    get_key()->set_data(key_data, IBUTTON_KEY_DATA_SIZE);
 
-            // convert hex value to byte
-            key_data[i] = strtol(byte_text, NULL, 16);
-        }
+    return true;
+}
 
-        get_fs_api()->file.close(&key_file);
+bool iButtonApp::load_key(const char* key_name) {
+    bool result = false;
+    string_t key_path;
 
-        get_key()->set_name(get_file_name());
-        get_key()->set_type(key_type);
-        get_key()->set_data(key_data, IBUTTON_KEY_DATA_SIZE);
+    string_init_set_str(key_path, key_name);
+    if(!string_start_with_str_p(key_path, app_folder) ||
+       !string_end_with_str_p(key_path, app_extension)) {
+        string_clear(key_path);
+        return false;
+    }
 
-        result = true;
+    result = load_key_data(key_path);
+    if(result) {
+        uint8_t folder_end = strlen(app_folder) + 1;
+        uint8_t extension_start = string_size(key_path) - strlen(app_extension);
+        string_mid(key_path, folder_end, extension_start - folder_end);
+        get_key()->set_name(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 = get_sd_ex_api()->file_select(
+        get_sd_ex_api()->context,
+        app_folder,
+        app_extension,
+        get_file_name(),
+        get_file_name_size(),
+        get_key()->get_name());
+
+    if(res) {
+        string_t key_str;
+
+        // Get key file path
+        string_init_set_str(key_str, app_folder);
+        string_cat_str(key_str, "/");
+        string_cat_str(key_str, get_file_name());
+        string_cat_str(key_str, app_extension);
+
+        result = load_key_data(key_str);
+        if(result) {
+            get_key()->set_name(get_file_name());
+        }
+        string_clear(key_str);
     }
 
     get_sd_ex_api()->check_error(get_sd_ex_api()->context);

+ 3 - 1
applications/ibutton/ibutton-app.h

@@ -39,7 +39,7 @@
 
 class iButtonApp {
 public:
-    void run(void);
+    void run(void* args);
 
     iButtonApp();
     ~iButtonApp();
@@ -100,6 +100,7 @@ public:
 
     bool save_key(const char* key_name);
     bool load_key();
+    bool load_key(const char* key_name);
     bool delete_key();
 
 private:
@@ -146,4 +147,5 @@ private:
     static const char* app_extension;
 
     void show_file_error_message(const char* error_text);
+    bool load_key_data(string_t key_path);
 };

+ 1 - 1
applications/ibutton/ibutton.cpp

@@ -3,7 +3,7 @@
 // app enter function
 extern "C" int32_t app_ibutton(void* p) {
     iButtonApp* app = new iButtonApp();
-    app->run();
+    app->run(p);
     delete app;
 
     return 255;