picopass.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "picopass_i.h"
  2. #define TAG "PicoPass"
  3. bool picopass_custom_event_callback(void* context, uint32_t event) {
  4. furi_assert(context);
  5. Picopass* picopass = context;
  6. return scene_manager_handle_custom_event(picopass->scene_manager, event);
  7. }
  8. bool picopass_back_event_callback(void* context) {
  9. furi_assert(context);
  10. Picopass* picopass = context;
  11. return scene_manager_handle_back_event(picopass->scene_manager);
  12. }
  13. void picopass_tick_event_callback(void* context) {
  14. furi_assert(context);
  15. Picopass* picopass = context;
  16. scene_manager_handle_tick_event(picopass->scene_manager);
  17. }
  18. Picopass* picopass_alloc() {
  19. Picopass* picopass = malloc(sizeof(Picopass));
  20. picopass->view_dispatcher = view_dispatcher_alloc();
  21. picopass->scene_manager = scene_manager_alloc(&picopass_scene_handlers, picopass);
  22. view_dispatcher_enable_queue(picopass->view_dispatcher);
  23. view_dispatcher_set_event_callback_context(picopass->view_dispatcher, picopass);
  24. view_dispatcher_set_custom_event_callback(
  25. picopass->view_dispatcher, picopass_custom_event_callback);
  26. view_dispatcher_set_navigation_event_callback(
  27. picopass->view_dispatcher, picopass_back_event_callback);
  28. view_dispatcher_set_tick_event_callback(
  29. picopass->view_dispatcher, picopass_tick_event_callback, 100);
  30. picopass->nfc = nfc_alloc();
  31. // Picopass device
  32. picopass->dev = picopass_device_alloc();
  33. // Open GUI record
  34. picopass->gui = furi_record_open(RECORD_GUI);
  35. view_dispatcher_attach_to_gui(
  36. picopass->view_dispatcher, picopass->gui, ViewDispatcherTypeFullscreen);
  37. // Open Notification record
  38. picopass->notifications = furi_record_open(RECORD_NOTIFICATION);
  39. // Submenu
  40. picopass->submenu = submenu_alloc();
  41. view_dispatcher_add_view(
  42. picopass->view_dispatcher, PicopassViewMenu, submenu_get_view(picopass->submenu));
  43. // Popup
  44. picopass->popup = popup_alloc();
  45. view_dispatcher_add_view(
  46. picopass->view_dispatcher, PicopassViewPopup, popup_get_view(picopass->popup));
  47. // Loading
  48. picopass->loading = loading_alloc();
  49. view_dispatcher_add_view(
  50. picopass->view_dispatcher, PicopassViewLoading, loading_get_view(picopass->loading));
  51. // Text Input
  52. picopass->text_input = text_input_alloc();
  53. view_dispatcher_add_view(
  54. picopass->view_dispatcher,
  55. PicopassViewTextInput,
  56. text_input_get_view(picopass->text_input));
  57. // Byte Input
  58. picopass->byte_input = byte_input_alloc();
  59. view_dispatcher_add_view(
  60. picopass->view_dispatcher,
  61. PicopassViewByteInput,
  62. byte_input_get_view(picopass->byte_input));
  63. // TextBox
  64. picopass->text_box = text_box_alloc();
  65. view_dispatcher_add_view(
  66. picopass->view_dispatcher, PicopassViewTextBox, text_box_get_view(picopass->text_box));
  67. picopass->text_box_store = furi_string_alloc();
  68. // Custom Widget
  69. picopass->widget = widget_alloc();
  70. view_dispatcher_add_view(
  71. picopass->view_dispatcher, PicopassViewWidget, widget_get_view(picopass->widget));
  72. picopass->dict_attack = dict_attack_alloc();
  73. view_dispatcher_add_view(
  74. picopass->view_dispatcher,
  75. PicopassViewDictAttack,
  76. dict_attack_get_view(picopass->dict_attack));
  77. picopass->loclass = loclass_alloc();
  78. view_dispatcher_add_view(
  79. picopass->view_dispatcher, PicopassViewLoclass, loclass_get_view(picopass->loclass));
  80. return picopass;
  81. }
  82. void picopass_free(Picopass* picopass) {
  83. furi_assert(picopass);
  84. // Picopass device
  85. picopass_device_free(picopass->dev);
  86. picopass->dev = NULL;
  87. nfc_free(picopass->nfc);
  88. // Submenu
  89. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewMenu);
  90. submenu_free(picopass->submenu);
  91. // Popup
  92. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewPopup);
  93. popup_free(picopass->popup);
  94. // Loading
  95. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewLoading);
  96. loading_free(picopass->loading);
  97. // TextInput
  98. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewTextInput);
  99. text_input_free(picopass->text_input);
  100. // ByteInput
  101. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewByteInput);
  102. byte_input_free(picopass->byte_input);
  103. // TextBox
  104. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewTextBox);
  105. text_box_free(picopass->text_box);
  106. furi_string_free(picopass->text_box_store);
  107. // Custom Widget
  108. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewWidget);
  109. widget_free(picopass->widget);
  110. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewDictAttack);
  111. dict_attack_free(picopass->dict_attack);
  112. view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewLoclass);
  113. loclass_free(picopass->loclass);
  114. // View Dispatcher
  115. view_dispatcher_free(picopass->view_dispatcher);
  116. // Scene Manager
  117. scene_manager_free(picopass->scene_manager);
  118. // GUI
  119. furi_record_close(RECORD_GUI);
  120. picopass->gui = NULL;
  121. // Notifications
  122. furi_record_close(RECORD_NOTIFICATION);
  123. picopass->notifications = NULL;
  124. free(picopass);
  125. }
  126. void picopass_text_store_set(Picopass* picopass, const char* text, ...) {
  127. va_list args;
  128. va_start(args, text);
  129. vsnprintf(picopass->text_store, sizeof(picopass->text_store), text, args);
  130. va_end(args);
  131. }
  132. void picopass_text_store_clear(Picopass* picopass) {
  133. memset(picopass->text_store, 0, sizeof(picopass->text_store));
  134. }
  135. static const NotificationSequence picopass_sequence_blink_start_cyan = {
  136. &message_blink_start_10,
  137. &message_blink_set_color_cyan,
  138. &message_do_not_reset,
  139. NULL,
  140. };
  141. static const NotificationSequence picopass_sequence_blink_start_magenta = {
  142. &message_blink_start_10,
  143. &message_blink_set_color_magenta,
  144. &message_do_not_reset,
  145. NULL,
  146. };
  147. static const NotificationSequence picopass_sequence_blink_stop = {
  148. &message_blink_stop,
  149. NULL,
  150. };
  151. void picopass_blink_start(Picopass* picopass) {
  152. notification_message(picopass->notifications, &picopass_sequence_blink_start_cyan);
  153. }
  154. void picopass_blink_emulate_start(Picopass* picopass) {
  155. notification_message(picopass->notifications, &picopass_sequence_blink_start_magenta);
  156. }
  157. void picopass_blink_stop(Picopass* picopass) {
  158. notification_message(picopass->notifications, &picopass_sequence_blink_stop);
  159. }
  160. void picopass_show_loading_popup(void* context, bool show) {
  161. Picopass* picopass = context;
  162. if(show) {
  163. // Raise timer priority so that animations can play
  164. furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated);
  165. view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewLoading);
  166. } else {
  167. // Restore default timer priority
  168. furi_timer_set_thread_priority(FuriTimerThreadPriorityNormal);
  169. }
  170. }
  171. static void picopass_migrate_from_old_folder() {
  172. Storage* storage = furi_record_open(RECORD_STORAGE);
  173. storage_common_migrate(storage, "/ext/picopass", STORAGE_APP_DATA_PATH_PREFIX);
  174. furi_record_close(RECORD_STORAGE);
  175. }
  176. bool picopass_is_memset(const uint8_t* data, const uint8_t pattern, size_t size) {
  177. bool result = size > 0;
  178. while(size > 0) {
  179. result &= (*data == pattern);
  180. data++;
  181. size--;
  182. }
  183. return result;
  184. }
  185. int32_t picopass_app(void* p) {
  186. UNUSED(p);
  187. picopass_migrate_from_old_folder();
  188. Picopass* picopass = picopass_alloc();
  189. scene_manager_next_scene(picopass->scene_manager, PicopassSceneStart);
  190. view_dispatcher_run(picopass->view_dispatcher);
  191. picopass_free(picopass);
  192. return 0;
  193. }