evil_portal_uart.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. // FURI_LOG_I("EP", "in worker");
  34. while (1) {
  35. uint32_t events = furi_thread_flags_wait(WORKER_ALL_RX_EVENTS,
  36. FuriFlagWaitAny, FuriWaitForever);
  37. furi_check((events & FuriFlagError) == 0);
  38. if (events & WorkerEvtStop)
  39. // FURI_LOG_I("EP", "event 1");
  40. break;
  41. if (events & WorkerEvtRxDone) {
  42. // FURI_LOG_I("EP", "event 2");
  43. size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf,
  44. RX_BUF_SIZE, 0);
  45. // FURI_LOG_I("EP", "comp len");
  46. if (len > 0) {
  47. // FURI_LOG_I("EP", "check cb");
  48. if (uart->handle_rx_data_cb) {
  49. uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
  50. if (uart->app->has_command_queue) {
  51. // FURI_LOG_I("EP", "Has command queue");
  52. // FURI_LOG_I("EP", (char *)uart->rx_buf);
  53. if (uart->app->command_index < 1) {
  54. // check the current command
  55. // if command x do x
  56. if (0 ==
  57. strncmp("setap",
  58. uart->app->command_queue[uart->app->command_index],
  59. strlen("setap"))) {
  60. char *out_data =
  61. malloc((size_t)(strlen((char *)uart->app->ap_name) +
  62. strlen("setap=")));
  63. strcat(out_data, "setap=");
  64. strcat(out_data, (char *)uart->app->ap_name);
  65. evil_portal_uart_tx((uint8_t *)(out_data), strlen(out_data));
  66. evil_portal_uart_tx((uint8_t *)("\n"), 1);
  67. uart->app->sent_ap = true;
  68. free(out_data);
  69. free(uart->app->ap_name);
  70. }
  71. uart->app->command_index = 0;
  72. uart->app->has_command_queue = false;
  73. uart->app->command_queue[0] = "";
  74. }
  75. // if(0 == strncmp("ack", (char *)uart->rx_buf, strlen("ack"))) {
  76. // } else {
  77. // uart->app->command_index = 0;
  78. // uart->app->has_command_queue = false;
  79. // uart->app->command_queue[0] = "";
  80. // }
  81. // }
  82. }
  83. // rx_buf has response
  84. // wait for ack
  85. // if response is ack
  86. // check for commands
  87. // if has commands
  88. // send next command
  89. strcat(uart->app->portal_logs, (char *)uart->rx_buf);
  90. if (strlen(uart->app->portal_logs) > 4000) {
  91. write_logs(uart->app->portal_logs);
  92. }
  93. }
  94. }
  95. }
  96. }
  97. furi_stream_buffer_free(uart->rx_stream);
  98. return 0;
  99. }
  100. void evil_portal_uart_tx(uint8_t *data, size_t len) {
  101. furi_hal_uart_tx(UART_CH, data, len);
  102. }
  103. Evil_PortalUart *evil_portal_uart_init(Evil_PortalApp *app) {
  104. Evil_PortalUart *uart = malloc(sizeof(Evil_PortalUart));
  105. uart->app = app;
  106. // Init all rx stream and thread early to avoid crashes
  107. uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
  108. uart->rx_thread = furi_thread_alloc();
  109. furi_thread_set_name(uart->rx_thread, "Evil_PortalUartRxThread");
  110. furi_thread_set_stack_size(uart->rx_thread, 1024);
  111. furi_thread_set_context(uart->rx_thread, uart);
  112. furi_thread_set_callback(uart->rx_thread, uart_worker);
  113. furi_thread_start(uart->rx_thread);
  114. furi_hal_console_disable();
  115. if (app->BAUDRATE == 0) {
  116. app->BAUDRATE = 115200;
  117. }
  118. furi_hal_uart_set_br(UART_CH, app->BAUDRATE);
  119. furi_hal_uart_set_irq_cb(UART_CH, evil_portal_uart_on_irq_cb, uart);
  120. return uart;
  121. }
  122. void evil_portal_uart_free(Evil_PortalUart *uart) {
  123. furi_assert(uart);
  124. furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
  125. furi_thread_join(uart->rx_thread);
  126. furi_thread_free(uart->rx_thread);
  127. furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL);
  128. furi_hal_console_enable();
  129. free(uart);
  130. }