uhf_app.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include "uhf_app_i.h"
  2. static const char* uhf_file_header = "Flipper UHF device";
  3. static const uint32_t uhf_file_version = 1;
  4. // empty callback
  5. void empty_rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
  6. UNUSED(event);
  7. UNUSED(data);
  8. UNUSED(ctx);
  9. }
  10. char* convertToHexString(const uint8_t* array, size_t length) {
  11. if(array == NULL || length == 0) {
  12. return NULL;
  13. }
  14. // Each byte takes 3 characters in the hex representation (2 characters + space), plus 1 for the null terminator
  15. size_t hexLength = (length * 3) + 1;
  16. char* hexArray = (char*)malloc(hexLength * sizeof(char));
  17. if(hexArray == NULL) {
  18. return NULL;
  19. }
  20. size_t index = 0;
  21. for(size_t i = 0; i < length; i++) {
  22. index += snprintf(&hexArray[index], hexLength - index, "%02x ", array[i]);
  23. }
  24. hexArray[hexLength - 1] = '\0';
  25. return hexArray;
  26. }
  27. bool uhf_save_read_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename) {
  28. if(!storage_dir_exists(storage, UHF_APPS_DATA_FOLDER)) {
  29. storage_simply_mkdir(storage, UHF_APPS_DATA_FOLDER);
  30. }
  31. if(!storage_dir_exists(storage, UHF_APPS_STORAGE_FOLDER)) {
  32. storage_simply_mkdir(storage, UHF_APPS_STORAGE_FOLDER);
  33. }
  34. FlipperFormat* file = flipper_format_file_alloc(storage);
  35. FuriString* temp_str = furi_string_alloc();
  36. // set file name
  37. furi_string_cat_printf(
  38. temp_str, "%s/%s%s", UHF_APPS_STORAGE_FOLDER, filename, UHF_FILE_EXTENSION);
  39. // open file
  40. if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) return false;
  41. // write header
  42. if(!flipper_format_write_header_cstr(file, uhf_file_header, uhf_file_version)) return false;
  43. // write epc bank
  44. if(!flipper_format_write_hex(
  45. file, "EPC", uhf_response_data->data->data, uhf_response_data->data->length))
  46. return false;
  47. furi_string_free(temp_str);
  48. flipper_format_free(file);
  49. return true;
  50. }
  51. bool uhf_custom_event_callback(void* ctx, uint32_t event) {
  52. furi_assert(ctx);
  53. UHFApp* uhf_app = ctx;
  54. return scene_manager_handle_custom_event(uhf_app->scene_manager, event);
  55. }
  56. bool uhf_back_event_callback(void* ctx) {
  57. furi_assert(ctx);
  58. UHFApp* uhf_app = ctx;
  59. return scene_manager_handle_back_event(uhf_app->scene_manager);
  60. }
  61. void uhf_tick_event_callback(void* ctx) {
  62. furi_assert(ctx);
  63. UHFApp* uhf_app = ctx;
  64. scene_manager_handle_tick_event(uhf_app->scene_manager);
  65. }
  66. UHFApp* uhf_alloc() {
  67. UHFApp* uhf_app = (UHFApp*)malloc(sizeof(UHFApp));
  68. uhf_app->worker = (UHFWorker*)uhf_worker_alloc();
  69. uhf_app->view_dispatcher = view_dispatcher_alloc();
  70. uhf_app->scene_manager = scene_manager_alloc(&uhf_scene_handlers, uhf_app);
  71. view_dispatcher_enable_queue(uhf_app->view_dispatcher);
  72. view_dispatcher_set_event_callback_context(uhf_app->view_dispatcher, uhf_app);
  73. view_dispatcher_set_custom_event_callback(uhf_app->view_dispatcher, uhf_custom_event_callback);
  74. view_dispatcher_set_navigation_event_callback(
  75. uhf_app->view_dispatcher, uhf_back_event_callback);
  76. view_dispatcher_set_tick_event_callback(
  77. uhf_app->view_dispatcher, uhf_tick_event_callback, 100);
  78. // Open GUI record
  79. uhf_app->gui = furi_record_open(RECORD_GUI);
  80. view_dispatcher_attach_to_gui(
  81. uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen);
  82. // Storage
  83. uhf_app->storage = furi_record_open(RECORD_STORAGE);
  84. // Open Notification record
  85. uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
  86. // Submenu
  87. uhf_app->submenu = submenu_alloc();
  88. view_dispatcher_add_view(
  89. uhf_app->view_dispatcher, UHFViewMenu, submenu_get_view(uhf_app->submenu));
  90. // Popup
  91. uhf_app->popup = popup_alloc();
  92. view_dispatcher_add_view(
  93. uhf_app->view_dispatcher, UHFViewPopup, popup_get_view(uhf_app->popup));
  94. // Loading
  95. uhf_app->loading = loading_alloc();
  96. view_dispatcher_add_view(
  97. uhf_app->view_dispatcher, UHFViewLoading, loading_get_view(uhf_app->loading));
  98. // Text Input
  99. uhf_app->text_input = text_input_alloc();
  100. view_dispatcher_add_view(
  101. uhf_app->view_dispatcher, UHFViewTextInput, text_input_get_view(uhf_app->text_input));
  102. // Custom Widget
  103. uhf_app->widget = widget_alloc();
  104. view_dispatcher_add_view(
  105. uhf_app->view_dispatcher, UHFViewWidget, widget_get_view(uhf_app->widget));
  106. return uhf_app;
  107. }
  108. void uhf_free(UHFApp* uhf_app) {
  109. furi_assert(uhf_app);
  110. // Submenu
  111. view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewMenu);
  112. submenu_free(uhf_app->submenu);
  113. // Popup
  114. view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewPopup);
  115. popup_free(uhf_app->popup);
  116. // Loading
  117. view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewLoading);
  118. loading_free(uhf_app->loading);
  119. // TextInput
  120. view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewTextInput);
  121. text_input_free(uhf_app->text_input);
  122. // Custom Widget
  123. view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewWidget);
  124. widget_free(uhf_app->widget);
  125. // Worker
  126. uhf_worker_stop(uhf_app->worker);
  127. uhf_worker_free(uhf_app->worker);
  128. // View Dispatcher
  129. view_dispatcher_free(uhf_app->view_dispatcher);
  130. // Scene Manager
  131. scene_manager_free(uhf_app->scene_manager);
  132. // GUI
  133. furi_record_close(RECORD_GUI);
  134. uhf_app->gui = NULL;
  135. // Storage
  136. furi_record_close(RECORD_STORAGE);
  137. uhf_app->storage = NULL;
  138. // Notifications
  139. furi_record_close(RECORD_NOTIFICATION);
  140. uhf_app->notifications = NULL;
  141. free(uhf_app);
  142. }
  143. static const NotificationSequence uhf_sequence_blink_start_cyan = {
  144. &message_blink_start_10,
  145. &message_blink_set_color_cyan,
  146. &message_do_not_reset,
  147. NULL,
  148. };
  149. static const NotificationSequence uhf_sequence_blink_stop = {
  150. &message_blink_stop,
  151. NULL,
  152. };
  153. void uhf_blink_start(UHFApp* uhf_app) {
  154. notification_message(uhf_app->notifications, &uhf_sequence_blink_start_cyan);
  155. }
  156. void uhf_blink_stop(UHFApp* uhf_app) {
  157. notification_message(uhf_app->notifications, &uhf_sequence_blink_stop);
  158. }
  159. void uhf_show_loading_popup(void* ctx, bool show) {
  160. UHFApp* uhf_app = ctx;
  161. TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
  162. if(show) {
  163. // Raise timer priority so that animations can play
  164. vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1);
  165. view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewLoading);
  166. } else {
  167. // Restore default timer priority
  168. vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY);
  169. }
  170. }
  171. int32_t uhf_app_main(void* ctx) {
  172. UNUSED(ctx);
  173. UHFApp* uhf_app = uhf_alloc();
  174. // enable 5v pin
  175. furi_hal_power_enable_otg();
  176. scene_manager_next_scene(uhf_app->scene_manager, UHFSceneVerify);
  177. view_dispatcher_run(uhf_app->view_dispatcher);
  178. // disable 5v pin
  179. furi_hal_power_disable_otg();
  180. // set uart callback to none
  181. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, empty_rx_callback, NULL);
  182. // exit app
  183. uhf_free(uhf_app);
  184. return 0;
  185. }