Eric Betts 1 год назад
Родитель
Сommit
f907489303
2 измененных файлов с 78 добавлено и 15 удалено
  1. 65 2
      plugin_wiegand.c
  2. 13 13
      scenes/seader_scene_card_menu.c

+ 65 - 2
plugin_wiegand.c

@@ -1,14 +1,70 @@
 
 #include "plugin_interface.h"
 
+#include <lib/bit_lib/bit_lib.h>
 #include <flipper_application/flipper_application.h>
 
+/*
+ * Huge thanks to the proxmark codebase:
+ * https://github.com/RfidResearchGroup/proxmark3/blob/master/client/src/wiegand_formats.c
+ */
+
+static int wiegand_h10301_parse(uint8_t bit_length, uint64_t bits, FuriString* description) {
+    UNUSED(description);
+    UNUSED(bits);
+    UNUSED(bit_length);
+
+    if(bit_length != 26) {
+        return 0;
+    }
+
+    //E XXXX XXXX XXXX
+    //XXXX XXXX XXXX O
+    uint32_t eBitMask = 0x02000000;
+    uint32_t oBitMask = 0x00000001;
+    uint32_t eParityMask = 0x01FFE000;
+    uint32_t oParityMask = 0x00001FFE;
+    uint8_t eBit = (eBitMask & bits) >> 25;
+    uint8_t oBit = (oBitMask & bits) >> 0;
+
+    bool eParity = bit_lib_test_parity_32((bits & eParityMask) >> 13, BitLibParityEven) &&
+                   eBit == 1;
+    bool oParity = bit_lib_test_parity_32((bits & oParityMask) >> 1, BitLibParityOdd) && oBit == 1;
+
+    FURI_LOG_D(
+        PLUGIN_APP_ID,
+        "eBit: %d, oBit: %d, eParity: %d, oParity: %d",
+        eBit,
+        oBit,
+        eParity,
+        oParity);
+
+    if(eParity && oParity) {
+        uint32_t cnMask = 0x1FFFE;
+        uint16_t cn = ((bits & cnMask) >> 1);
+
+        uint32_t fcMask = 0x1FE0000;
+        uint16_t fc = ((bits & fcMask) >> 17);
+
+        furi_string_cat_printf(description, "H10301\nFC: %d CN: %d\n", fc, cn);
+        return 1;
+    }
+
+    return 0;
+}
+
 static int wiegand_format_count(uint8_t bit_length, uint64_t bits) {
     UNUSED(bit_length);
     UNUSED(bits);
+    int count = 0;
+    FuriString* ignore = furi_string_alloc();
 
-    FURI_LOG_I(PLUGIN_APP_ID, "count");
-    return 1;
+    count += wiegand_h10301_parse(bit_length, bits, ignore);
+
+    furi_string_free(ignore);
+
+    FURI_LOG_I(PLUGIN_APP_ID, "count: %i", count);
+    return count;
 }
 
 static void wiegand_format_description(
@@ -20,6 +76,13 @@ static void wiegand_format_description(
     UNUSED(bit_length);
     UNUSED(bits);
 
+    size_t i = 0;
+
+    i += wiegand_h10301_parse(bit_length, bits, description);
+    if(i - 1 == index) {
+        return;
+    }
+
     furi_string_cat_printf(description, "[%i] <name> FC: CN:", index);
 }
 

+ 13 - 13
scenes/seader_scene_card_menu.c

@@ -1,12 +1,12 @@
 #include "../seader_i.h"
 
 enum SubmenuIndex {
+    SubmenuIndexParse,
     SubmenuIndexSave,
     SubmenuIndexSavePicopass,
     SubmenuIndexSaveRFID,
     SubmenuIndexSaveSR,
     SubmenuIndexSaveMFC,
-    SubmenuIndexParse,
 };
 
 void seader_scene_card_menu_submenu_callback(void* context, uint32_t index) {
@@ -21,6 +21,18 @@ void seader_scene_card_menu_on_enter(void* context) {
     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(
@@ -46,18 +58,6 @@ void seader_scene_card_menu_on_enter(void* context) {
     submenu_add_item(
         submenu, "Save MFC", SubmenuIndexSaveMFC, seader_scene_card_menu_submenu_callback, seader);
 
-    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_set_selected_item(
         seader->submenu,
         scene_manager_get_scene_state(seader->scene_manager, SeaderSceneCardMenu));