ios_trigger.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "ios_trigger.h"
  2. __int32_t ios_trigger_app(void *p){
  3. //Fake using p to compile
  4. UNUSED(p);
  5. AppStruct* app = appStructAlloc();
  6. bt_disconnect(app->bt);
  7. // Wait 2nd core to update nvm storage
  8. furi_delay_ms(200);
  9. bt_keys_storage_set_storage_path(app->bt, HID_BT_KEYS_STORAGE_PATH);
  10. if(!bt_set_profile(app->bt, BtProfileHidKeyboard)) {
  11. FURI_LOG_E(TAG, "Failed to switch to HID profile");
  12. }
  13. furi_hal_bt_start_advertising();
  14. bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
  15. DOLPHIN_DEED(DolphinDeedPluginStart);
  16. //An event
  17. IosTriggerEvent event;
  18. //List of 8 events
  19. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(IosTriggerEvent));
  20. //A timer
  21. FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
  22. //Callback for the display
  23. view_port_draw_callback_set(app->view_port, draw_callback, app);
  24. //Callback for the inputs passing the list as param
  25. view_port_input_callback_set(app->view_port, input_callback, event_queue);
  26. //Linking the drawin on the display
  27. gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
  28. bool keypressed= false;
  29. //Main loop
  30. while(app->running){
  31. //Geting new event from the envent list in the event variable
  32. //waiting forever if the list is empty
  33. //checking status as ok
  34. furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
  35. //Dealing with events one by one
  36. switch(event.type){
  37. case(EventTypeInput):
  38. //On ne considère que les appuies courts
  39. if(event.input.type == InputTypeShort) {
  40. switch(event.input.key){
  41. case(InputKeyBack):
  42. //Breaking main loop if the back key is pressed
  43. app->shooting = false;
  44. app->running = false;
  45. break;
  46. case(InputKeyOk):
  47. app->shooting = !app->shooting;
  48. if(app->shooting){
  49. app->shots = 0;
  50. //Timer triggered every delay ms
  51. furi_timer_start(timer, app->delay * 1000);
  52. }else{
  53. //Timer triggered every delay ms
  54. furi_timer_stop(timer);
  55. }
  56. break;
  57. case(InputKeyUp):
  58. app->delay++;
  59. break;
  60. case(InputKeyDown):
  61. app->delay--;
  62. break;
  63. case(InputKeyLeft):
  64. break;
  65. case(InputKeyRight):
  66. break;
  67. default:
  68. break;
  69. }
  70. }
  71. break;
  72. case(EventTypeTick):
  73. if(app->shooting){
  74. //sending command to trigger via BT
  75. furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT);
  76. furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT);
  77. notification_message(app->notifications, &sequence_blink_blue_100);
  78. app->shots++;
  79. }
  80. break;
  81. default:
  82. break;
  83. }
  84. }
  85. //Going back to serial mode BT
  86. bt_set_status_changed_callback(app->bt, NULL, NULL);
  87. bt_disconnect(app->bt);
  88. // Wait 2nd core to update nvm storage
  89. furi_delay_ms(200);
  90. bt_keys_storage_set_default_path(app->bt);
  91. if(!bt_set_profile(app->bt, BtProfileSerial)) {
  92. FURI_LOG_E(TAG, "Failed to switch to Serial profile");
  93. }
  94. //Freeing memory
  95. furi_message_queue_free(event_queue);
  96. //Freeing timer
  97. furi_timer_free(timer);
  98. cleanUpBeforeYouLeave(app);
  99. return 0;
  100. }
  101. //Callback display
  102. static void draw_callback(Canvas* canvas, void* ctx) {
  103. AppStruct* app = ctx;
  104. char chaine_photo[36];
  105. char chaine_delais[36];
  106. if(app->shooting){
  107. snprintf(chaine_photo, sizeof(chaine_photo), "Shooting... Photos: %i", app->shots);
  108. }else{
  109. snprintf(chaine_photo, sizeof(chaine_photo), "Photos: %i", app->shots);
  110. }
  111. snprintf(chaine_delais, sizeof(chaine_delais), "Delais %i", app->delay);
  112. canvas_clear(canvas);
  113. canvas_set_font(canvas, FontPrimary);
  114. if(app->connected){
  115. canvas_draw_str(canvas, 0, 10, "Connected");
  116. canvas_draw_str(canvas, 0, 20, chaine_delais);
  117. canvas_draw_str(canvas, 0, 30, chaine_photo);
  118. }else{
  119. canvas_draw_str(canvas, 0, 10, "Connection en cours...");
  120. }
  121. }
  122. //Input callbacks
  123. static void input_callback(InputEvent* input_event, void* ctx) {
  124. furi_assert(ctx);
  125. //Getting our event queue
  126. FuriMessageQueue* event_queue = ctx;
  127. //Adding the event to our custom Struct
  128. IosTriggerEvent event = {.type = EventTypeInput, .input = *input_event};
  129. //Adding our event to the event queue
  130. furi_message_queue_put(event_queue, &event, FuriWaitForever);
  131. }
  132. //Timer callback
  133. static void timer_callback(FuriMessageQueue* event_queue) {
  134. //check eventqueue is not null
  135. furi_assert(event_queue);
  136. //creating event and adding it to the event list
  137. IosTriggerEvent event = {.type = EventTypeTick};
  138. furi_message_queue_put(event_queue, &event, 0);
  139. }
  140. static void bt_hid_connection_status_changed_callback(BtStatus status, void* context) {
  141. furi_assert(context);
  142. AppStruct* app = context;
  143. app->connected = (status == BtStatusConnected);
  144. //if(app->connected) {
  145. // notification_message(app->notifications, &sequence_set_blue_255);
  146. //} else {
  147. // notification_message(app->notifications, &sequence_reset_blue);
  148. //}
  149. }
  150. AppStruct* appStructAlloc(){
  151. AppStruct* app = malloc(sizeof(AppStruct));
  152. //Init bluetooth
  153. app->bt = furi_record_open(RECORD_BT);
  154. //Drawing to be displayed
  155. app->gui = furi_record_open(RECORD_GUI);
  156. //Display
  157. app->view_port = view_port_alloc();
  158. //Init notifications (used for led blink)
  159. app->notifications = furi_record_open(RECORD_NOTIFICATION);
  160. app->connected = false;
  161. app->running = true;
  162. return app;
  163. }
  164. void cleanUpBeforeYouLeave(AppStruct* app){
  165. furi_assert(app);
  166. //Freeing notifications
  167. furi_record_close(RECORD_NOTIFICATION);
  168. app->notifications = NULL;
  169. //Remove gui from display
  170. gui_remove_view_port(app->gui, app->view_port);
  171. //Freeing display
  172. view_port_free(app->view_port);
  173. furi_record_close(RECORD_GUI);
  174. app->gui = NULL;
  175. furi_record_close(RECORD_BT);
  176. app->bt = NULL;
  177. free(app);
  178. }