Просмотр исходного кода

Basic command shortcuts and rx console output view

0xchocolate 3 лет назад
Родитель
Сommit
4e25574d62

+ 1 - 0
applications/wifi_marauder_companion/scenes/wifi_marauder_scene_config.h

@@ -1 +1,2 @@
 ADD_SCENE(wifi_marauder, start, Start)
 ADD_SCENE(wifi_marauder, start, Start)
+ADD_SCENE(wifi_marauder, console_output, ConsoleOutput)

+ 71 - 0
applications/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c

@@ -0,0 +1,71 @@
+#include "../wifi_marauder_app_i.h"
+
+//void wifi_marauder_scene_console_output_callback(WifiMarauderCustomEvent event, void* context) {
+    
+//}
+
+void wifi_marauder_console_output_handle_rx_data_cb(uint8_t *buf, size_t len, void* context) {
+    furi_assert(context);
+    WifiMarauderApp* app = context;
+
+    // If the text box store will reach 75% capacity, then truncate half from the beginning
+    const size_t text_box_store_size = string_size(app->text_box_store);
+    if ((text_box_store_size + len) >= (3*string_capacity(app->text_box_store)/4)) {
+        string_right(app->text_box_store, text_box_store_size/2);
+    }
+
+    // TODO: optimize
+    for (size_t i = 0; i < len; ++i) {
+        string_cat_printf(app->text_box_store, "%c", buf[i]);
+    }
+
+    view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventRefreshConsoleOutput);
+}
+
+void wifi_marauder_scene_console_output_on_enter(void* context) {
+    WifiMarauderApp* app = context;
+
+    TextBox* text_box = app->text_box;
+    text_box_set_font(text_box, TextBoxFontText);
+    text_box_set_focus(text_box, TextBoxFocusEnd);
+    string_reset(app->text_box_store);
+
+    //wifi_marauder_console_output_set_callback(app->detect, wifi_marauder_scene_console_output_callback, app);
+    scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
+    view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
+
+    // TODO: start the thread here instead?
+    wifi_marauder_uart_set_handle_rx_data_cb(app->uart, wifi_marauder_console_output_handle_rx_data_cb); // setup callback for rx thread
+
+    if (app->selected_tx_string) {
+        wifi_marauder_uart_tx((uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
+    }
+}
+
+bool wifi_marauder_scene_console_output_on_event(void* context, SceneManagerEvent event) {
+    WifiMarauderApp* app = context;
+
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        text_box_set_text(app->text_box, string_get_cstr(app->text_box_store));
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeTick) {
+        consumed = true;
+    }
+
+    return consumed;
+}
+
+void wifi_marauder_scene_console_output_on_exit(void* context) {
+    WifiMarauderApp* app = context;
+
+    // Unregister rx callback
+    wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL);
+
+    // Automatically stop the scan when exiting view
+    wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
+
+    text_box_reset(app->text_box);
+    string_reset(app->text_box_store);
+}

+ 74 - 48
applications/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c

@@ -1,12 +1,31 @@
 #include "../wifi_marauder_app_i.h"
 #include "../wifi_marauder_app_i.h"
 
 
-enum WifiMarauderItem {
-    WifiMarauderItemScan,
-    WifiMarauderItemAttack,
-    WifiMarauderItemSniff,
-    WifiMarauderItemChannel,
-    WifiMarauderItemUpdate,
-    WifiMarauderItemReboot,
+#define NUM_MENU_ITEMS (24)
+const char* const item_strings[NUM_MENU_ITEMS] = {
+    "attack -t beacon -l\n",
+    "attack -t beacon -r\n",
+    "attack -t beacon -a\n",
+    "attack -t deauth\n",
+    "attack -t probe\n",
+    "attack -t rickroll\n",
+    "channel\n",
+    "channel -s\n",
+    "clearlist -a\n",
+    "clearlist -s\n",
+    "help\n",
+    "list -a\n",
+    "list -s\n",
+    "reboot\n",
+    "scanap\n",
+    "select -a\n",
+    "select -s\n",
+    "sniffbeacon\n",
+    "sniffdeauth\n",
+    "sniffesp\n",
+    "sniffpmkid\n",
+    "sniffpwn\n",
+    "ssid\n",
+    "update -w\n",
 };
 };
 
 
 // TODO: check if all these channels are actually supported
 // TODO: check if all these channels are actually supported
