evil_portal_uart.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "evil_portal_app_i.h"
  2. #include "evil_portal_uart.h"
  3. #include "helpers/evil_portal_storage.h"
  4. // #define UART_CH (FuriHalUartIdUSART1)
  5. // #define BAUDRATE (115200)
  6. struct Evil_PortalUart {
  7. Evil_PortalApp *app;
  8. FuriThread *rx_thread;
  9. FuriStreamBuffer *rx_stream;
  10. uint8_t rx_buf[RX_BUF_SIZE + 1];
  11. void (*handle_rx_data_cb)(uint8_t *buf, size_t len, void *context);
  12. };
  13. typedef enum {
  14. WorkerEvtStop = (1 << 0),
  15. WorkerEvtRxDone = (1 << 1),
  16. } WorkerEvtFlags;
  17. void evil_portal_uart_set_handle_rx_data_cb(
  18. Evil_PortalUart *uart,
  19. void (*handle_rx_data_cb)(uint8_t *buf, size_t len, void *context)) {
  20. furi_assert(uart);
  21. uart->handle_rx_data_cb = handle_rx_data_cb;
  22. }
  23. #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
  24. void evil_portal_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void *context) {
  25. Evil_PortalUart *uart = (Evil_PortalUart *)context;
  26. if (ev == UartIrqEventRXNE) {
  27. furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
  28. furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
  29. }
  30. }
  31. static int32_t uart_worker(void *context) {
  32. Evil_PortalUart *uart = (void *)context;
  33. while (1) {
  34. uint32_t events = furi_thread_flags_wait(WORKER_ALL_RX_EVENTS,
  35. FuriFlagWaitAny, FuriWaitForever);
  36. furi_check((events & FuriFlagError) == 0);
  37. if (events & WorkerEvtStop)
  38. break;
  39. if (events & WorkerEvtRxDone) {
  40. size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf,
  41. RX_BUF_SIZE, 0);
  42. if (len > 0) {
  43. if (uart->handle_rx_data_cb) {
  44. uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
  45. if (uart->app->has_command_queue) {
  46. if (uart->app->command_index < 1) {
  47. // check the current command
  48. // if command x do x
  49. if (0 ==
  50. strncmp("setap",
  51. uart->app->command_queue[uart->app->command_index],
  52. strlen("setap"))) {
  53. char *out_data =
  54. malloc((size_t)(strlen((char *)uart->app->ap_name) +
  55. strlen("setap=")));
  56. strcat(out_data, "setap=");
  57. strcat(out_data, (char *)uart->app->ap_name);
  58. evil_portal_uart_tx((uint8_t *)(out_data), strlen(out_data));
  59. evil_portal_uart_tx((uint8_t *)("\n"), 1);
  60. uart->app->sent_ap = true;
  61. free(out_data);
  62. free(uart->app->ap_name);
  63. }
  64. uart->app->command_index = 0;
  65. uart->app->has_command_queue = false;
  66. uart->app->command_queue[0] = "";
  67. }
  68. // if(0 == strncmp("ack", (char *)uart->rx_buf, strlen("ack"))) {
  69. // } else {
  70. // uart->app->command_index = 0;
  71. // uart->app->has_command_queue = false;
  72. // uart->app->command_queue[0] = "";
  73. // }
  74. // }
  75. }
  76. // rx_buf has response
  77. // wait for ack
  78. // if response is ack
  79. // check for commands
  80. // if has commands
  81. // send next command
  82. strcat(uart->app->portal_logs, (char *)uart->rx_buf);
  83. if (strlen(uart->app->portal_logs) > 4000) {
  84. write_logs(uart->app->portal_logs);
  85. }
  86. }
  87. }
  88. }
  89. }
  90. furi_stream_buffer_free(uart->rx_stream);
  91. return 0;
  92. }
  93. void evil_portal_uart_tx(uint8_t *data, size_t len) {
  94. furi_hal_uart_tx(UART_CH, data, len);
  95. }
  96. Evil_PortalUart *evil_portal_uart_init(Evil_PortalApp *app) {
  97. Evil_PortalUart *uart = malloc(sizeof(Evil_PortalUart));
  98. uart->app = app;
  99. // Init all rx stream and thread early to avoid crashes
  100. uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
  101. uart->rx_thread = furi_thread_alloc();
  102. furi_thread_set_name(uart->rx_thread, "Evil_PortalUartRxThread");
  103. furi_thread_set_stack_size(uart->rx_thread, 1024);
  104. furi_thread_set_context(uart->rx_thread, uart);
  105. furi_thread_set_callback(uart->rx_thread, uart_worker);
  106. furi_thread_start(uart->rx_thread);
  107. furi_hal_console_disable();
  108. if (app->BAUDRATE == 0) {
  109. app->BAUDRATE = 115200;
  110. }
  111. furi_hal_uart_set_br(UART_CH, app->BAUDRATE);
  112. furi_hal_uart_set_irq_cb(UART_CH, evil_portal_uart_on_irq_cb, uart);
  113. return uart;
  114. }
  115. void evil_portal_uart_free(Evil_PortalUart *uart) {
  116. furi_assert(uart);
  117. furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
  118. furi_thread_join(uart->rx_thread);
  119. furi_thread_free(uart->rx_thread);
  120. furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL);
  121. furi_hal_console_enable();
  122. free(uart);
  123. }