picopass_scene_card_menu.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "../picopass_i.h"
  2. enum SubmenuIndex {
  3. SubmenuIndexSave,
  4. SubmenuIndexSaveAsLF,
  5. SubmenuIndexSaveAsSeader,
  6. SubmenuIndexParse,
  7. SubmenuIndexChangeKey,
  8. SubmenuIndexWrite,
  9. SubmenuIndexEmulate,
  10. SubmenuIndexSavePartial,
  11. };
  12. void picopass_scene_card_menu_submenu_callback(void* context, uint32_t index) {
  13. Picopass* picopass = context;
  14. view_dispatcher_send_custom_event(picopass->view_dispatcher, index);
  15. }
  16. void picopass_scene_card_menu_on_enter(void* context) {
  17. Picopass* picopass = context;
  18. Submenu* submenu = picopass->submenu;
  19. PicopassPacs* pacs = &picopass->dev->dev_data.pacs;
  20. PicopassBlock* card_data = picopass->dev->dev_data.card_data;
  21. PicopassDeviceAuthMethod auth = picopass->dev->dev_data.auth;
  22. PluginWiegand* plugin = picopass->plugin_wiegand;
  23. bool SE = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid &&
  24. 0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0];
  25. bool SR = card_data[10].valid && 0x30 == card_data[10].data[0];
  26. bool has_sio = SE || SR;
  27. bool secured = (card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[7] & PICOPASS_FUSE_CRYPT10) !=
  28. PICOPASS_FUSE_CRYPT0;
  29. bool no_credential = picopass_is_memset(pacs->credential, 0x00, sizeof(pacs->credential));
  30. if(auth == PicopassDeviceAuthMethodFailed) {
  31. submenu_add_item(
  32. submenu,
  33. "Save Partial",
  34. SubmenuIndexSavePartial,
  35. picopass_scene_card_menu_submenu_callback,
  36. picopass);
  37. } else {
  38. submenu_add_item(
  39. submenu, "Save", SubmenuIndexSave, picopass_scene_card_menu_submenu_callback, picopass);
  40. }
  41. if(secured && has_sio) {
  42. submenu_add_item(
  43. submenu,
  44. "Save in Seader fmt",
  45. SubmenuIndexSaveAsSeader,
  46. picopass_scene_card_menu_submenu_callback,
  47. picopass);
  48. }
  49. if(secured && !no_credential) {
  50. submenu_add_item(
  51. submenu,
  52. "Save as LFRFID",
  53. SubmenuIndexSaveAsLF,
  54. picopass_scene_card_menu_submenu_callback,
  55. picopass);
  56. if(plugin) {
  57. // Convert from byte array to uint64_t
  58. uint64_t credential = 0;
  59. memcpy(&credential, pacs->credential, sizeof(uint64_t));
  60. credential = __builtin_bswap64(credential);
  61. size_t format_count = plugin->count(pacs->bitLength, credential);
  62. if(format_count > 0) {
  63. submenu_add_item(
  64. submenu,
  65. "Parse",
  66. SubmenuIndexParse,
  67. picopass_scene_card_menu_submenu_callback,
  68. picopass);
  69. }
  70. }
  71. }
  72. if(auth == PicopassDeviceAuthMethodNone || auth == PicopassDeviceAuthMethodKey) {
  73. submenu_add_item(
  74. submenu,
  75. "Write",
  76. SubmenuIndexWrite,
  77. picopass_scene_card_menu_submenu_callback,
  78. picopass);
  79. submenu_add_item(
  80. submenu,
  81. "Emulate",
  82. SubmenuIndexEmulate,
  83. picopass_scene_card_menu_submenu_callback,
  84. picopass);
  85. if(secured) {
  86. submenu_add_item(
  87. submenu,
  88. "Change Key",
  89. SubmenuIndexChangeKey,
  90. picopass_scene_card_menu_submenu_callback,
  91. picopass);
  92. }
  93. }
  94. submenu_set_selected_item(
  95. picopass->submenu,
  96. scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneCardMenu));
  97. view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewMenu);
  98. }
  99. bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
  100. Picopass* picopass = context;
  101. bool consumed = false;
  102. if(event.type == SceneManagerEventTypeCustom) {
  103. if(event.event == SubmenuIndexSave) {
  104. scene_manager_set_scene_state(
  105. picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave);
  106. scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
  107. picopass->dev->format = PicopassDeviceSaveFormatHF;
  108. consumed = true;
  109. } else if(event.event == SubmenuIndexSavePartial) {
  110. scene_manager_set_scene_state(
  111. picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave);
  112. scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
  113. picopass->dev->format = PicopassDeviceSaveFormatPartial;
  114. consumed = true;
  115. } else if(event.event == SubmenuIndexSaveAsSeader) {
  116. scene_manager_set_scene_state(
  117. picopass->scene_manager, PicopassSceneCardMenu, event.event);
  118. scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
  119. picopass->dev->format = PicopassDeviceSaveFormatSeader;
  120. consumed = true;
  121. } else if(event.event == SubmenuIndexSaveAsLF) {
  122. scene_manager_set_scene_state(
  123. picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSaveAsLF);
  124. picopass->dev->format = PicopassDeviceSaveFormatLF;
  125. scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
  126. consumed = true;
  127. } else if(event.event == SubmenuIndexWrite) {
  128. scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCard);
  129. consumed = true;
  130. } else if(event.event == SubmenuIndexEmulate) {
  131. scene_manager_next_scene(picopass->scene_manager, PicopassSceneEmulate);
  132. consumed = true;
  133. } else if(event.event == SubmenuIndexChangeKey) {
  134. scene_manager_set_scene_state(
  135. picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexChangeKey);
  136. scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu);
  137. consumed = true;
  138. } else if(event.event == SubmenuIndexParse) {
  139. scene_manager_set_scene_state(
  140. picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexParse);
  141. scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats);
  142. consumed = true;
  143. }
  144. } else if(event.type == SceneManagerEventTypeBack) {
  145. consumed = scene_manager_search_and_switch_to_previous_scene(
  146. picopass->scene_manager, PicopassSceneStart);
  147. }
  148. return consumed;
  149. }
  150. void picopass_scene_card_menu_on_exit(void* context) {
  151. Picopass* picopass = context;
  152. submenu_reset(picopass->submenu);
  153. }