MX 1 год назад
Родитель
Сommit
556f7830d5
2 измененных файлов с 100 добавлено и 16 удалено
  1. 9 1
      acknowledgements.h
  2. 91 15
      plugin/wiegand.c

+ 9 - 1
acknowledgements.h

@@ -1,2 +1,10 @@
 const char* acknowledgements_text =
 const char* acknowledgements_text =
-    "The developers of Picopass would like to humbly acknowledge the work of those who came before and made this possible.\nWe stand on the shoulders of giants.\nFlavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and Milosch Meriac for their research on iClass.  Martin HS (holiman) for their work on the loclass library.  Iceman and the Proxmark3 community.";
+    "The developers of Picopass would like to humbly acknowledge the work of those who came before and made this possible. (cont.)\
+    \nWe stand on the shoulders of giants:\
+    \n* Flavio D. Garcia\
+    \n* Gerhard de Koning Gans\
+    \n* Roel Verdult \
+    \n* Milosch Meriac \
+    \nfor their research on iClass.\
+    \nMartin HS (holiman) for their work on the loclass library.\
+    \nIceman and the Proxmark3 community.";

+ 91 - 15
plugin/wiegand.c

@@ -26,16 +26,39 @@ static inline uint8_t evenparity32(uint32_t x) {
     return bit_lib_test_parity_32(x, BitLibParityEven);
     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;
+uint8_t get_bit_by_position(wiegand_message_t* data, uint8_t pos) {
+    if(pos >= data->Length) return false;
+    pos = (data->Length - pos) -
+          1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit.
+    uint8_t result = 0;
+    if(pos > 95)
+        result = 0;
+    else if(pos > 63)
+        result = (data->Top >> (pos - 64)) & 1;
+    else if(pos > 31)
+        result = (data->Mid >> (pos - 32)) & 1;
+    else
+        result = (data->Bot >> pos) & 1;
+    return result;
+}
+
+uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length) {
+    uint64_t result = 0;
+    for(uint8_t i = 0; i < length; i++) {
+        result = (result << 1) | get_bit_by_position(data, firstBit + i);
     }
     }
+    return result;
+}
 
 
+static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* description) {
     wiegand_message_t value;
     wiegand_message_t value;
+    value.Length = bit_length;
     value.Mid = bits >> 32;
     value.Mid = bits >> 32;
     value.Bot = bits;
     value.Bot = bits;
     wiegand_message_t* packed = &value;
     wiegand_message_t* packed = &value;
 
 
+    if(packed->Length != 35) return false; // Wrong length? Stop here.
+
     uint32_t cn = (packed->Bot >> 1) & 0x000FFFFF;
     uint32_t cn = (packed->Bot >> 1) & 0x000FFFFF;
     uint32_t fc = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21));
     uint32_t fc = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21));
     bool valid = (evenparity32((packed->Mid & 0x1) ^ (packed->Bot & 0xB6DB6DB6)) ==
     bool valid = (evenparity32((packed->Mid & 0x1) ^ (packed->Bot & 0xB6DB6DB6)) ==
@@ -48,6 +71,8 @@ static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* d
     if(valid) {
     if(valid) {
         furi_string_cat_printf(description, "C1k35s\nFC: %ld CN: %ld\n", fc, cn);
         furi_string_cat_printf(description, "C1k35s\nFC: %ld CN: %ld\n", fc, cn);
         return 1;
         return 1;
+    } else {
+        FURI_LOG_D(PLUGIN_APP_ID, "C1k35s invalid");
     }
     }
 
 
     return 0;
     return 0;
@@ -89,6 +114,57 @@ static int wiegand_h10301_parse(uint8_t bit_length, uint64_t bits, FuriString* d
 
 
         furi_string_cat_printf(description, "H10301\nFC: %d CN: %d\n", fc, cn);
         furi_string_cat_printf(description, "H10301\nFC: %d CN: %d\n", fc, cn);
         return 1;
         return 1;
+    } else {
+        FURI_LOG_D(PLUGIN_APP_ID, "H10301 invalid");
+    }
+
+    return 0;
+}
+
+static int wiegand_H10304_parse(uint8_t bit_length, uint64_t bits, FuriString* description) {
+    wiegand_message_t value;
+    value.Length = bit_length;
+    value.Mid = bits >> 32;
+    value.Bot = bits;
+    wiegand_message_t* packed = &value;
+
+    if(packed->Length != 37) return false; // Wrong length? Stop here.
+
+    uint32_t fc = get_linear_field(packed, 1, 16);
+    uint32_t cn = get_linear_field(packed, 17, 19);
+    bool valid =
+        (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) &&
+        (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18)));
+
+    if(valid) {
+        furi_string_cat_printf(description, "H10304\nFC: %ld CN: %ld\n", fc, cn);
+        return 1;
+    } else {
+        FURI_LOG_D(PLUGIN_APP_ID, "H10304 invalid");
+    }
+
+    return 0;
+}
+
+static int wiegand_H10302_parse(uint8_t bit_length, uint64_t bits, FuriString* description) {
+    wiegand_message_t value;
+    value.Length = bit_length;
+    value.Mid = bits >> 32;
+    value.Bot = bits;
+    wiegand_message_t* packed = &value;
+
+    if(packed->Length != 37) return false; // Wrong length? Stop here.
+
+    uint64_t cn = get_linear_field(packed, 1, 35);
+    bool valid =
+        (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) &&
+        (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18)));
+
+    if(valid) {
+        furi_string_cat_printf(description, "H10302\nCN: %lld\n", cn);
+        return 1;
+    } else {
+        FURI_LOG_D(PLUGIN_APP_ID, "H10302 invalid");
     }
     }
 
 
     return 0;
     return 0;
