From 4aeb5f46149417e158352b9b977152fc8f8fcc40 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sun, 14 Apr 2024 14:43:22 -0700 Subject: [PATCH] add C1k35s --- plugin_wiegand.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/plugin_wiegand.c b/plugin_wiegand.c index 947665f9d7c..51d69734391 100644 --- a/plugin_wiegand.c +++ b/plugin_wiegand.c @@ -9,11 +9,51 @@ * 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); +// Structure for packed wiegand messages +// Always align lowest value (last transmitted) bit to ordinal position 0 (lowest valued bit bottom) +typedef struct { + uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) + uint32_t Top; // Bits in x<<64 positions + uint32_t Mid; // Bits in x<<32 positions + uint32_t Bot; // Lowest ordinal positions +} wiegand_message_t; + +static inline uint8_t oddparity32(uint32_t x) { + return bit_lib_test_parity_32(x, BitLibParityOdd); +} + +static inline uint8_t evenparity32(uint32_t x) { + return bit_lib_test_parity_32(x, BitLibParityEven); +} +static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { + if(bit_length != 35) { + return 0; + } + + wiegand_message_t value; + value.Mid = bits >> 32; + value.Bot = bits; + wiegand_message_t* packed = &value; + + uint32_t cn = (packed->Bot >> 1) & 0x000FFFFF; + uint32_t fc = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); + bool valid = (evenparity32((packed->Mid & 0x1) ^ (packed->Bot & 0xB6DB6DB6)) == + ((packed->Mid >> 1) & 1)) && + (oddparity32((packed->Mid & 0x3) ^ (packed->Bot & 0x6DB6DB6C)) == + ((packed->Bot >> 0) & 1)) && + (oddparity32((packed->Mid & 0x3) ^ (packed->Bot & 0xFFFFFFFF)) == + ((packed->Mid >> 2) & 1)); + + if(valid) { + furi_string_cat_printf(description, "C1k35s\nFC: %ld CN: %ld\n", fc, cn); + return 1; + } + + return 0; +} + +static int wiegand_h10301_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { if(bit_length != 26) { return 0; } @@ -60,6 +100,7 @@ static int wiegand_format_count(uint8_t bit_length, uint64_t bits) { FuriString* ignore = furi_string_alloc(); count += wiegand_h10301_parse(bit_length, bits, ignore); + count += wiegand_C1k35s_parse(bit_length, bits, ignore); furi_string_free(ignore); @@ -82,6 +123,10 @@ static void wiegand_format_description( if(i - 1 == index) { return; } + i += wiegand_C1k35s_parse(bit_length, bits, description); + if(i - 1 == index) { + return; + } furi_string_cat_printf(description, "[%i] FC: CN:", index); }