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_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
  53. // Submenu view
  54. app->submenu = submenu_alloc();
  55. submenu_set_header(app->submenu, "USB Consumer Control");
  56. submenu_add_item(
  57. app->submenu, "About", UsbCcbSubmenuIndexAbout, usb_ccb_submenu_callback, app);
  58. submenu_add_item(app->submenu, "Help", UsbCcbSubmenuIndexHelp, usb_ccb_submenu_callback, app);
  59. submenu_add_item(
  60. app->submenu, "Start", UsbCcbSubmenuIndexStart, usb_ccb_submenu_callback, app);
  61. view_set_previous_callback(submenu_get_view(app->submenu), usb_ccb_exit);
  62. view_dispatcher_add_view(
  63. app->view_dispatcher, UsbCcbViewSubmenu, submenu_get_view(app->submenu));
  64. // Dialog view
  65. app->dialog = dialog_ex_alloc();
  66. dialog_ex_set_result_callback(app->dialog, usb_ccb_dialog_callback);
  67. dialog_ex_set_context(app->dialog, app);
  68. dialog_ex_set_left_button_text(app->dialog, "Exit");
  69. dialog_ex_set_right_button_text(app->dialog, "Stay");
  70. dialog_ex_set_center_button_text(app->dialog, "Menu");
  71. dialog_ex_set_header(app->dialog, "Exit or return to menu?", 64, 11, AlignCenter, AlignTop);
  72. view_dispatcher_add_view(
  73. app->view_dispatcher, UsbCcbViewExitConfirm, dialog_ex_get_view(app->dialog));
  74. // About view
  75. app->usb_ccb_about = usb_ccb_about_alloc();
  76. view_set_previous_callback(
  77. usb_ccb_about_get_view(app->usb_ccb_about), usb_ccb_exit_confirm_view);
  78. view_dispatcher_add_view(
  79. app->view_dispatcher, UsbCcbViewAbout, usb_ccb_about_get_view(app->usb_ccb_about));
  80. // Help view
  81. app->usb_ccb_help = usb_ccb_help_alloc();
  82. view_set_previous_callback(
  83. usb_ccb_help_get_view(app->usb_ccb_help), usb_ccb_exit_confirm_view);
  84. view_dispatcher_add_view(
  85. app->view_dispatcher, UsbCcbViewHelp, usb_ccb_help_get_view(app->usb_ccb_help));
  86. // Start view
  87. app->usb_ccb_start = usb_ccb_start_alloc();
  88. view_set_previous_callback(
  89. usb_ccb_start_get_view(app->usb_ccb_start), usb_ccb_exit_confirm_view);
  90. view_dispatcher_add_view(
  91. app->view_dispatcher, UsbCcbViewStart, usb_ccb_start_get_view(app->usb_ccb_start));
  92. app->view_id = UsbCcbViewSubmenu;
  93. view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
  94. return app;
  95. }
  96. void usb_ccb_app_free(UsbCcb* app) {
  97. furi_assert(app);
  98. // Reset notification
  99. notification_internal_message(app->notifications, &sequence_reset_blue);
  100. // Free views
  101. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewSubmenu);
  102. submenu_free(app->submenu);
  103. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewExitConfirm);
  104. dialog_ex_free(app->dialog);
  105. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewAbout);
  106. usb_ccb_about_free(app->usb_ccb_about);
  107. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewHelp);
  108. usb_ccb_help_free(app->usb_ccb_help);
  109. view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewStart);
  110. usb_ccb_start_free(app->usb_ccb_start);
  111. view_dispatcher_free(app->view_dispatcher);
  112. // Close records
  113. furi_record_close(RECORD_GUI);
  114. app->gui = NULL;
  115. furi_record_close(RECORD_NOTIFICATION);
  116. app->notifications = NULL;
  117. // Free rest
  118. free(app);
  119. }
  120. int32_t usb_ccb_app(void* p) {
  121. UNUSED(p);
  122. // Switch profile to Hid
  123. UsbCcb* app = usb_ccb_app_alloc();
  124. FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
  125. furi_hal_usb_unlock();
  126. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  127. view_dispatcher_run(app->view_dispatcher);
  128. // Change back profile
  129. furi_hal_usb_set_config(usb_mode_prev, NULL);
  130. usb_ccb_app_free(app);
  131. return 0;
  132. }