plugin_wiegand.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include "plugin_interface.h"
  2. #include <lib/bit_lib/bit_lib.h>
  3. #include <flipper_application/flipper_application.h>
  4. /*
  5. * Huge thanks to the proxmark codebase:
  6. * https://github.com/RfidResearchGroup/proxmark3/blob/master/client/src/wiegand_formats.c
  7. */
  8. static int wiegand_h10301_parse(uint8_t bit_length, uint64_t bits, FuriString* description) {
  9. UNUSED(description);
  10. UNUSED(bits);
  11. UNUSED(bit_length);
  12. if(bit_length != 26) {
  13. return 0;
  14. }
  15. //E XXXX XXXX XXXX
  16. //XXXX XXXX XXXX O
  17. uint32_t eBitMask = 0x02000000;
  18. uint32_t oBitMask = 0x00000001;
  19. uint32_t eParityMask = 0x01FFE000;
  20. uint32_t oParityMask = 0x00001FFE;
  21. uint8_t eBit = (eBitMask & bits) >> 25;
  22. uint8_t oBit = (oBitMask & bits) >> 0;
  23. bool eParity = bit_lib_test_parity_32((bits & eParityMask) >> 13, BitLibParityEven) &&
  24. eBit == 1;
  25. bool oParity = bit_lib_test_parity_32((bits & oParityMask) >> 1, BitLibParityOdd) && oBit == 1;
  26. FURI_LOG_D(
  27. PLUGIN_APP_ID,
  28. "eBit: %d, oBit: %d, eParity: %d, oParity: %d",
  29. eBit,
  30. oBit,
  31. eParity,
  32. oParity);
  33. if(eParity && oParity) {
  34. uint32_t cnMask = 0x1FFFE;
  35. uint16_t cn = ((bits & cnMask) >> 1);
  36. uint32_t fcMask = 0x1FE0000;
  37. uint16_t fc = ((bits & fcMask) >> 17);
  38. furi_string_cat_printf(description, "H10301\nFC: %d CN: %d\n", fc, cn);
  39. return 1;
  40. }
  41. return 0;
  42. }
  43. static int wiegand_format_count(uint8_t bit_length, uint64_t bits) {
  44. UNUSED(bit_length);
  45. UNUSED(bits);
  46. int count = 0;
  47. FuriString* ignore = furi_string_alloc();
  48. count += wiegand_h10301_parse(bit_length, bits, ignore);
  49. furi_string_free(ignore);
  50. FURI_LOG_I(PLUGIN_APP_ID, "count: %i", count);
  51. return count;
  52. }
  53. static void wiegand_format_description(
  54. uint8_t bit_length,
  55. uint64_t bits,
  56. size_t index,
  57. FuriString* description) {
  58. FURI_LOG_I(PLUGIN_APP_ID, "description %d", index);
  59. UNUSED(bit_length);
  60. UNUSED(bits);
  61. size_t i = 0;
  62. i += wiegand_h10301_parse(bit_length, bits, description);
  63. if(i - 1 == index) {
  64. return;
  65. }
  66. furi_string_cat_printf(description, "[%i] <name> FC: CN:", index);
  67. }
  68. /* Actual implementation of app<>plugin interface */
  69. static const PluginWiegand plugin_wiegand = {
  70. .name = "Plugin Wiegand",
  71. .count = &wiegand_format_count,
  72. .description = &wiegand_format_description,
  73. };
  74. /* Plugin descriptor to comply with basic plugin specification */
  75. static const FlipperAppPluginDescriptor plugin_wiegand_descriptor = {
  76. .appid = PLUGIN_APP_ID,
  77. .ep_api_version = PLUGIN_API_VERSION,
  78. .entry_point = &plugin_wiegand,
  79. };
  80. /* Plugin entry point - must return a pointer to const descriptor */
  81. const FlipperAppPluginDescriptor* plugin_wiegand_ep(void) {
  82. return &plugin_wiegand_descriptor;
  83. }