bt_trigger.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include "bt_trigger.h"
  2. __int32_t bt_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. app->ble_hid_profile = bt_profile_start(app->bt, ble_profile_hid, NULL);
  11. furi_check(app->ble_hid_profile);
  12. furi_hal_bt_start_advertising();
  13. bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
  14. dolphin_deed(DolphinDeedPluginStart);
  15. //An event
  16. IosTriggerEvent event;
  17. //List of 8 events
  18. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(IosTriggerEvent));
  19. //A timer
  20. FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
  21. //Callback for the display
  22. view_port_draw_callback_set(app->view_port, draw_callback, app);
  23. //Callback for the inputs passing the list as param
  24. view_port_input_callback_set(app->view_port, input_callback, event_queue);
  25. //Linking the drawin on the display
  26. gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
  27. //Main loop
  28. while(app->running) {
  29. //Geting new event from the envent list in the event variable
  30. //waiting forever if the list is empty
  31. //checking status as ok
  32. furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
  33. //Dealing with events one by one
  34. switch(event.type) {
  35. case(EventTypeInput):
  36. //On ne considère que les appuies courts
  37. if(event.input.type == InputTypeShort) {
  38. switch(event.input.key) {
  39. case(InputKeyBack):
  40. //Breaking main loop if the back key is pressed
  41. app->shooting = false;
  42. app->running = false;
  43. break;
  44. case(InputKeyOk): //Take a shot and start intervalometer
  45. if(app->delay > 0) {
  46. app->shooting = !app->shooting;
  47. if(app->shooting) {
  48. ble_profile_hid_consumer_key_press(
  49. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  50. ble_profile_hid_consumer_key_release(
  51. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  52. notification_message(app->notifications, &sequence_blink_blue_100);
  53. app->shots++;
  54. //Timer triggered every delay ms
  55. furi_timer_start(timer, app->delay * 1000);
  56. } else {
  57. //Timer triggered every delay ms
  58. furi_timer_stop(timer);
  59. }
  60. }
  61. break;
  62. case(InputKeyUp): //Increase delay
  63. if(!app->shooting) {
  64. app->delay++;
  65. }
  66. break;
  67. case(InputKeyDown): //Decrease delay
  68. if(!app->shooting && app->delay > 1) {
  69. app->delay--;
  70. }
  71. break;
  72. case(InputKeyLeft): //Reset shots counter
  73. if(!app->shooting) {
  74. app->shots = 0;
  75. }
  76. break;
  77. case(InputKeyRight): //Take a shot
  78. if(!app->shooting) {
  79. ble_profile_hid_consumer_key_press(
  80. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  81. ble_profile_hid_consumer_key_release(
  82. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  83. notification_message(app->notifications, &sequence_blink_blue_100);
  84. app->shots++;
  85. }
  86. break;
  87. default:
  88. break;
  89. }
  90. }
  91. view_port_update(app->view_port);
  92. break;
  93. case(EventTypeTick):
  94. if(app->shooting) {
  95. //sending command to trigger via BT
  96. ble_profile_hid_consumer_key_press(
  97. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  98. ble_profile_hid_consumer_key_release(
  99. app->ble_hid_profile, HID_CONSUMER_VOLUME_INCREMENT);
  100. notification_message(app->notifications, &sequence_blink_blue_100);
  101. app->shots++;
  102. }
  103. view_port_update(app->view_port);
  104. break;
  105. default:
  106. break;
  107. }
  108. }
  109. //Going back to serial mode BT
  110. bt_set_status_changed_callback(app->bt, NULL, NULL);
  111. bt_disconnect(app->bt);
  112. // Wait 2nd core to update nvm storage
  113. furi_delay_ms(200);
  114. bt_keys_storage_set_default_path(app->bt);
  115. furi_check(bt_profile_restore_default(app->bt));
  116. //Freeing memory
  117. furi_message_queue_free(event_queue);
  118. //Freeing timer
  119. furi_timer_free(timer);
  120. cleanUpBeforeYouLeave(app);
  121. return 0;
  122. }
  123. //Callback display
  124. static void draw_callback(Canvas* canvas, void* ctx) {
  125. AppStruct* app = ctx;
  126. char chaine_photo[36];
  127. char chaine_delais[36];
  128. char chaine_shooting[36];
  129. snprintf(chaine_photo, sizeof(chaine_photo), "%i shots", app->shots);
  130. snprintf(chaine_delais, sizeof(chaine_delais), "%i", app->delay);
  131. if(app->shooting) {
  132. snprintf(chaine_shooting, sizeof(chaine_shooting), "Press to stop");
  133. } else {
  134. snprintf(chaine_shooting, sizeof(chaine_shooting), "Press to start");
  135. }
  136. canvas_clear(canvas);
  137. canvas_draw_frame(canvas, 0, 0, 128, 64);
  138. canvas_set_font(canvas, FontPrimary);
  139. canvas_draw_str(canvas, 2, 10, "iOS Intervalometer");
  140. //Represent
  141. canvas_set_font(canvas, FontSecondary);
  142. canvas_draw_str(canvas, 92, 62, "Nem0oo");
  143. if(app->connected) {
  144. canvas_draw_icon(canvas, 111, 2, &I_Ble_connected_15x15);
  145. canvas_set_font(canvas, FontSecondary);
  146. //Delay line
  147. canvas_draw_icon(canvas, 3, 19, &I_ButtonDown_7x4);
  148. canvas_draw_icon(canvas, 3, 14, &I_ButtonUp_7x4);
  149. canvas_draw_str(canvas, 13, 22, "Delay (in sec)");
  150. canvas_draw_str(canvas, 71, 22, chaine_delais);
  151. //Start/stop line
  152. canvas_draw_icon(canvas, 2, 25, &I_Ok_btn_9x9);
  153. canvas_draw_str(canvas, 13, 33, chaine_shooting);
  154. //Single shot line
  155. canvas_draw_icon(canvas, 6, 36, &I_ButtonRight_4x7);
  156. canvas_draw_str(canvas, 13, 43, "Single shot");
  157. //Reset shot count line
  158. canvas_draw_icon(canvas, 3, 45, &I_ButtonLeft_4x7);
  159. canvas_draw_str(canvas, 13, 52, "Reset shot count");
  160. //Shots number line
  161. canvas_draw_icon(canvas, 2, 53, &I_dir_10px);
  162. canvas_draw_str(canvas, 14, 62, chaine_photo);
  163. } else {
  164. canvas_draw_icon(canvas, 111, 2, &I_Ble_disconnected_15x15);
  165. canvas_draw_icon(canvas, 1, 21, &I_WarningDolphin_45x42);
  166. canvas_set_font(canvas, FontSecondary);
  167. canvas_draw_str(canvas, 48, 37, "Awaiting bluetooth");
  168. }
  169. }
  170. //Input callbacks
  171. static void input_callback(InputEvent* input_event, void* ctx) {
  172. furi_assert(ctx);
  173. //Getting our event queue
  174. FuriMessageQueue* event_queue = ctx;
  175. //Adding the event to our custom Struct
  176. IosTriggerEvent event = {.type = EventTypeInput, .input = *input_event};
  177. //Adding our event to the event queue
  178. furi_message_queue_put(event_queue, &event, FuriWaitForever);
  179. }
  180. //Timer callback
  181. static void timer_callback(void* ctx) {
  182. FuriMessageQueue* event_queue = ctx;
  183. //check eventqueue is not null
  184. furi_assert(event_queue);
  185. //creating event and adding it to the event list
  186. IosTriggerEvent event = {.type = EventTypeTick};
  187. furi_message_queue_put(event_queue, &event, 0);
  188. }
  189. static void bt_hid_connection_status_changed_callback(BtStatus status, void* context) {
  190. furi_assert(context);
  191. AppStruct* app = context;
  192. app->connected = (status == BtStatusConnected);
  193. view_port_update(app->view_port);
  194. }
  195. AppStruct* appStructAlloc() {
  196. AppStruct* app = malloc(sizeof(AppStruct));
  197. //Init bluetooth
  198. app->bt = furi_record_open(RECORD_BT);
  199. //Drawing to be displayed
  200. app->gui = furi_record_open(RECORD_GUI);
  201. //Display
  202. app->view_port = view_port_alloc();
  203. //Init notifications (used for led blink)
  204. app->notifications = furi_record_open(RECORD_NOTIFICATION);
  205. app->connected = false;
  206. app->running = true;
  207. app->delay = 1;
  208. return app;
  209. }
  210. void cleanUpBeforeYouLeave(AppStruct* app) {
  211. furi_assert(app);
  212. //Freeing notifications
  213. furi_record_close(RECORD_NOTIFICATION);
  214. app->notifications = NULL;
  215. //Remove gui from display
  216. gui_remove_view_port(app->gui, app->view_port);
  217. //Freeing display
  218. view_port_free(app->view_port);
  219. furi_record_close(RECORD_GUI);
  220. app->gui = NULL;
  221. furi_record_close(RECORD_BT);
  222. app->bt = NULL;
  223. free(app);
  224. }