@@ -19,18 +38,9 @@ const char* const channel_select_text[NUM_CHANNELS] = {
 static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) {
 static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) {
     furi_assert(context);
     furi_assert(context);
     WifiMarauderApp* app = context;
     WifiMarauderApp* app = context;
-
-    if(index == WifiMarauderItemScan) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventScan);
-    } else if(index == WifiMarauderItemAttack) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventAttack);
-    } else if(index == WifiMarauderItemSniff) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventSniff);
-    } else if(index == WifiMarauderItemUpdate) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventUpdate);
-    } else if(index == WifiMarauderItemReboot) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventReboot);
-    }
+    app->selected_tx_string = item_strings[index];
+    app->selected_menu_index = index;
+    view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole);
 }
 }
 
 
 static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* item) {
 static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* item) {
@@ -39,7 +49,7 @@ static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* ite
 
 
     variable_item_set_current_value_text(item, channel_select_text[index]);
     variable_item_set_current_value_text(item, channel_select_text[index]);
     app->selected_wifi_channel = index + 1;
     app->selected_wifi_channel = index + 1;
-    view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderStartEventChannel);
+    //view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole);
 }
 }
 
 
 void wifi_marauder_scene_start_on_enter(void* context) {
 void wifi_marauder_scene_start_on_enter(void* context) {
@@ -50,13 +60,30 @@ void wifi_marauder_scene_start_on_enter(void* context) {
     variable_item_list_set_enter_callback(
     variable_item_list_set_enter_callback(
         var_item_list, wifi_marauder_scene_start_var_list_enter_callback, app);
         var_item_list, wifi_marauder_scene_start_var_list_enter_callback, app);
 
 
-    variable_item_list_add(var_item_list, "Scan", 0, NULL, NULL);
-    variable_item_list_add(var_item_list, "Attack", 0, NULL, NULL);
-    variable_item_list_add(var_item_list, "Sniff", 0, NULL, NULL);
+    // TODO: organize menu
+    for (int i = 0; i < NUM_MENU_ITEMS; ++i) {
+        if (0 == strncmp(item_strings[i], "channel -s", strlen("channel -s"))) {
+            item = variable_item_list_add(var_item_list, item_strings[i], NUM_CHANNELS,
+                                          wifi_marauder_scene_start_var_list_change_callback,
+                                          app);
+            variable_item_set_current_value_index(item, 0);
+            variable_item_set_current_value_text(item, channel_select_text[0]);
+        } else {
+            variable_item_list_add(var_item_list, item_strings[i], 0, NULL, NULL);
+        }
+    }
+    /*
+    variable_item_list_add(var_item_list, ATTACK_BEACON_L, 0, NULL, NULL);
+    variable_item_list_add(var_item_list, ATTACK_BEACON_R, 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "attack -t beacon -a", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "attack -t deauth", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "attack -t probe", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "attack -t rickroll", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "channel", 0, NULL, NULL);
 
 
     item = variable_item_list_add(
     item = variable_item_list_add(
         var_item_list,
         var_item_list,
-        "Channel",
+        "channel -s",
         NUM_CHANNELS,
         NUM_CHANNELS,
         wifi_marauder_scene_start_var_list_change_callback,
         wifi_marauder_scene_start_var_list_change_callback,
         app);
         app);
@@ -65,8 +92,22 @@ void wifi_marauder_scene_start_on_enter(void* context) {
     variable_item_set_current_value_index(item, 0);
     variable_item_set_current_value_index(item, 0);
     variable_item_set_current_value_text(item, channel_select_text[0]);
     variable_item_set_current_value_text(item, channel_select_text[0]);
 
 
-    variable_item_list_add(var_item_list, "Update", 0, NULL, NULL);
-    variable_item_list_add(var_item_list, "Reboot", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "clearlist -a", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "clearlist -s", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "help", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "listap -a", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "listap -s", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "reboot", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "scanap", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "select -a", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "select -s", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "sniffbeacon", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "sniffdeauth", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "sniffesp", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "sniffpmkid", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "sniffpwn", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "update -w", 0, NULL, NULL);
+    */
 
 
     variable_item_list_set_selected_item(
     variable_item_list_set_selected_item(
         var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneStart));
         var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneStart));
@@ -81,28 +122,13 @@ bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event)
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         // TODO remove when done debugging
         // TODO remove when done debugging
