picopass_scene_device_info.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "../picopass_i.h"
  2. #include <dolphin/dolphin.h>
  3. void picopass_scene_device_info_widget_callback(
  4. GuiButtonType result,
  5. InputType type,
  6. void* context) {
  7. Picopass* picopass = context;
  8. if(type == InputTypeShort) {
  9. view_dispatcher_send_custom_event(picopass->view_dispatcher, result);
  10. }
  11. }
  12. void picopass_scene_device_info_on_enter(void* context) {
  13. Picopass* picopass = context;
  14. FuriString* csn_str = furi_string_alloc_set("CSN:");
  15. FuriString* credential_str = furi_string_alloc();
  16. FuriString* wiegand_str = furi_string_alloc();
  17. dolphin_deed(DolphinDeedNfcReadSuccess);
  18. // Setup view
  19. PicopassBlock* card_data = picopass->dev->dev_data.card_data;
  20. PicopassPacs* pacs = &picopass->dev->dev_data.pacs;
  21. PluginWiegand* plugin = picopass->plugin_wiegand;
  22. Widget* widget = picopass->widget;
  23. uint8_t csn[PICOPASS_BLOCK_LEN] = {0};
  24. memcpy(csn, card_data[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN);
  25. for(uint8_t i = 0; i < PICOPASS_BLOCK_LEN; i++) {
  26. furi_string_cat_printf(csn_str, "%02X ", csn[i]);
  27. }
  28. bool sio = 0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0];
  29. if(sio) {
  30. furi_string_cat_printf(wiegand_str, "SIO");
  31. } else if(pacs->bitLength == 0 || pacs->bitLength == 255) {
  32. // Neither of these are valid. Indicates the block was all 0x00 or all 0xff
  33. furi_string_cat_printf(wiegand_str, "Invalid PACS");
  34. } else {
  35. size_t bytesLength = pacs->bitLength / 8;
  36. if(pacs->bitLength % 8 > 0) {
  37. // Add extra byte if there are bits remaining
  38. bytesLength++;
  39. }
  40. furi_string_set(credential_str, "");
  41. for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) {
  42. furi_string_cat_printf(credential_str, "%02X", pacs->credential[i]);
  43. }
  44. furi_string_cat_printf(wiegand_str, "%d bits", pacs->bitLength);
  45. if(pacs->sio) { // SR
  46. furi_string_cat_printf(credential_str, " +SIO");
  47. }
  48. }
  49. widget_add_string_element(
  50. widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(csn_str));
  51. widget_add_string_element(
  52. widget, 64, 20, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str));
  53. widget_add_string_element(
  54. widget,
  55. 64,
  56. 36,
  57. AlignCenter,
  58. AlignCenter,
  59. FontSecondary,
  60. furi_string_get_cstr(credential_str));
  61. furi_string_free(csn_str);
  62. furi_string_free(credential_str);
  63. furi_string_free(wiegand_str);
  64. widget_add_button_element(
  65. picopass->widget,
  66. GuiButtonTypeLeft,
  67. "Back",
  68. picopass_scene_device_info_widget_callback,
  69. picopass);
  70. if(plugin) {
  71. // Convert from byte array to uint64_t
  72. uint64_t credential = 0;
  73. memcpy(&credential, pacs->credential, sizeof(uint64_t));
  74. credential = __builtin_bswap64(credential);
  75. size_t format_count = plugin->count(pacs->bitLength, credential);
  76. if(format_count > 0) {
  77. widget_add_button_element(
  78. picopass->widget,
  79. GuiButtonTypeCenter,
  80. "Parse",
  81. picopass_scene_device_info_widget_callback,
  82. picopass);
  83. }
  84. }
  85. widget_add_button_element(
  86. picopass->widget,
  87. GuiButtonTypeRight,
  88. "Raw",
  89. picopass_scene_device_info_widget_callback,
  90. picopass);
  91. view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
  92. }
  93. bool picopass_scene_device_info_on_event(void* context, SceneManagerEvent event) {
  94. Picopass* picopass = context;
  95. bool consumed = false;
  96. if(event.type == SceneManagerEventTypeCustom) {
  97. if(event.event == GuiButtonTypeLeft) {
  98. consumed = scene_manager_previous_scene(picopass->scene_manager);
  99. } else if(event.event == GuiButtonTypeRight) {
  100. scene_manager_next_scene(picopass->scene_manager, PicopassSceneMoreInfo);
  101. consumed = true;
  102. } else if(event.event == GuiButtonTypeCenter) {
  103. scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats);
  104. consumed = true;
  105. } else if(event.event == PicopassCustomEventViewExit) {
  106. view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
  107. consumed = true;
  108. }
  109. } else if(event.type == SceneManagerEventTypeBack) {
  110. consumed = scene_manager_previous_scene(picopass->scene_manager);
  111. }
  112. return consumed;
  113. }
  114. void picopass_scene_device_info_on_exit(void* context) {
  115. Picopass* picopass = context;
  116. // Clear views
  117. widget_reset(picopass->widget);
  118. }