picopass_scene_card_menu.c 7.7 KB

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