ios_trigger.c 8.5 KB

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