-        variable_item_list_add(app->var_item_list, "FEEDBACK", 0, NULL, NULL);
-        const char *attack_str = "attack -t rickroll\n";
-        wifi_marauder_uart_tx((uint8_t*)attack_str, strlen(attack_str));
-        // TODO
-        // if (event.event == WifiMarauderStartEventScan) {
-        //     scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, WifiMarauderItemScan);
-        //     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScan);
-        // } else if (event.event == WifiMarauderStartEventAttack) {
-        //     scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, WifiMarauderItemAttack);
-        //     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneAttack);
-        // } else if (event.event == WifiMarauderStartEventSniff) {
-        //     scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, WifiMarauderItemSniff);
-        //     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSniff);
-        // } else if (event.event == WifiMarauderStartEventUpdate) {
-        //     scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, WifiMarauderItemUpdate);
-        //     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUpdate);
-        // } else if (event.event == WifiMarauderStartEventReboot) {
-        //     scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, WifiMarauderItemReboot);
-        //     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneReboot);
-        // } else if (event.event == WifiMarauderStartEventChannel) {
-        //     // TODO: Send app->selected_wifi_channel to UART
-        // }
+        //variable_item_list_add(app->var_item_list, "FEEDBACK", 0, NULL, NULL);
+        //const char *attack_str = "attack -t rickroll\n";
+        //wifi_marauder_uart_tx((uint8_t*)attack_str, strlen(attack_str));
+        if (event.event == WifiMarauderEventStartConsole) {
+            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
+            scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewConsoleOutput);
+        }
         consumed = true;
         consumed = true;
     }
     }
 
 

+ 0 - 0
applications/wifi_marauder_companion/views/wifi_marauder_console_output.c


+ 8 - 8
applications/wifi_marauder_companion/wifi_marauder_app.c

@@ -50,6 +50,10 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
         WifiMarauderAppViewVarItemList,
         WifiMarauderAppViewVarItemList,
         variable_item_list_get_view(app->var_item_list));
         variable_item_list_get_view(app->var_item_list));
 
 
+    app->text_box = text_box_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput, text_box_get_view(app->text_box));
+    string_init(app->text_box_store);
+    string_reserve(app->text_box_store, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE);
     // TODO add other views
     // TODO add other views
 
 
     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart);
     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart);
@@ -62,13 +66,9 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
 
 
     // Views
     // Views
     view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
     view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
-    // TODO add back
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewScan);
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewAttack);
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewSniff);
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewChannel);
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewUpdate);
-    // view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewReboot);
+    view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
+    text_box_free(app->text_box);
+    string_clear(app->text_box_store);
 
 
     // View dispatcher
     // View dispatcher
     view_dispatcher_free(app->view_dispatcher);
     view_dispatcher_free(app->view_dispatcher);
