usb_ccb.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "usb_ccb.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <notification/notification_messages.h>
  5. #define TAG "UsbCcbApp"
  6. enum UsbDebugSubmenuIndex {
  7. UsbCcbSubmenuIndexAbout,
  8. UsbCcbSubmenuIndexHelp,
  9. UsbCcbSubmenuIndexStart,
  10. };
  11. void usb_ccb_submenu_callback(void* context, uint32_t index) {
  12. furi_assert(context);
  13. UsbCcb* app = context;
  14. if(index == UsbCcbSubmenuIndexAbout) {
  15. app->view_id = UsbCcbViewAbout;
  16. view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewAbout);
  17. } else if(index == UsbCcbSubmenuIndexHelp) {
  18. app->view_id = UsbCcbViewHelp;
  19. view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewHelp);
  20. } else if(index == UsbCcbSubmenuIndexStart) {
  21. app->view_id = UsbCcbViewStart;
  22. view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewStart);
  23. }
  24. }
  25. void usb_ccb_dialog_callback(DialogExResult result, void* context) {
  26. furi_assert(context);
  27. UsbCcb* app = context;
  28. if(result == DialogExResultLeft) {
  29. view_dispatcher_stop(app->view_dispatcher);
  30. } else if(result == DialogExResultRight) {
  31. view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); // Show last view
  32. } else if(result == DialogExResultCenter) {
  33. view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewSubmenu);
  34. }
  35. }
  36. uint32_t usb_ccb_exit_confirm_view(void* context) {
  37. UNUSED(context);
  38. return UsbCcbViewExitConfirm;
  39. }
  40. uint32_t usb_ccb_exit(void* context) {
  41. UNUSED(context);
  42. return VIEW_NONE;
  43. }
  44. UsbCcb* usb_ccb_app_alloc() {
  45. UsbCcb* app = malloc(sizeof(UsbCcb));
  46. // Gui
  47. app->gui = furi_record_open(RECORD_GUI);
  48. // Notifications
  49. app->notifications = furi_record_open(RECORD_NOTIFICATION);
  50. // View dispatcher
  51. app->view_dispatcher = view_dispatcher_alloc();
  52. view_dispatcher_enable_queue(app->view_dispatcher);
  53. view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
  54. // Submenu view
  55. app->submenu = submenu_alloc();
  56. submenu_set_header(app->submenu, "USB Consumer Control");
  57. submenu_add_item(
  58. app->submenu, "About", UsbCcbSubmenuIndexAbout, usb_ccb_submenu_callback, app);
  59. submenu_add_item(app->submenu, "Help", UsbCcbSubmenuIndexHelp, usb_ccb_submenu_callback, app);
  60. submenu_add_item(
  61. app->submenu, "Start", UsbCcbSubmenuIndexStart, usb_ccb_submenu_callback, app);
  62. view_set_previous_callback(submenu_get_view(app->submenu), usb_ccb_exit);
  63. view_dispatcher_add_view(
  64. app->view_dispatcher, UsbCcbViewSubmenu, submenu_get_view(app->submenu));
  65. // Dialog view
  66. app->dialog = dialog_ex_alloc();
  67. dialog_ex_set_result_callback(app->dialog, usb_ccb_dialog_callback);
  68. dialog_ex_set_context(app->dialog, app);
  69. dialog_ex_set_left_button_text(app->dialog, "Exit");
  70. dialog_ex_set_right_button_text(app->dialog, "Stay");
  71. dialog_ex_set_center_button_text(app->dialog, "Menu");
  72. dialog_ex_set_header(app->dialog, "Exit or return to menu?", 64, 11, AlignCenter, AlignTop);
  73. view_dispatcher_add_view(
  74. app->view_dispatcher, UsbCcbViewExitConfirm, dialog_ex_get_view(app->dialog));
  75. // About view
  76. app->usb_ccb_about = usb_ccb_about_alloc();
  77. view_set_previous_callback(
  78. usb_ccb_about_get_view(app->usb_ccb_about), usb_ccb_exit_confirm_view);
  79. view_dispatcher_add_view(
  80. app->view_dispatcher, UsbCcbViewAbout, usb_ccb_about_get_view(app->usb_ccb_about));
  81. // Help view
  82. app->usb_ccb_help = usb_ccb_help_alloc();
  83. view_set_previous_callback(
  84. usb_ccb_help_get_view(app->usb_ccb_help), usb_ccb_exit_confirm_view);
  85. view_dispatcher_add_view(
  86. app->view_dispatcher, UsbCcbViewHelp, usb_ccb_help_get_view(app->usb_ccb_help));
  87. // Start view
  88. app->usb_ccb_start = usb_ccb_start_alloc();
  89. view_set_previous_callback(
  90. usb_ccb_start_get_view(app->usb_ccb_start), usb_ccb_exit_confirm_view);
  91. view_dispatcher_add_view(
  92. app->view_dispatcher, UsbCcbViewStart, usb_ccb_start_get_view(app->usb_ccb_start));
  93. app->view_id = UsbCcbViewSubmenu;
  94. view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
  95. return app;
  96. }
  97. void usb_ccb_app_free(UsbCcb* app) {
  98. furi_assert(app);
  99. // Reset notification
  100. notification_internal_message(app->notifications, &sequence_reset_blue);
  101. // Free views
  102. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewSubmenu);
  103. submenu_free(app->submenu);
  104. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewExitConfirm);
  105. dialog_ex_free(app->dialog);
  106. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewAbout);
  107. usb_ccb_about_free(app->usb_ccb_about);
  108. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewHelp);
  109. usb_ccb_help_free(app->usb_ccb_help);
  110. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewStart);
  111. usb_ccb_start_free(app->usb_ccb_start);
  112. view_dispatcher_free(app->view_dispatcher);
  113. // Close records
  114. furi_record_close(RECORD_GUI);
  115. app->gui = NULL;
  116. furi_record_close(RECORD_NOTIFICATION);
  117. app->notifications = NULL;
  118. // Free rest
  119. free(app);
  120. }
  121. int32_t usb_ccb_app(void* p) {
  122. UNUSED(p);
  123. // Switch profile to Hid
  124. UsbCcb* app = usb_ccb_app_alloc();
  125. FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
  126. furi_hal_usb_unlock();
  127. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  128. view_dispatcher_run(app->view_dispatcher);
  129. // Change back profile
  130. furi_hal_usb_set_config(usb_mode_prev, NULL);
  131. usb_ccb_app_free(app);
  132. return 0;
  133. }