picopass_scene_read_card.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "../picopass_i.h"
  2. #include <dolphin/dolphin.h>
  3. #include "../picopass_keys.h"
  4. enum {
  5. PicopassSceneReadCardDictStandard,
  6. PicopassSceneReadCardDictElite,
  7. };
  8. static bool picopass_read_card_change_dict(Picopass* picopass) {
  9. bool success = false;
  10. do {
  11. uint32_t scene_state =
  12. scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneReadCard);
  13. keys_dict_free(picopass->dict);
  14. picopass->dict = NULL;
  15. if(scene_state == PicopassSceneReadCardDictElite) break;
  16. if(!keys_dict_check_presence(PICOPASS_ICLASS_ELITE_DICT_FLIPPER_NAME)) break;
  17. picopass->dict = keys_dict_alloc(
  18. PICOPASS_ICLASS_ELITE_DICT_FLIPPER_NAME, KeysDictModeOpenExisting, PICOPASS_KEY_LEN);
  19. scene_manager_set_scene_state(
  20. picopass->scene_manager, PicopassSceneReadCard, PicopassSceneReadCardDictElite);
  21. success = true;
  22. } while(false);
  23. return success;
  24. }
  25. NfcCommand picopass_read_card_worker_callback(PicopassPollerEvent event, void* context) {
  26. furi_assert(context);
  27. NfcCommand command = NfcCommandContinue;
  28. Picopass* picopass = context;
  29. if(event.type == PicopassPollerEventTypeRequestMode) {
  30. event.data->req_mode.mode = PicopassPollerModeRead;
  31. } else if(event.type == PicopassPollerEventTypeRequestKey) {
  32. uint8_t key[PICOPASS_KEY_LEN] = {};
  33. bool is_key_provided = true;
  34. if(!keys_dict_get_next_key(picopass->dict, key, PICOPASS_KEY_LEN)) {
  35. if(picopass_read_card_change_dict(picopass)) {
  36. is_key_provided = keys_dict_get_next_key(picopass->dict, key, PICOPASS_KEY_LEN);
  37. } else {
  38. is_key_provided = false;
  39. }
  40. }
  41. uint32_t scene_state =
  42. scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneReadCard);
  43. memcpy(event.data->req_key.key, key, PICOPASS_KEY_LEN);
  44. event.data->req_key.is_elite_key = (scene_state == PicopassSceneReadCardDictElite);
  45. event.data->req_key.is_key_provided = is_key_provided;
  46. } else if(event.type == PicopassPollerEventTypeSuccess) {
  47. const PicopassDeviceData* data = picopass_poller_get_data(picopass->poller);
  48. memcpy(&picopass->dev->dev_data, data, sizeof(PicopassDeviceData));
  49. view_dispatcher_send_custom_event(
  50. picopass->view_dispatcher, PicopassCustomEventPollerSuccess);
  51. } else if(event.type == PicopassPollerEventTypeFail) {
  52. const PicopassDeviceData* data = picopass_poller_get_data(picopass->poller);
  53. memcpy(&picopass->dev->dev_data, data, sizeof(PicopassDeviceData));
  54. view_dispatcher_send_custom_event(
  55. picopass->view_dispatcher, PicopassCustomEventPollerSuccess);
  56. }
  57. return command;
  58. }
  59. void picopass_scene_read_card_on_enter(void* context) {
  60. Picopass* picopass = context;
  61. dolphin_deed(DolphinDeedNfcRead);
  62. // Setup view
  63. Popup* popup = picopass->popup;
  64. popup_set_header(popup, "Detecting\npicopass\ncard", 68, 30, AlignLeft, AlignTop);
  65. popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
  66. picopass->dict = keys_dict_alloc(
  67. PICOPASS_ICLASS_STANDARD_DICT_FLIPPER_NAME, KeysDictModeOpenExisting, PICOPASS_KEY_LEN);
  68. scene_manager_set_scene_state(
  69. picopass->scene_manager, PicopassSceneReadCard, PicopassSceneReadCardDictStandard);
  70. // Start worker
  71. picopass->poller = picopass_poller_alloc(picopass->nfc);
  72. picopass_poller_start(picopass->poller, picopass_read_card_worker_callback, picopass);
  73. view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup);
  74. picopass_blink_start(picopass);
  75. }
  76. bool picopass_scene_read_card_on_event(void* context, SceneManagerEvent event) {
  77. Picopass* picopass = context;
  78. bool consumed = false;
  79. if(event.type == SceneManagerEventTypeCustom) {
  80. if(event.event == PicopassCustomEventPollerSuccess) {
  81. if(memcmp(
  82. picopass->dev->dev_data.pacs.key,
  83. picopass_factory_debit_key,
  84. PICOPASS_BLOCK_LEN) == 0) {
  85. scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadFactorySuccess);
  86. } else {
  87. scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess);
  88. }
  89. consumed = true;
  90. }
  91. }
  92. return consumed;
  93. }
  94. void picopass_scene_read_card_on_exit(void* context) {
  95. Picopass* picopass = context;
  96. if(picopass->dict) {
  97. keys_dict_free(picopass->dict);
  98. picopass->dict = NULL;
  99. }
  100. picopass_poller_stop(picopass->poller);
  101. picopass_poller_free(picopass->poller);
  102. // Clear view
  103. popup_reset(picopass->popup);
  104. scene_manager_set_scene_state(
  105. picopass->scene_manager, PicopassSceneReadCard, PicopassSceneReadCardDictStandard);
  106. picopass_blink_stop(picopass);
  107. }