Jelajahi Sumber

Merge picopass/plugin from https://gitlab.com/bettse/flipper-wiegand-plugin

Willy-JL 1 tahun lalu
induk
melakukan
e0b5fee942
2 mengubah file dengan 282 tambahan dan 15 penghapusan
  1. 191 0
      picopass/plugin/.clang-format
  2. 91 15
      picopass/plugin/wiegand.c

+ 191 - 0
picopass/plugin/.clang-format

@@ -0,0 +1,191 @@
+---
+Language:        Cpp
+AccessModifierOffset: -4
+AlignAfterOpenBracket: AlwaysBreak
+AlignArrayOfStructures: None
+AlignConsecutiveMacros: None
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: None
+AlignEscapedNewlines: Left
+AlignOperands:   Align
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: WithoutElse
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros:
+  - __capability
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  AfterExternBlock: false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: true
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit:     99
+CommentPragmas:  '^ IWYU pragma:'
+QualifierAlignment: Leave
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+PackConstructorInitializers: BinPack
+BasedOnStyle:    ''
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+AllowAllConstructorInitializersOnNextLine: true
+FixNamespaceComments: false
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseLabels: false
+IndentCaseBlocks: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentExternBlock: AfterExternBlock
+IndentRequires:  false
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+LambdaBodyIndentation: Signature
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 10
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 10
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+PenaltyIndentedWhitespace: 0
+PointerAlignment: Left
+PPIndentWidth:   -1
+ReferenceAlignment: Pointer
+ReflowComments:  false
+RemoveBracesLLVM: false
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes:    Never
+SortJavaStaticImport: Before
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: Never
+SpaceBeforeParensOptions:
+  AfterControlStatements: false
+  AfterForeachMacros: false
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   false
+  AfterOverloadedOperator: false
+  BeforeNonEmptyParentheses: false
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+BitFieldColonSpacing: Both
+Standard:        c++03
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        4
+UseCRLF:         false
+UseTab:          Never
+WhitespaceSensitiveMacros:
+  - STRINGIZE
+  - PP_STRINGIZE
+  - BOOST_PP_STRINGIZE
+  - NS_SWIFT_NAME
+  - CF_SWIFT_NAME
+...
+

+ 91 - 15
picopass/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 */