From f90748930394869b1482211f86b8201a6c8fbd16 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sun, 14 Apr 2024 13:25:53 -0700 Subject: [PATCH] H10301 parsing --- plugin_wiegand.c | 67 ++++++++++++++++++++++++++++++++- scenes/seader_scene_card_menu.c | 26 ++++++------- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/plugin_wiegand.c b/plugin_wiegand.c index bc84299f05b..947665f9d7c 100644 --- a/plugin_wiegand.c +++ b/plugin_wiegand.c @@ -1,14 +1,70 @@ #include "plugin_interface.h" +#include #include +/* + * 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] FC: CN:", index); } diff --git a/scenes/seader_scene_card_menu.c b/scenes/seader_scene_card_menu.c index 813a47ad1a9..f10c3bde554 100644 --- a/scenes/seader_scene_card_menu.c +++ b/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));