@@ -100,12 +176,17 @@ static int wiegand_format_count(uint8_t bit_length, uint64_t bits) {
     int count = 0;
     int count = 0;
     FuriString* ignore = furi_string_alloc();
     FuriString* ignore = furi_string_alloc();
 
 
+    // NOTE: Always update the `total` and add to the wiegand_format_description function
+    // TODO: Make this into a function pointer array
     count += wiegand_h10301_parse(bit_length, bits, ignore);
     count += wiegand_h10301_parse(bit_length, bits, ignore);
     count += wiegand_C1k35s_parse(bit_length, bits, ignore);
     count += wiegand_C1k35s_parse(bit_length, bits, ignore);
+    count += wiegand_H10302_parse(bit_length, bits, ignore);
+    count += wiegand_H10304_parse(bit_length, bits, ignore);
+    int total = 4;
 
 
     furi_string_free(ignore);
     furi_string_free(ignore);
 
 
-    FURI_LOG_I(PLUGIN_APP_ID, "count: %i", count);
+    FURI_LOG_I(PLUGIN_APP_ID, "count: %i/%i", count, total);
     return count;
     return count;
 }
 }
 
 
@@ -115,21 +196,16 @@ static void wiegand_format_description(
     size_t index,
     size_t index,
     FuriString* description) {
     FuriString* description) {
     FURI_LOG_I(PLUGIN_APP_ID, "description %d", index);
     FURI_LOG_I(PLUGIN_APP_ID, "description %d", index);
-    UNUSED(bit_length);
-    UNUSED(bits);
-
-    size_t i = 0;
 
 
-    i += wiegand_h10301_parse(bit_length, bits, description);
-    if(i - 1 == index) {
-        return;
-    }
-    i += wiegand_C1k35s_parse(bit_length, bits, description);
-    if(i - 1 == index) {
+    // Turns out I did this wrong and trying to use the index means the results get repeated.  Instead, just return the results for index == 0
+    if(index != 0) {
         return;
         return;
     }
     }
 
 
-    furi_string_cat_printf(description, "[%i] <name> FC: CN:", index);
+    wiegand_h10301_parse(bit_length, bits, description);
+    wiegand_C1k35s_parse(bit_length, bits, description);
+    wiegand_H10302_parse(bit_length, bits, description);
+    wiegand_H10304_parse(bit_length, bits, description);
 }
 }
 
 
 /* Actual implementation of app<>plugin interface */
 /* Actual implementation of app<>plugin interface */