Przeglądaj źródła

Merge seader from https://github.com/bettse/seader

Willy-JL 1 rok temu
rodzic
commit
f83a18aab9

BIN
seader/.flipcorg/gallery/menu.png


BIN
seader/.flipcorg/gallery/pacs.png


BIN
seader/.flipcorg/gallery/save_menu.png


+ 2 - 0
seader/.github/workflows/main.yml

@@ -7,6 +7,8 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v3
+        with:
+          submodules: 'true'
       - name: Build with ufbt
         uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
         id: build-app

+ 10 - 1
seader/application.fam

@@ -16,10 +16,11 @@ App(
     sources=[
         "*.c",
         "aeabi_uldivmod.sx",
+        "!plugin/*.c",
     ],
     fap_icon="icons/logo.png",
     fap_category="NFC",
-    fap_version="2.6",
+    fap_version="2.7",
     fap_author="bettse",
     #    fap_extbuild=(
     #        ExtFile(
@@ -41,3 +42,11 @@ App(
     fap_weburl="https://seader.ericbetts.dev",
     fap_icon_assets="icons",
 )
+
+App(
+    appid="plugin_wiegand",
+    apptype=FlipperAppType.PLUGIN,
+    entry_point="plugin_wiegand_ep",
+    requires=["seader"],
+    sources=["plugin/wiegand.c"],
+)

+ 0 - 0
seader/fake_screenshot.pxd → seader/media/fake_screenshot.pxd


+ 6 - 0
seader/sam_api.c

@@ -855,6 +855,12 @@ bool seader_process_success_response_i(
     if(rval.code == RC_OK) {
 #ifdef ASN1_DEBUG
         if(online == false) {
+            memset(display, 0, sizeof(display));
+            for(uint8_t i = 0; i < len - 6; i++) {
+                snprintf(display + (i * 2), sizeof(display), "%02x", apdu[i + 6]);
+            }
+            FURI_LOG_D(TAG, "incoming APDU %s", display);
+
             char payloadDebug[384] = {0};
             memset(payloadDebug, 0, sizeof(payloadDebug));
             (&asn_DEF_Payload)

+ 19 - 0
seader/scenes/seader_scene_card_menu.c

@@ -1,6 +1,7 @@
 #include "../seader_i.h"
 
 enum SubmenuIndex {
+    SubmenuIndexParse,
     SubmenuIndexSave,
     SubmenuIndexSavePicopass,
     SubmenuIndexSaveRFID,
@@ -17,8 +18,21 @@ void seader_scene_card_menu_submenu_callback(void* context, uint32_t index) {
 void seader_scene_card_menu_on_enter(void* context) {
     Seader* seader = context;
     SeaderCredential* credential = seader->credential;
+    PluginWiegand* plugin = seader->plugin_wiegand;
     Submenu* submenu = seader->submenu;
 
+    if(plugin) {
+        size_t format_count = plugin->count(credential->bit_length, credential->credential);
+        if(format_count > 0) {
+            submenu_add_item(
+                submenu,
+                "Parse",
+                SubmenuIndexParse,
+                seader_scene_card_menu_submenu_callback,
+                seader);
+        }
+    }
+
     submenu_add_item(
         submenu, "Save", SubmenuIndexSave, seader_scene_card_menu_submenu_callback, seader);
     submenu_add_item(
@@ -85,6 +99,11 @@ bool seader_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
             seader->credential->save_format = SeaderCredentialSaveFormatMFC;
             scene_manager_next_scene(seader->scene_manager, SeaderSceneSaveName);
             consumed = true;
+        } else if(event.event == SubmenuIndexParse) {
+            scene_manager_set_scene_state(
+                seader->scene_manager, SeaderSceneCardMenu, SubmenuIndexParse);
+            scene_manager_next_scene(seader->scene_manager, SeaderSceneFormats);
+            consumed = true;
         }
     } else if(event.type == SceneManagerEventTypeBack) {
         consumed = scene_manager_search_and_switch_to_previous_scene(

+ 1 - 0
seader/scenes/seader_scene_config.h

@@ -15,3 +15,4 @@ ADD_SCENE(seader, delete_success, DeleteSuccess)
 ADD_SCENE(seader, credential_info, CredentialInfo)
 ADD_SCENE(seader, sam_info, SamInfo)
 ADD_SCENE(seader, virtual_credential, VirtualCredential)
+ADD_SCENE(seader, formats, Formats)

+ 16 - 5
seader/scenes/seader_scene_credential_info.c

@@ -16,6 +16,7 @@ void seader_scene_credential_info_widget_callback(
 void seader_scene_credential_info_on_enter(void* context) {
     Seader* seader = context;
     SeaderCredential* credential = seader->credential;
+    PluginWiegand* plugin = seader->plugin_wiegand;
     Widget* widget = seader->widget;
 
     FuriString* type_str = furi_string_alloc();
@@ -23,11 +24,6 @@ void seader_scene_credential_info_on_enter(void* context) {
     FuriString* credential_str = furi_string_alloc();
     FuriString* sio_str = furi_string_alloc();
 
-    dolphin_deed(DolphinDeedNfcReadSuccess);
-
-    // Send notification
-    notification_message(seader->notifications, &sequence_success);
-
     furi_string_set(credential_str, "");
     furi_string_set(bitlength_str, "");
     furi_string_set(sio_str, "");
@@ -53,6 +49,18 @@ void seader_scene_credential_info_on_enter(void* context) {
         seader_scene_credential_info_widget_callback,
         seader);
 
+    if(plugin) {
+        size_t format_count = plugin->count(credential->bit_length, credential->credential);
+        if(format_count > 0) {
+            widget_add_button_element(
+                seader->widget,
+                GuiButtonTypeCenter,
+                "Parse",
+                seader_scene_credential_info_widget_callback,
+                seader);
+        }
+    }
+
     widget_add_string_element(
         widget, 64, 5, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(type_str));
     widget_add_string_element(
@@ -93,6 +101,9 @@ bool seader_scene_credential_info_on_event(void* context, SceneManagerEvent even
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == GuiButtonTypeLeft) {
             consumed = scene_manager_previous_scene(seader->scene_manager);
+        } else if(event.event == GuiButtonTypeCenter) {
+            scene_manager_next_scene(seader->scene_manager, SeaderSceneFormats);
+            consumed = true;
         } else if(event.event == SeaderCustomEventViewExit) {
             view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewWidget);
             consumed = true;

+ 47 - 0
seader/scenes/seader_scene_formats.c

@@ -0,0 +1,47 @@
+#include "../seader_i.h"
+#include <dolphin/dolphin.h>
+
+void seader_scene_formats_on_enter(void* context) {
+    Seader* seader = context;
+    PluginWiegand* plugin = seader->plugin_wiegand;
+    SeaderCredential* credential = seader->credential;
+
+    FuriString* str = seader->text_box_store;
+    furi_string_reset(str);
+
+    if(plugin) {
+        FuriString* description = furi_string_alloc();
+        size_t format_count = plugin->count(credential->bit_length, credential->credential);
+        for(size_t i = 0; i < format_count; i++) {
+            plugin->description(credential->bit_length, credential->credential, i, description);
+
+            furi_string_cat_printf(str, "%s\n", furi_string_get_cstr(description));
+        }
+        furi_string_free(description);
+    }
+
+    text_box_set_font(seader->text_box, TextBoxFontHex);
+    text_box_set_text(seader->text_box, furi_string_get_cstr(seader->text_box_store));
+    view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewTextBox);
+}
+
+bool seader_scene_formats_on_event(void* context, SceneManagerEvent event) {
+    Seader* seader = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == GuiButtonTypeLeft) {
+            consumed = scene_manager_previous_scene(seader->scene_manager);
+        }
+    } else if(event.type == SceneManagerEventTypeBack) {
+        consumed = scene_manager_previous_scene(seader->scene_manager);
+    }
+    return consumed;
+}
+
+void seader_scene_formats_on_exit(void* context) {
+    Seader* seader = context;
+
+    // Clear views
+    text_box_reset(seader->text_box);
+}

+ 3 - 3
seader/scenes/seader_scene_saved_menu.c

@@ -1,8 +1,8 @@
 #include "../seader_i.h"
 
 enum SubmenuIndex {
-    SubmenuIndexDelete,
     SubmenuIndexInfo,
+    SubmenuIndexDelete,
     SubmenuIndexVirtual,
 };
 
@@ -17,10 +17,10 @@ void seader_scene_saved_menu_on_enter(void* context) {
     SeaderCredential* credential = seader->credential;
     Submenu* submenu = seader->submenu;
 
-    submenu_add_item(
-        submenu, "Delete", SubmenuIndexDelete, seader_scene_saved_menu_submenu_callback, seader);
     submenu_add_item(
         submenu, "Info", SubmenuIndexInfo, seader_scene_saved_menu_submenu_callback, seader);
+    submenu_add_item(
+        submenu, "Delete", SubmenuIndexDelete, seader_scene_saved_menu_submenu_callback, seader);
 
     if(credential->sio[0] == 0x30) {
         submenu_add_item(

+ 34 - 0
seader/seader.c

@@ -81,11 +81,38 @@ Seader* seader_alloc() {
     view_dispatcher_add_view(
         seader->view_dispatcher, SeaderViewTextInput, text_input_get_view(seader->text_input));
 
+    // TextBox
+    seader->text_box = text_box_alloc();
+    view_dispatcher_add_view(
+        seader->view_dispatcher, SeaderViewTextBox, text_box_get_view(seader->text_box));
+    seader->text_box_store = furi_string_alloc();
+
     // Custom Widget
     seader->widget = widget_alloc();
     view_dispatcher_add_view(
         seader->view_dispatcher, SeaderViewWidget, widget_get_view(seader->widget));
 
+    seader->plugin_manager =
+        plugin_manager_alloc(PLUGIN_APP_ID, PLUGIN_API_VERSION, firmware_api_interface);
+
+    seader->plugin_wiegand = NULL;
+    if(plugin_manager_load_all(seader->plugin_manager, APP_DATA_PATH("plugins")) !=
+       PluginManagerErrorNone) {
+        FURI_LOG_E(TAG, "Failed to load all libs");
+    } else {
+        uint32_t plugin_count = plugin_manager_get_count(seader->plugin_manager);
+        FURI_LOG_I(TAG, "Loaded %lu plugin(s)", plugin_count);
+
+        for(uint32_t i = 0; i < plugin_count; i++) {
+            const PluginWiegand* plugin = plugin_manager_get_ep(seader->plugin_manager, i);
+            FURI_LOG_I(TAG, "plugin name: %s", plugin->name);
+            if(strcmp(plugin->name, "Plugin Wiegand") == 0) {
+                // Have to cast to drop "const" qualifier
+                seader->plugin_wiegand = (PluginWiegand*)plugin;
+            }
+        }
+    }
+
     return seader;
 }
 
@@ -123,6 +150,11 @@ void seader_free(Seader* seader) {
     view_dispatcher_remove_view(seader->view_dispatcher, SeaderViewTextInput);
     text_input_free(seader->text_input);
 
+    // TextBox
+    view_dispatcher_remove_view(seader->view_dispatcher, SeaderViewTextBox);
+    text_box_free(seader->text_box);
+    furi_string_free(seader->text_box_store);
+
     // Custom Widget
     view_dispatcher_remove_view(seader->view_dispatcher, SeaderViewWidget);
     widget_free(seader->widget);
@@ -145,6 +177,8 @@ void seader_free(Seader* seader) {
     furi_record_close(RECORD_NOTIFICATION);
     seader->notifications = NULL;
 
+    plugin_manager_free(seader->plugin_manager);
+
     free(seader);
 }
 

+ 1 - 0
seader/seader_credential.c

@@ -399,6 +399,7 @@ bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
     FlipperFormat* file = flipper_format_file_alloc(cred->storage);
     FuriString* temp_str = furi_string_alloc();
 
+    storage_simply_mkdir(cred->storage, EXT_PATH("apps_data/picopass"));
     if(use_load_path && !furi_string_empty(cred->load_path)) {
         // Get directory name
         path_extract_dirname(furi_string_get_cstr(cred->load_path), temp_str);

+ 11 - 0
seader/seader_i.h

@@ -20,6 +20,7 @@
 #include <gui/modules/popup.h>
 #include <gui/modules/loading.h>
 #include <gui/modules/text_input.h>
+#include <gui/modules/text_box.h>
 #include <gui/modules/widget.h>
 
 #include <input/input.h>
@@ -42,6 +43,11 @@
 #include <Payload.h>
 #include <FrameProtocol.h>
 
+#include "plugin/interface.h"
+#include <flipper_application/flipper_application.h>
+#include <flipper_application/plugins/plugin_manager.h>
+#include <loader/firmware_api/firmware_api.h>
+
 #include "protocol/picopass_poller.h"
 #include "scenes/seader_scene.h"
 
@@ -105,6 +111,7 @@ struct Seader {
     Popup* popup;
     Loading* loading;
     TextInput* text_input;
+    TextBox* text_box;
     Widget* widget;
 
     Nfc* nfc;
@@ -112,6 +119,9 @@ struct Seader {
     PicopassPoller* picopass_poller;
 
     NfcDevice* nfc_device;
+
+    PluginManager* plugin_manager;
+    PluginWiegand* plugin_wiegand;
 };
 
 struct SeaderPollerContainer {
@@ -124,6 +134,7 @@ typedef enum {
     SeaderViewPopup,
     SeaderViewLoading,
     SeaderViewTextInput,
+    SeaderViewTextBox,
     SeaderViewWidget,
     SeaderViewUart,
 } SeaderView;