@@ -86,7 +86,7 @@ int32_t wifi_marauder_app(void* p) {
     UNUSED(p);
     UNUSED(p);
     WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc();
     WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc();
 
 
-    wifi_marauder_uart_init();
+    wifi_marauder_uart_init(wifi_marauder_app);
 
 
     view_dispatcher_run(wifi_marauder_app->view_dispatcher);
     view_dispatcher_run(wifi_marauder_app->view_dispatcher);
 
 

+ 12 - 2
applications/wifi_marauder_companion/wifi_marauder_app_i.h

@@ -8,19 +8,27 @@
 #include <gui/gui.h>
 #include <gui/gui.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
 #include <gui/scene_manager.h>
 #include <gui/scene_manager.h>
-#include <gui/modules/submenu.h>
+#include <gui/modules/text_box.h>
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/variable_item_list.h>
 
 
+#define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096)
+
 struct WifiMarauderApp {
 struct WifiMarauderApp {
     Gui* gui;
     Gui* gui;
     ViewDispatcher* view_dispatcher;
     ViewDispatcher* view_dispatcher;
     SceneManager* scene_manager;
     SceneManager* scene_manager;
 
 
+    string_t text_box_store;
+    TextBox* text_box;
+    //Widget* widget;
+
     VariableItemList* var_item_list;
     VariableItemList* var_item_list;
+    //WifiMarauderDetect* detect;
 
 
     WifiMarauderUart* uart;
     WifiMarauderUart* uart;
-
     int selected_wifi_channel;
     int selected_wifi_channel;
+    int selected_menu_index;
+    const char* selected_tx_string;
 };
 };
 
 
 // Supported commands:
 // Supported commands:
@@ -46,6 +54,8 @@ struct WifiMarauderApp {
 
 
 typedef enum {
 typedef enum {
     WifiMarauderAppViewVarItemList,
     WifiMarauderAppViewVarItemList,
+    WifiMarauderAppViewConsoleOutput,
+    WifiMarauderAppViewDetect,
     WifiMarauderAppViewScan,
     WifiMarauderAppViewScan,
     WifiMarauderAppViewAttack,
     WifiMarauderAppViewAttack,
     WifiMarauderAppViewSniff,
     WifiMarauderAppViewSniff,

+ 2 - 6
applications/wifi_marauder_companion/wifi_marauder_custom_event.h

@@ -1,10 +1,6 @@
 #pragma once
 #pragma once
 
 
 typedef enum {
 typedef enum {
-    WifiMarauderStartEventScan = 0,
-    WifiMarauderStartEventAttack,
-    WifiMarauderStartEventSniff,
-    WifiMarauderStartEventUpdate,
-    WifiMarauderStartEventReboot,
-    WifiMarauderStartEventChannel,
+    WifiMarauderEventRefreshConsoleOutput = 0,
+    WifiMarauderEventStartConsole,
 } WifiMarauderCustomEvent;
 } WifiMarauderCustomEvent;

+ 55 - 6
applications/wifi_marauder_companion/wifi_marauder_uart.c

@@ -1,3 +1,4 @@
+#include "wifi_marauder_app_i.h"
 #include "wifi_marauder_uart.h"
 #include "wifi_marauder_uart.h"
 
 
 #include <stream_buffer.h>
 #include <stream_buffer.h>
@@ -7,40 +8,88 @@
 #define RX_BUF_SIZE (64)
 #define RX_BUF_SIZE (64)
 
 
 struct WifiMarauderUart {
 struct WifiMarauderUart {
+    WifiMarauderApp* app;
+    FuriThread* rx_thread;
     StreamBufferHandle_t rx_stream;
     StreamBufferHandle_t rx_stream;
     uint8_t rx_buf[RX_BUF_SIZE];
     uint8_t rx_buf[RX_BUF_SIZE];
+    void (*handle_rx_data_cb)(uint8_t *buf, size_t len, void* context);
 };
 };
 
 
+typedef enum {
+    WorkerEvtStop = (1 << 0),
+    WorkerEvtRxDone = (1 << 1),
+} WorkerEvtFlags;
+
+void wifi_marauder_uart_set_handle_rx_data_cb(WifiMarauderUart* uart, void (*handle_rx_data_cb)(uint8_t *buf, size_t len, void* context)) {
+    furi_assert(uart);
+    uart->handle_rx_data_cb = handle_rx_data_cb;
+}
+
+#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
+
 void wifi_marauder_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
 void wifi_marauder_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
     WifiMarauderUart* uart = (WifiMarauderUart*)context;
     WifiMarauderUart* uart = (WifiMarauderUart*)context;
     BaseType_t xHigherPriorityTaskWoken = pdFALSE;
     BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 
 
     if(ev == UartIrqEventRXNE) {
     if(ev == UartIrqEventRXNE) {
         xStreamBufferSendFromISR(uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
         xStreamBufferSendFromISR(uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
-        //furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone);
+        furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
         portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
         portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
     }
     }
 }
 }
 
 
-// TODO: need rx worker thread to receive into rx_stream / rx_buf
-// add a "Console" menu item to print output?
+static int32_t uart_worker(void* context) {
+    WifiMarauderUart* uart = (void*)context;
+
+    uart->rx_stream = xStreamBufferCreate(RX_BUF_SIZE, 1);
+
+    while(1) {
+        uint32_t events =
+            furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, osFlagsWaitAny, osWaitForever);
+        furi_check((events & osFlagsError) == 0);
+        if(events & WorkerEvtStop) break;
+        if(events & WorkerEvtRxDone) {
+            size_t len =
+                xStreamBufferReceive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
+            if(len > 0) {
+                if (uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
+            }
+        }
+    }
+
+    vStreamBufferDelete(uart->rx_stream);
+
+    return 0;
+}
 
 
 void wifi_marauder_uart_tx(uint8_t *data, size_t len) {
 void wifi_marauder_uart_tx(uint8_t *data, size_t len) {
     furi_hal_uart_tx(UART_CH, data, len);
     furi_hal_uart_tx(UART_CH, data, len);
 }
 }
 
 
-WifiMarauderUart* wifi_marauder_uart_init() {
+WifiMarauderUart* wifi_marauder_uart_init(WifiMarauderApp* app) {
     furi_hal_console_disable();
     furi_hal_console_disable();
     furi_hal_uart_set_br(UART_CH, BAUDRATE);
     furi_hal_uart_set_br(UART_CH, BAUDRATE);
+    furi_hal_uart_set_irq_cb(UART_CH, wifi_marauder_uart_on_irq_cb, app->uart);
 
 
     WifiMarauderUart *uart = malloc(sizeof(WifiMarauderUart));
     WifiMarauderUart *uart = malloc(sizeof(WifiMarauderUart));
-    uart->rx_stream = xStreamBufferCreate(RX_BUF_SIZE, 1);
 
 
+    uart->app = app;
+    uart->rx_thread = furi_thread_alloc();
+    furi_thread_set_name(uart->rx_thread, "WifiMarauderUartRxThread");
+    furi_thread_set_stack_size(uart->rx_thread, 1024);
+    furi_thread_set_context(uart->rx_thread, uart);
+    furi_thread_set_callback(uart->rx_thread, uart_worker);
+
+    furi_thread_start(uart->rx_thread);
     return uart;
     return uart;
 }
 }
 
 
 void wifi_marauder_uart_free(WifiMarauderUart* uart) {
 void wifi_marauder_uart_free(WifiMarauderUart* uart) {
     furi_assert(uart);
     furi_assert(uart);
-    vStreamBufferDelete(uart->rx_stream);
+
+    furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
+    furi_thread_join(uart->rx_thread);
+    furi_thread_free(uart->rx_thread);
+
     free(uart);
     free(uart);
 }
 }

+ 1 - 0
applications/wifi_marauder_companion/wifi_marauder_uart.h

@@ -4,6 +4,7 @@
 
 
 typedef struct WifiMarauderUart WifiMarauderUart;
 typedef struct WifiMarauderUart WifiMarauderUart;
 
 
+void wifi_marauder_uart_set_handle_rx_data_cb(WifiMarauderUart* uart, void (*handle_rx_data_cb)(uint8_t *buf, size_t len, void* context));
 void wifi_marauder_uart_tx(uint8_t *data, size_t len);
 void wifi_marauder_uart_tx(uint8_t *data, size_t len);
 WifiMarauderUart* wifi_marauder_uart_init();
 WifiMarauderUart* wifi_marauder_uart_init();
 void wifi_marauder_uart_free(WifiMarauderUart* uart);
 void wifi_marauder_uart_free(WifiMarauderUart* uart);