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

Support Unified serial PCAPs + Fix for OFW 0.98 (#47)

* Support Unified serial PCAPs (packets over main UART)

* Port to new FuriHalSerial API

* Format

* Remember if 5v was enabled

* Bump version 7.0

* Fix interference with expansion modules
WillyJL 1 год назад
Родитель
Сommit
272eb25ed9

+ 1 - 1
application.fam

@@ -1,7 +1,7 @@
 App(
     appid="esp32_wifi_marauder",
     name="[ESP32] WiFi Marauder",
-    fap_version=(6,6),
+    fap_version=(7, 0),
     apptype=FlipperAppType.EXTERNAL,
     entry_point="wifi_marauder_app",
     requires=["gui"],

+ 17 - 11
scenes/wifi_marauder_scene_console_output.c

@@ -104,8 +104,8 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
     wifi_marauder_uart_set_handle_rx_data_cb(
         app->uart,
         wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
-    wifi_marauder_uart_set_handle_rx_data_cb(
-        app->lp_uart,
+    wifi_marauder_uart_set_handle_rx_pcap_cb(
+        app->uart,
         wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
 
     // Get ready to send command
@@ -157,11 +157,15 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
         // Send command with newline '\n'
         if(app->selected_tx_string) {
             wifi_marauder_uart_tx(
-                (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
-            wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
+                app->uart, (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
+            if(app->is_writing_pcap) {
+                wifi_marauder_uart_tx(app->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
+            } else {
+                wifi_marauder_uart_tx(app->uart, (uint8_t*)("\n"), 1);
+            }
             if(send_html && the_html) {
-                wifi_marauder_uart_tx(the_html, html_size);
-                wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
+                wifi_marauder_uart_tx(app->uart, the_html, html_size);
+                wifi_marauder_uart_tx(app->uart, (uint8_t*)("\n"), 1);
                 free(the_html);
                 send_html = false;
             }
@@ -169,7 +173,7 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
 
         // Run the script if the file with the script has been opened
         if(app->script != NULL) {
-            app->script_worker = wifi_marauder_script_worker_alloc();
+            app->script_worker = wifi_marauder_script_worker_alloc(app->uart);
             wifi_marauder_script_worker_start(app->script_worker, app->script);
         }
     }
@@ -195,16 +199,18 @@ void wifi_marauder_scene_console_output_on_exit(void* context) {
 
     // Automatically stop the scan when exiting view
     if(app->is_command) {
-        wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
+        wifi_marauder_uart_tx(app->uart, (uint8_t*)("stopscan\n"), strlen("stopscan\n"));
         furi_delay_ms(50);
     }
 
     // Unregister rx callback
     wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL);
-    wifi_marauder_uart_set_handle_rx_data_cb(app->lp_uart, NULL);
+    wifi_marauder_uart_set_handle_rx_pcap_cb(app->uart, NULL);
 
-    wifi_marauder_script_worker_free(app->script_worker);
-    app->script_worker = NULL;
+    if(app->script_worker) {
+        wifi_marauder_script_worker_free(app->script_worker);
+        app->script_worker = NULL;
+    }
 
     app->is_writing_pcap = false;
     if(app->capture_file && storage_file_is_open(app->capture_file)) {

+ 16 - 2
scenes/wifi_marauder_scene_start.c

@@ -62,9 +62,23 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = {
      FOCUS_CONSOLE_END,
      NO_TIP},
     {"Attack",
-     {"deauth", "probe", "rickroll", "sour apple", "swiftpair spam", "samsung spam", "google spam", "bt spam all"},
+     {"deauth",
+      "probe",
+      "rickroll",
+      "sour apple",
+      "swiftpair spam",
+      "samsung spam",
+      "google spam",
+      "bt spam all"},
      8,
-     {"attack -t deauth", "attack -t probe", "attack -t rickroll", "blespam -t apple", "blespam -t windows", "blespam -t samsung", "blespam -t google", "blespam -t all"},
+     {"attack -t deauth",
+      "attack -t probe",
+      "attack -t rickroll",
+      "blespam -t apple",
+      "blespam -t windows",
+      "blespam -t samsung",
+      "blespam -t google",
+      "blespam -t all"},
      NO_ARGS,
      FOCUS_CONSOLE_END,
      SHOW_STOPSCAN_TIP},

+ 0 - 1
scenes/wifi_marauder_scene_user_input.c

@@ -155,7 +155,6 @@ bool wifi_marauder_scene_user_input_on_event(void* context, SceneManagerEvent ev
     }
 
     return consumed;
-
 }
 
 void wifi_marauder_scene_user_input_on_exit(void* context) {

+ 59 - 54
script/wifi_marauder_script_executor.c

@@ -5,20 +5,20 @@ void _wifi_marauder_script_delay(WifiMarauderScriptWorker* worker, uint32_t dela
     for(uint32_t i = 0; i < delay_secs && worker->is_running; i++) furi_delay_ms(1000);
 }
 
-void _send_stop() {
+void _send_stop(WifiMarauderScriptWorker* worker) {
     const char stop_command[] = "stopscan\n";
-    wifi_marauder_uart_tx((uint8_t*)(stop_command), strlen(stop_command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(stop_command), strlen(stop_command));
 }
 
-void _send_line_break() {
-    wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
+void _send_line_break(WifiMarauderScriptWorker* worker) {
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
 }
 
-void _send_channel_select(int channel) {
+void _send_channel_select(WifiMarauderScriptWorker* worker, int channel) {
     char command[30];
-    _send_line_break();
+    _send_line_break(worker);
     snprintf(command, sizeof(command), "channel -s %d\n", channel);
-    wifi_marauder_uart_tx((uint8_t*)(command), strlen(command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
 }
 
 void _wifi_marauder_script_execute_scan(
@@ -27,7 +27,7 @@ void _wifi_marauder_script_execute_scan(
     char command[15];
     // Set channel
     if(stage->channel > 0) {
-        _send_channel_select(stage->channel);
+        _send_channel_select(worker, stage->channel);
     }
     // Start scan
     if(stage->type == WifiMarauderScriptScanTypeAp) {
@@ -35,12 +35,14 @@ void _wifi_marauder_script_execute_scan(
     } else {
         snprintf(command, sizeof(command), "scansta\n");
     }
-    wifi_marauder_uart_tx((uint8_t*)(command), strlen(command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
-void _wifi_marauder_script_execute_select(WifiMarauderScriptStageSelect* stage) {
+void _wifi_marauder_script_execute_select(
+    WifiMarauderScriptStageSelect* stage,
+    WifiMarauderScriptWorker* worker) {
     const char* select_type = NULL;
     switch(stage->type) {
     case WifiMarauderScriptSelectTypeAp:
@@ -79,61 +81,61 @@ void _wifi_marauder_script_execute_select(WifiMarauderScriptStageSelect* stage)
             command, sizeof(command), "select %s -f \"%s\"\n", select_type, stage->filter);
     }
 
-    wifi_marauder_uart_tx((uint8_t*)command, command_length);
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, command_length);
 }
 
 void _wifi_marauder_script_execute_deauth(
     WifiMarauderScriptStageDeauth* stage,
     WifiMarauderScriptWorker* worker) {
     const char attack_command[] = "attack -t deauth\n";
-    wifi_marauder_uart_tx((uint8_t*)(attack_command), strlen(attack_command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_probe(
     WifiMarauderScriptStageProbe* stage,
     WifiMarauderScriptWorker* worker) {
     const char attack_command[] = "attack -t probe\n";
-    wifi_marauder_uart_tx((uint8_t*)(attack_command), strlen(attack_command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_sniff_raw(
     WifiMarauderScriptStageSniffRaw* stage,
     WifiMarauderScriptWorker* worker) {
-    const char sniff_command[] = "sniffraw\n";
-    wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
+    const char sniff_command[] = "sniffraw -serial\n";
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_sniff_beacon(
     WifiMarauderScriptStageSniffBeacon* stage,
     WifiMarauderScriptWorker* worker) {
-    const char sniff_command[] = "sniffbeacon\n";
-    wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
+    const char sniff_command[] = "sniffbeacon -serial\n";
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_sniff_deauth(
     WifiMarauderScriptStageSniffDeauth* stage,
     WifiMarauderScriptWorker* worker) {
-    const char sniff_command[] = "sniffdeauth\n";
-    wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
+    const char sniff_command[] = "sniffdeauth -serial\n";
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_sniff_esp(
     WifiMarauderScriptStageSniffEsp* stage,
     WifiMarauderScriptWorker* worker) {
-    const char sniff_command[] = "sniffesp\n";
-    wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
+    const char sniff_command[] = "sniffesp -serial\n";
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_sniff_pmkid(
@@ -150,10 +152,10 @@ void _wifi_marauder_script_execute_sniff_pmkid(
                 len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d");
             }
 
-            len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n");
-            wifi_marauder_uart_tx((uint8_t*)attack_command, len);
+            len += snprintf(attack_command + len, sizeof(attack_command) - len, " -serial\n");
+            wifi_marauder_uart_tx(worker->uart, (uint8_t*)attack_command, len);
             _wifi_marauder_script_delay(worker, stage->timeout);
-            _send_stop();
+            _send_stop(worker);
         }
     } else {
         char attack_command[50] = "sniffpmkid";
@@ -167,27 +169,27 @@ void _wifi_marauder_script_execute_sniff_pmkid(
         if(stage->force_deauth) {
             len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d");
         }
-        len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n");
-        wifi_marauder_uart_tx((uint8_t*)attack_command, len);
+        len += snprintf(attack_command + len, sizeof(attack_command) - len, " -serial\n");
+        wifi_marauder_uart_tx(worker->uart, (uint8_t*)attack_command, len);
         _wifi_marauder_script_delay(worker, stage->timeout);
-        _send_stop();
+        _send_stop(worker);
     }
 }
 
 void _wifi_marauder_script_execute_sniff_pwn(
     WifiMarauderScriptStageSniffPwn* stage,
     WifiMarauderScriptWorker* worker) {
-    const char sniff_command[] = "sniffpwn\n";
-    wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
+    const char sniff_command[] = "sniffpwn -serial\n";
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_beacon_list(
     WifiMarauderScriptStageBeaconList* stage,
     WifiMarauderScriptWorker* worker) {
     const char clearlist_command[] = "clearlist -s\n";
-    wifi_marauder_uart_tx((uint8_t*)(clearlist_command), strlen(clearlist_command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(clearlist_command), strlen(clearlist_command));
 
     char command[100];
     char* ssid;
@@ -195,8 +197,8 @@ void _wifi_marauder_script_execute_beacon_list(
     for(int i = 0; i < stage->ssid_count; i++) {
         ssid = stage->ssids[i];
         snprintf(command, sizeof(command), "ssid -a -n \"%s\"", ssid);
-        wifi_marauder_uart_tx((uint8_t*)(command), strlen(command));
-        _send_line_break();
+        wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
+        _send_line_break(worker);
     }
     if(stage->random_ssids > 0) {
         char add_random_command[50];
@@ -205,27 +207,30 @@ void _wifi_marauder_script_execute_beacon_list(
             sizeof(add_random_command),
             "ssid -a -r -g %d\n",
             stage->random_ssids);
-        wifi_marauder_uart_tx((uint8_t*)add_random_command, strlen(add_random_command));
+        wifi_marauder_uart_tx(
+            worker->uart, (uint8_t*)add_random_command, strlen(add_random_command));
     }
     const char attack_command[] = "attack -t beacon -l\n";
-    wifi_marauder_uart_tx((uint8_t*)(attack_command), strlen(attack_command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
 void _wifi_marauder_script_execute_beacon_ap(
     WifiMarauderScriptStageBeaconAp* stage,
     WifiMarauderScriptWorker* worker) {
     const char command[] = "attack -t beacon -a\n";
-    wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
+    wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
     _wifi_marauder_script_delay(worker, stage->timeout);
-    _send_stop();
+    _send_stop(worker);
 }
 
-void _wifi_marauder_script_execute_exec(WifiMarauderScriptStageExec* stage) {
+void _wifi_marauder_script_execute_exec(
+    WifiMarauderScriptStageExec* stage,
+    WifiMarauderScriptWorker* worker) {
     if(stage->command != NULL) {
-        wifi_marauder_uart_tx((uint8_t*)stage->command, strlen(stage->command));
-        _send_line_break();
+        wifi_marauder_uart_tx(worker->uart, (uint8_t*)stage->command, strlen(stage->command));
+        _send_line_break(worker);
     }
 }
 
@@ -248,8 +253,8 @@ void wifi_marauder_script_execute_start(void* context) {
             sizeof(command),
             "settings -s EnableLED %s",
             script->enable_led ? "enable" : "disable");
-        wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
-        _send_line_break();
+        wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
+        _send_line_break(worker);
     }
 
     // Enables or disables PCAP saving according to script settings
@@ -259,8 +264,8 @@ void wifi_marauder_script_execute_start(void* context) {
             sizeof(command),
             "settings -s SavePCAP %s",
             script->save_pcap ? "enable" : "disable");
-        wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
-        _send_line_break();
+        wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
+        _send_line_break(worker);
     }
 }
 
@@ -274,7 +279,7 @@ void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* co
         _wifi_marauder_script_execute_scan((WifiMarauderScriptStageScan*)stage_data, worker);
         break;
     case WifiMarauderScriptStageTypeSelect:
-        _wifi_marauder_script_execute_select((WifiMarauderScriptStageSelect*)stage_data);
+        _wifi_marauder_script_execute_select((WifiMarauderScriptStageSelect*)stage_data, worker);
         break;
     case WifiMarauderScriptStageTypeDeauth:
         _wifi_marauder_script_execute_deauth((WifiMarauderScriptStageDeauth*)stage_data, worker);
@@ -315,7 +320,7 @@ void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* co
             (WifiMarauderScriptStageBeaconAp*)stage_data, worker);
         break;
     case WifiMarauderScriptStageTypeExec:
-        _wifi_marauder_script_execute_exec((WifiMarauderScriptStageExec*)stage_data);
+        _wifi_marauder_script_execute_exec((WifiMarauderScriptStageExec*)stage_data, worker);
         break;
     case WifiMarauderScriptStageTypeDelay:
         _wifi_marauder_script_execute_delay((WifiMarauderScriptStageDelay*)stage_data, worker);

+ 2 - 1
script/wifi_marauder_script_worker.c

@@ -1,7 +1,7 @@
 #include "../wifi_marauder_app_i.h"
 #include "wifi_marauder_script_worker.h"
 
-WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc() {
+WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc(WifiMarauderUart* uart) {
     WifiMarauderScriptWorker* worker = malloc(sizeof(WifiMarauderScriptWorker));
     if(worker == NULL) {
         return NULL;
@@ -9,6 +9,7 @@ WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc() {
     worker->callback_start = NULL;
     worker->callback_stage = NULL;
     worker->worker_thread = NULL;
+    worker->uart = uart;
     worker->is_running = false;
     return worker;
 }

+ 1 - 0
script/wifi_marauder_script_worker.h

@@ -11,6 +11,7 @@ typedef enum {
 typedef struct WifiMarauderScriptWorker {
     WifiMarauderScript* script;
     FuriThread* worker_thread;
+    WifiMarauderUart* uart;
     void (*callback_start)(void*);
     void (*callback_stage)(WifiMarauderScriptStage*, void*);
     void* context;

+ 10 - 3
wifi_marauder_app.c

@@ -2,6 +2,7 @@
 
 #include <furi.h>
 #include <furi_hal.h>
+#include <expansion/expansion.h>
 
 static bool wifi_marauder_app_custom_event_callback(void* context, uint32_t event) {
     furi_assert(context);
@@ -161,7 +162,6 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
     scene_manager_free(app->scene_manager);
 
     wifi_marauder_uart_free(app->uart);
-    wifi_marauder_uart_free(app->lp_uart);
 
     // Close records
     furi_record_close(RECORD_GUI);
@@ -173,8 +173,12 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
 
 int32_t wifi_marauder_app(void* p) {
     UNUSED(p);
+    // Disable expansion protocol to avoid interference with UART Handle
+    Expansion* expansion = furi_record_open(RECORD_EXPANSION);
+    expansion_disable(expansion);
 
     uint8_t attempts = 0;
+    bool otg_was_enabled = furi_hal_power_is_otg_enabled();
     while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
         furi_hal_power_enable_otg();
         furi_delay_ms(10);
@@ -187,15 +191,18 @@ int32_t wifi_marauder_app(void* p) {
     wifi_marauder_load_settings(wifi_marauder_app);
 
     wifi_marauder_app->uart = wifi_marauder_usart_init(wifi_marauder_app);
-    wifi_marauder_app->lp_uart = wifi_marauder_lp_uart_init(wifi_marauder_app);
 
     view_dispatcher_run(wifi_marauder_app->view_dispatcher);
 
     wifi_marauder_app_free(wifi_marauder_app);
 
-    if(furi_hal_power_is_otg_enabled()) {
+    if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
         furi_hal_power_disable_otg();
     }
 
+    // Return previous state of expansion
+    expansion_enable(expansion);
+    furi_record_close(RECORD_EXPANSION);
+
     return 0;
 }

+ 1 - 1
wifi_marauder_app.h

@@ -4,7 +4,7 @@
 extern "C" {
 #endif
 
-#define WIFI_MARAUDER_APP_VERSION "v0.6.6"
+#define WIFI_MARAUDER_APP_VERSION "v0.7.0"
 
 typedef struct WifiMarauderApp WifiMarauderApp;
 

+ 0 - 1
wifi_marauder_app_i.h

@@ -80,7 +80,6 @@ struct WifiMarauderApp {
     int open_log_file_num_pages;
 
     WifiMarauderUart* uart;
-    WifiMarauderUart* lp_uart;
     int selected_menu_index;
     int selected_option_index[NUM_MENU_ITEMS];
     const char* selected_tx_string;

+ 95 - 33
wifi_marauder_uart.c

@@ -1,22 +1,27 @@
 #include "wifi_marauder_app_i.h"
 #include "wifi_marauder_uart.h"
 
-#define UART_CH (FuriHalUartIdUSART1)
-#define LP_UART_CH (FuriHalUartIdLPUART1)
+#define UART_CH (FuriHalSerialIdUsart)
 #define BAUDRATE (115200)
 
 struct WifiMarauderUart {
     WifiMarauderApp* app;
-    FuriHalUartId channel;
     FuriThread* rx_thread;
     FuriStreamBuffer* rx_stream;
+    FuriStreamBuffer* pcap_stream;
+    FuriHalSerialHandle* serial_handle;
+    bool pcap;
+    uint8_t mark_test_buf[11];
+    uint8_t mark_test_idx;
     uint8_t rx_buf[RX_BUF_SIZE + 1];
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
+    void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context);
 };
 
 typedef enum {
     WorkerEvtStop = (1 << 0),
     WorkerEvtRxDone = (1 << 1),
+    WorkerEvtPcapDone = (1 << 2),
 } WorkerEvtFlags;
 
 void wifi_marauder_uart_set_handle_rx_data_cb(
@@ -26,14 +31,75 @@ void wifi_marauder_uart_set_handle_rx_data_cb(
     uart->handle_rx_data_cb = handle_rx_data_cb;
 }
 
-#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
+void wifi_marauder_uart_set_handle_rx_pcap_cb(
+    WifiMarauderUart* uart,
+    void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context)) {
+    furi_assert(uart);
+    uart->handle_rx_pcap_cb = handle_rx_pcap_cb;
+}
 
-void wifi_marauder_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
+#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone | WorkerEvtPcapDone)
+
+void wifi_marauder_uart_on_irq_cb(
+    FuriHalSerialHandle* handle,
+    FuriHalSerialRxEvent event,
+    void* context) {
     WifiMarauderUart* uart = (WifiMarauderUart*)context;
 
-    if(ev == UartIrqEventRXNE) {
-        furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
-        furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
+    if(event == FuriHalSerialRxEventData) {
+        uint8_t data = furi_hal_serial_async_rx(handle);
+        const char* mark_begin = "[BUF/BEGIN]";
+        const char* mark_close = "[BUF/CLOSE]";
+        if(uart->mark_test_idx != 0) {
+            // We are trying to match a marker
+            if(data == mark_begin[uart->mark_test_idx] ||
+               data == mark_close[uart->mark_test_idx]) {
+                // Received char matches next char in a marker, append to test buffer
+                uart->mark_test_buf[uart->mark_test_idx++] = data;
+                if(uart->mark_test_idx == sizeof(uart->mark_test_buf)) {
+                    // Test buffer reached max length, parse what marker this is and discard buffer
+                    if(!memcmp(
+                           uart->mark_test_buf, (void*)mark_begin, sizeof(uart->mark_test_buf))) {
+                        uart->pcap = true;
+                    } else if(!memcmp(
+                                  uart->mark_test_buf,
+                                  (void*)mark_close,
+                                  sizeof(uart->mark_test_buf))) {
+                        uart->pcap = false;
+                    }
+                    uart->mark_test_idx = 0;
+                }
+                // Don't pass to stream
+                return;
+            } else {
+                // Received char doesn't match any expected next char, send current test buffer
+                if(uart->pcap) {
+                    furi_stream_buffer_send(
+                        uart->pcap_stream, uart->mark_test_buf, uart->mark_test_idx, 0);
+                    furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtPcapDone);
+                } else {
+                    furi_stream_buffer_send(
+                        uart->rx_stream, uart->mark_test_buf, uart->mark_test_idx, 0);
+                    furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
+                }
+                // Reset test buffer and try parsing this char from scratch
+                uart->mark_test_idx = 0;
+            }
+        }
+        // If we reach here the buffer is empty
+        if(data == mark_begin[0]) {
+            // Received marker start, append to test buffer
+            uart->mark_test_buf[uart->mark_test_idx++] = data;
+        } else {
+            // Not a marker start and we aren't matching a marker, this is just data
+            if(uart->pcap) {
+                furi_stream_buffer_send(uart->pcap_stream, &data, 1, 0);
+                furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtPcapDone);
+            } else {
+                furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
+                furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
+            }
+        }
     }
 }
 
@@ -51,41 +117,44 @@ static int32_t uart_worker(void* context) {
                 if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
             }
         }
+        if(events & WorkerEvtPcapDone) {
+            size_t len =
+                furi_stream_buffer_receive(uart->pcap_stream, uart->rx_buf, RX_BUF_SIZE, 0);
+            if(len > 0) {
+                if(uart->handle_rx_pcap_cb) uart->handle_rx_pcap_cb(uart->rx_buf, len, uart->app);
+            }
+        }
     }
 
     furi_stream_buffer_free(uart->rx_stream);
+    furi_stream_buffer_free(uart->pcap_stream);
 
     return 0;
 }
 
-void wifi_marauder_uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(UART_CH, data, len);
-}
-
-void wifi_marauder_lp_uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(LP_UART_CH, data, len);
+void wifi_marauder_uart_tx(WifiMarauderUart* uart, uint8_t* data, size_t len) {
+    furi_hal_serial_tx(uart->serial_handle, data, len);
 }
 
-WifiMarauderUart*
-    wifi_marauder_uart_init(WifiMarauderApp* app, FuriHalUartId channel, const char* thread_name) {
+WifiMarauderUart* wifi_marauder_uart_init(
+    WifiMarauderApp* app,
+    FuriHalSerialId channel,
+    const char* thread_name) {
     WifiMarauderUart* uart = malloc(sizeof(WifiMarauderUart));
 
     uart->app = app;
-    uart->channel = channel;
     uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
+    uart->pcap_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
     uart->rx_thread = furi_thread_alloc();
     furi_thread_set_name(uart->rx_thread, thread_name);
     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);
-    if(channel == FuriHalUartIdUSART1) {
-        furi_hal_console_disable();
-    } else if(channel == FuriHalUartIdLPUART1) {
-        furi_hal_uart_init(channel, BAUDRATE);
-    }
-    furi_hal_uart_set_br(channel, BAUDRATE);
-    furi_hal_uart_set_irq_cb(channel, wifi_marauder_uart_on_irq_cb, uart);
+    uart->serial_handle = furi_hal_serial_control_acquire(channel);
+    furi_check(uart->serial_handle);
+    furi_hal_serial_init(uart->serial_handle, BAUDRATE);
+    furi_hal_serial_async_rx_start(uart->serial_handle, wifi_marauder_uart_on_irq_cb, uart, false);
 
     return uart;
 }
@@ -94,10 +163,6 @@ WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app) {
     return wifi_marauder_uart_init(app, UART_CH, "WifiMarauderUartRxThread");
 }
 
-WifiMarauderUart* wifi_marauder_lp_uart_init(WifiMarauderApp* app) {
-    return wifi_marauder_uart_init(app, LP_UART_CH, "WifiMarauderLPUartRxThread");
-}
-
 void wifi_marauder_uart_free(WifiMarauderUart* uart) {
     furi_assert(uart);
 
@@ -105,11 +170,8 @@ void wifi_marauder_uart_free(WifiMarauderUart* uart) {
     furi_thread_join(uart->rx_thread);
     furi_thread_free(uart->rx_thread);
 
-    furi_hal_uart_set_irq_cb(uart->channel, NULL, NULL);
-    if(uart->channel == FuriHalUartIdLPUART1) {
-        furi_hal_uart_deinit(uart->channel);
-    }
-    furi_hal_console_enable();
+    furi_hal_serial_deinit(uart->serial_handle);
+    furi_hal_serial_control_release(uart->serial_handle);
 
     free(uart);
 }

+ 4 - 3
wifi_marauder_uart.h

@@ -9,8 +9,9 @@ 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_lp_uart_tx(uint8_t* data, size_t len);
+void wifi_marauder_uart_set_handle_rx_pcap_cb(
+    WifiMarauderUart* uart,
+    void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context));
+void wifi_marauder_uart_tx(WifiMarauderUart* uart, uint8_t* data, size_t len);
 WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app);
-WifiMarauderUart* wifi_marauder_lp_uart_init(WifiMarauderApp* app);
 void wifi_marauder_uart_free(WifiMarauderUart* uart);