picopass_scene_card_menu.c 7.2 KB

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