sentry_safe.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <furi.h>
  2. #include <gui/gui.h>
  3. #include <input/input.h>
  4. #include <stdlib.h>
  5. #include <furi_hal.h>
  6. typedef struct {
  7. uint8_t status;
  8. } SentryState;
  9. typedef enum {
  10. EventTypeTick,
  11. EventTypeKey,
  12. } EventType;
  13. typedef struct {
  14. EventType type;
  15. InputEvent input;
  16. } Event;
  17. const char* status_texts[3] = { "[Press OK to open safe]", "Sending...", "Done !" };
  18. static void sentry_safe_render_callback(Canvas* const canvas, void* ctx) {
  19. const SentryState* sentry_state = acquire_mutex((ValueMutex*)ctx, 25);
  20. if(sentry_state == NULL) {
  21. return;
  22. }
  23. // Before the function is called, the state is set with the canvas_reset(canvas)
  24. // Frame
  25. canvas_draw_frame(canvas, 0, 0, 128, 64);
  26. // Message
  27. canvas_set_font(canvas, FontPrimary);
  28. canvas_draw_frame(canvas, 28, 4, 73, 24);
  29. canvas_draw_str_aligned(canvas, 64, 15, AlignCenter, AlignBottom, "BLACK <-> GND");
  30. canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignBottom, "GREEN <-> C1");
  31. canvas_draw_str_aligned(canvas, 64, 50, AlignCenter, AlignBottom, status_texts[sentry_state->status]);
  32. release_mutex((ValueMutex*)ctx, sentry_state);
  33. }
  34. static void sentry_safe_input_callback(InputEvent* input_event, osMessageQueueId_t event_queue) {
  35. furi_assert(event_queue);
  36. Event event = {.type = EventTypeKey, .input = *input_event};
  37. osMessageQueuePut(event_queue, &event, 0, osWaitForever);
  38. }
  39. void send_request(int command, int a, int b, int c, int d, int e){
  40. int checksum = (command + a + b + c + d + e);
  41. furi_hal_gpio_init_simple(&gpio_ext_pc1, GpioModeOutputPushPull);
  42. furi_hal_gpio_write(&gpio_ext_pc1, false);
  43. osDelay(3.4);
  44. furi_hal_gpio_write(&gpio_ext_pc1, true);
  45. furi_hal_uart_init(FuriHalUartIdLPUART1, 4800);
  46. //furi_hal_uart_set_br(FuriHalUartIdLPUART1, 4800);
  47. //furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, usb_uart_on_irq_cb, usb_uart);
  48. uint8_t data[8] = {0x0, command, a, b, c, d, e, checksum};
  49. furi_hal_uart_tx(FuriHalUartIdLPUART1, data, 8);
  50. osDelay(100);
  51. furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, NULL, NULL);
  52. furi_hal_uart_deinit(FuriHalUartIdLPUART1);
  53. }
  54. void reset_code(int a, int b, int c, int d, int e) {
  55. send_request(0x75, a, b, c, d, e);
  56. }
  57. void try_code(int a, int b, int c, int d, int e) {
  58. send_request(0x71, a, b, c, d, e);
  59. }
  60. int32_t sentry_safe_app(void* p) {
  61. UNUSED(p);
  62. osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(Event), NULL);
  63. SentryState* sentry_state = malloc(sizeof(SentryState));
  64. sentry_state->status = 0;
  65. ValueMutex state_mutex;
  66. if(!init_mutex(&state_mutex, sentry_state, sizeof(SentryState))) {
  67. FURI_LOG_E("SentrySafe", "cannot create mutex\r\n");
  68. free(sentry_state);
  69. return 255;
  70. }
  71. ViewPort* view_port = view_port_alloc();
  72. view_port_draw_callback_set(view_port, sentry_safe_render_callback, &state_mutex);
  73. view_port_input_callback_set(view_port, sentry_safe_input_callback, event_queue);
  74. // Open GUI and register view_port
  75. Gui* gui = furi_record_open("gui");
  76. gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  77. Event event;
  78. for(bool processing = true; processing;) {
  79. osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
  80. SentryState* sentry_state = (SentryState*)acquire_mutex_block(&state_mutex);
  81. if(event_status == osOK) {
  82. // press events
  83. if(event.type == EventTypeKey) {
  84. if(event.input.type == InputTypePress) {
  85. switch(event.input.key) {
  86. case InputKeyUp:
  87. break;
  88. case InputKeyDown:
  89. break;
  90. case InputKeyRight:
  91. break;
  92. case InputKeyLeft:
  93. break;
  94. case InputKeyOk:
  95. if(sentry_state->status == 2){
  96. sentry_state->status = 0;
  97. }else if(sentry_state->status == 0){
  98. sentry_state->status = 1;
  99. reset_code(1,2,3,4,5);
  100. osDelay(500);
  101. try_code(1,2,3,4,5);
  102. sentry_state->status = 2;
  103. }
  104. break;
  105. case InputKeyBack:
  106. processing = false;
  107. break;
  108. }
  109. }
  110. }
  111. } else {
  112. // event timeout
  113. }
  114. view_port_update(view_port);
  115. release_mutex(&state_mutex, sentry_state);
  116. }
  117. view_port_enabled_set(view_port, false);
  118. gui_remove_view_port(gui, view_port);
  119. furi_record_close("gui");
  120. view_port_free(view_port);
  121. osMessageQueueDelete(event_queue);
  122. delete_mutex(&state_mutex);
  123. free(sentry_state);
  124. return 0;
  125. }