refactor for csi_manager component
This commit is contained in:
parent
c8814dfa39
commit
89f1b382ce
|
|
@ -0,0 +1,4 @@
|
||||||
|
idf_component_register(SRCS "csi_manager.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES esp_wifi freertos
|
||||||
|
PRIV_REQUIRES csi_log log)
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
#include "csi_manager.h"
|
||||||
|
#include "csi_log.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
static const char *TAG = "CSI_MGR";
|
||||||
|
|
||||||
|
static bool s_csi_enabled = false;
|
||||||
|
static uint32_t s_csi_packet_count = 0;
|
||||||
|
|
||||||
|
// --- Callback ---
|
||||||
|
static void csi_cb(void *ctx, wifi_csi_info_t *info) {
|
||||||
|
if (!info || !s_csi_enabled) return;
|
||||||
|
|
||||||
|
csi_log_append_record(info);
|
||||||
|
s_csi_packet_count++;
|
||||||
|
|
||||||
|
if ((s_csi_packet_count % 100) == 0) {
|
||||||
|
ESP_LOGI(TAG, "Captured %lu CSI packets", (unsigned long)s_csi_packet_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tasks ---
|
||||||
|
|
||||||
|
static void enable_task(void *arg) {
|
||||||
|
// Wait for connection to stabilize
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
|
||||||
|
if (s_csi_enabled) {
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_csi_config_t csi_cfg = { 0 };
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
// Detailed config for Xtensa chips
|
||||||
|
csi_cfg.lltf_en = true;
|
||||||
|
csi_cfg.htltf_en = true;
|
||||||
|
csi_cfg.stbc_htltf2_en = true;
|
||||||
|
csi_cfg.ltf_merge_en = true;
|
||||||
|
csi_cfg.channel_filter_en = true;
|
||||||
|
csi_cfg.manu_scale = false;
|
||||||
|
csi_cfg.shift = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Configuring CSI...");
|
||||||
|
if (esp_wifi_set_csi_config(&csi_cfg) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set CSI config");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_csi_rx_cb(csi_cb, NULL) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set CSI callback");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_csi(true) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to enable CSI");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_csi_enabled = true;
|
||||||
|
ESP_LOGI(TAG, "CSI enabled!");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_task(void *arg) {
|
||||||
|
// Wait before dumping (per your original logic)
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20000));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Dumping CSI data...");
|
||||||
|
csi_log_dump_over_uart();
|
||||||
|
ESP_LOGI(TAG, "CSI dump complete");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- API ---
|
||||||
|
|
||||||
|
void csi_mgr_init(void) {
|
||||||
|
s_csi_enabled = false;
|
||||||
|
s_csi_packet_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csi_mgr_enable_async(void) {
|
||||||
|
if (s_csi_enabled) return;
|
||||||
|
xTaskCreate(enable_task, "csi_enable", 4096, NULL, 5, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void csi_mgr_disable(void) {
|
||||||
|
if (!s_csi_enabled) return;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Disabling CSI...");
|
||||||
|
esp_wifi_set_csi(false);
|
||||||
|
s_csi_enabled = false;
|
||||||
|
ESP_LOGI(TAG, "CSI disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
void csi_mgr_schedule_dump(void) {
|
||||||
|
xTaskCreate(dump_task, "csi_dump", 4096, NULL, 5, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool csi_mgr_is_enabled(void) {
|
||||||
|
return s_csi_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t csi_mgr_get_packet_count(void) {
|
||||||
|
return s_csi_packet_count;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize CSI Manager state
|
||||||
|
*/
|
||||||
|
void csi_mgr_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable CSI capture asynchronously
|
||||||
|
* Spawns a task to wait 2 seconds (to let connection settle) then enables CSI.
|
||||||
|
* Safe to call from Event Handlers.
|
||||||
|
*/
|
||||||
|
void csi_mgr_enable_async(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable CSI capture immediately
|
||||||
|
*/
|
||||||
|
void csi_mgr_disable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dump collected CSI data to UART asynchronously
|
||||||
|
* Spawns a task that waits 20s then dumps data (simulating your original logic).
|
||||||
|
*/
|
||||||
|
void csi_mgr_schedule_dump(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if CSI is currently enabled
|
||||||
|
*/
|
||||||
|
bool csi_mgr_is_enabled(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get total packet count (stats)
|
||||||
|
*/
|
||||||
|
uint32_t csi_mgr_get_packet_count(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -15,4 +15,5 @@ idf_component_register(
|
||||||
gps_sync
|
gps_sync
|
||||||
led_strip
|
led_strip
|
||||||
status_led
|
status_led
|
||||||
|
csi_manager
|
||||||
)
|
)
|
||||||
|
|
|
||||||
95
main/main.c
95
main/main.c
|
|
@ -23,6 +23,7 @@
|
||||||
#include "gps_sync.h"
|
#include "gps_sync.h"
|
||||||
#include "status_led.h"
|
#include "status_led.h"
|
||||||
#include "board_config.h"
|
#include "board_config.h"
|
||||||
|
#include "csi_manager.h" // <--- New Component
|
||||||
|
|
||||||
static const char *TAG = "MAIN";
|
static const char *TAG = "MAIN";
|
||||||
|
|
||||||
|
|
@ -43,85 +44,18 @@ static void auto_monitor_task(void *arg);
|
||||||
// --- GPS Logging Helper ---
|
// --- GPS Logging Helper ---
|
||||||
void log_collapse_event(float nav_duration_us, int rssi, int retry) {
|
void log_collapse_event(float nav_duration_us, int rssi, int retry) {
|
||||||
gps_timestamp_t ts = gps_get_timestamp();
|
gps_timestamp_t ts = gps_get_timestamp();
|
||||||
// Format: COLLAPSE,MonoMS,GpsMS,Synced,Duration,RSSI,Retry
|
|
||||||
printf("COLLAPSE,%" PRIi64 ",%" PRIi64 ",%d,%.2f,%d,%d\n",
|
printf("COLLAPSE,%" PRIi64 ",%" PRIi64 ",%d,%.2f,%d,%d\n",
|
||||||
ts.monotonic_ms,
|
ts.monotonic_ms, ts.gps_ms, ts.synced ? 1 : 0, nav_duration_us, rssi, retry);
|
||||||
ts.gps_ms,
|
|
||||||
ts.synced ? 1 : 0,
|
|
||||||
nav_duration_us,
|
|
||||||
rssi,
|
|
||||||
retry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- CSI Support ---------------------------------------------------
|
|
||||||
static bool s_csi_enabled = false;
|
|
||||||
static uint32_t s_csi_packet_count = 0;
|
|
||||||
|
|
||||||
static void csi_cb(void *ctx, wifi_csi_info_t *info) {
|
|
||||||
csi_log_append_record(info);
|
|
||||||
s_csi_packet_count++;
|
|
||||||
if ((s_csi_packet_count % 100) == 0) {
|
|
||||||
ESP_LOGI("CSI", "Captured %lu CSI packets", (unsigned long)s_csi_packet_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wifi_enable_csi_once(void) {
|
|
||||||
if (s_csi_enabled) return;
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
|
||||||
|
|
||||||
wifi_csi_config_t csi_cfg = { 0 };
|
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32)
|
|
||||||
csi_cfg.lltf_en = true;
|
|
||||||
csi_cfg.htltf_en = true;
|
|
||||||
csi_cfg.stbc_htltf2_en = true;
|
|
||||||
csi_cfg.ltf_merge_en = true;
|
|
||||||
csi_cfg.channel_filter_en = true;
|
|
||||||
csi_cfg.manu_scale = false;
|
|
||||||
csi_cfg.shift = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI("CSI", "Configuring CSI...");
|
|
||||||
if (esp_wifi_set_csi_config(&csi_cfg) != ESP_OK) {
|
|
||||||
ESP_LOGE("CSI", "Failed to set CSI config"); return;
|
|
||||||
}
|
|
||||||
if (esp_wifi_set_csi_rx_cb(csi_cb, NULL) != ESP_OK) {
|
|
||||||
ESP_LOGE("CSI", "Failed to set CSI callback"); return;
|
|
||||||
}
|
|
||||||
if (esp_wifi_set_csi(true) != ESP_OK) {
|
|
||||||
ESP_LOGE("CSI", "Failed to enable CSI"); return;
|
|
||||||
}
|
|
||||||
ESP_LOGI("CSI", "CSI enabled!");
|
|
||||||
s_csi_enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wifi_disable_csi(void) {
|
|
||||||
if (!s_csi_enabled) return;
|
|
||||||
ESP_LOGI("CSI", "Disabling CSI...");
|
|
||||||
esp_wifi_set_csi(false);
|
|
||||||
s_csi_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void csi_dump_task(void *arg) {
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(20000));
|
|
||||||
ESP_LOGI("CSI", "Dumping CSI data...");
|
|
||||||
csi_log_dump_over_uart();
|
|
||||||
ESP_LOGI("CSI", "CSI dump complete");
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- WiFi Monitor Mode Support -------------------------------------
|
// --- WiFi Monitor Mode Support -------------------------------------
|
||||||
static bool s_monitor_enabled = false;
|
static bool s_monitor_enabled = false;
|
||||||
static uint32_t s_monitor_frame_count = 0;
|
|
||||||
static TaskHandle_t s_monitor_stats_task_handle = NULL;
|
static TaskHandle_t s_monitor_stats_task_handle = NULL;
|
||||||
|
|
||||||
static void monitor_frame_callback(const wifi_frame_info_t *frame, const uint8_t *payload, uint16_t len) {
|
static void monitor_frame_callback(const wifi_frame_info_t *frame, const uint8_t *payload, uint16_t len) {
|
||||||
s_monitor_frame_count++;
|
|
||||||
// Check for Collapse
|
|
||||||
if (frame->retry && frame->duration_id > 5000) {
|
if (frame->retry && frame->duration_id > 5000) {
|
||||||
log_collapse_event((float)frame->duration_id, frame->rssi, frame->retry);
|
log_collapse_event((float)frame->duration_id, frame->rssi, frame->retry);
|
||||||
}
|
}
|
||||||
// Warn on extremely high NAV
|
|
||||||
if (frame->duration_id > 30000) {
|
if (frame->duration_id > 30000) {
|
||||||
ESP_LOGW("MONITOR", "⚠️ VERY HIGH NAV: %u us", frame->duration_id);
|
ESP_LOGW("MONITOR", "⚠️ VERY HIGH NAV: %u us", frame->duration_id);
|
||||||
}
|
}
|
||||||
|
|
@ -146,12 +80,14 @@ static void monitor_stats_task(void *arg) {
|
||||||
esp_err_t switch_to_monitor_mode(uint8_t channel, wifi_bandwidth_t bandwidth) {
|
esp_err_t switch_to_monitor_mode(uint8_t channel, wifi_bandwidth_t bandwidth) {
|
||||||
if (current_wifi_mode == WIFI_MODE_MONITOR) return ESP_OK;
|
if (current_wifi_mode == WIFI_MODE_MONITOR) return ESP_OK;
|
||||||
|
|
||||||
if (bandwidth != WIFI_BW_HT20) bandwidth = WIFI_BW_HT20; // Forced for monitor mode
|
if (bandwidth != WIFI_BW_HT20) bandwidth = WIFI_BW_HT20;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Switching to MONITOR MODE (Ch %d)", channel);
|
ESP_LOGI(TAG, "Switching to MONITOR MODE (Ch %d)", channel);
|
||||||
iperf_stop();
|
iperf_stop();
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
wifi_disable_csi();
|
|
||||||
|
// Disable CSI using Manager
|
||||||
|
csi_mgr_disable();
|
||||||
|
|
||||||
esp_wifi_disconnect();
|
esp_wifi_disconnect();
|
||||||
esp_wifi_stop();
|
esp_wifi_stop();
|
||||||
|
|
@ -195,8 +131,6 @@ esp_err_t switch_to_sta_mode(wifi_band_mode_t band_mode) {
|
||||||
esp_wifi_get_config(WIFI_IF_STA, &wifi_config);
|
esp_wifi_get_config(WIFI_IF_STA, &wifi_config);
|
||||||
wifi_config.sta.channel = 0;
|
wifi_config.sta.channel = 0;
|
||||||
|
|
||||||
// Auto band selection logic can be refined here
|
|
||||||
|
|
||||||
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
||||||
esp_wifi_start();
|
esp_wifi_start();
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
|
@ -221,8 +155,7 @@ static int cmd_mode_monitor(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_mode_sta(int argc, char **argv) {
|
static int cmd_mode_sta(int argc, char **argv) {
|
||||||
wifi_band_mode_t band_mode = WIFI_BAND_MODE_AUTO;
|
if (switch_to_sta_mode(WIFI_BAND_MODE_AUTO) != ESP_OK) {
|
||||||
if (switch_to_sta_mode(band_mode) != ESP_OK) {
|
|
||||||
printf("Failed to switch to STA mode\n");
|
printf("Failed to switch to STA mode\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +168,11 @@ static int cmd_mode_status(int argc, char **argv) {
|
||||||
printf("Current mode: %s\n", current_wifi_mode == WIFI_MODE_STA_CSI ? "STA" : "MONITOR");
|
printf("Current mode: %s\n", current_wifi_mode == WIFI_MODE_STA_CSI ? "STA" : "MONITOR");
|
||||||
printf("LED state: %d\n", status_led_get_state());
|
printf("LED state: %d\n", status_led_get_state());
|
||||||
printf("GPS synced: %s\n", gps_is_synced() ? "Yes" : "No");
|
printf("GPS synced: %s\n", gps_is_synced() ? "Yes" : "No");
|
||||||
|
|
||||||
|
if (current_wifi_mode == WIFI_MODE_STA_CSI) {
|
||||||
|
printf("CSI Enabled: %s\n", csi_mgr_is_enabled() ? "Yes" : "No");
|
||||||
|
printf("CSI Packets: %lu\n", (unsigned long)csi_mgr_get_packet_count());
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,12 +180,12 @@ static int cmd_csi_dump(int argc, char **argv) {
|
||||||
if (current_wifi_mode != WIFI_MODE_STA_CSI) {
|
if (current_wifi_mode != WIFI_MODE_STA_CSI) {
|
||||||
printf("Error: CSI only available in STA mode\n"); return 1;
|
printf("Error: CSI only available in STA mode\n"); return 1;
|
||||||
}
|
}
|
||||||
|
// Uses the new manager to dump
|
||||||
csi_log_dump_over_uart();
|
csi_log_dump_over_uart();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_mode_commands(void) {
|
static void register_mode_commands(void) {
|
||||||
// Uses designated initializers to avoid missing field errors
|
|
||||||
const esp_console_cmd_t cmds[] = {
|
const esp_console_cmd_t cmds[] = {
|
||||||
{ .command = "mode_monitor", .help = "Switch to monitor mode", .func = &cmd_mode_monitor },
|
{ .command = "mode_monitor", .help = "Switch to monitor mode", .func = &cmd_mode_monitor },
|
||||||
{ .command = "mode_sta", .help = "Switch to STA mode", .func = &cmd_mode_sta },
|
{ .command = "mode_sta", .help = "Switch to STA mode", .func = &cmd_mode_sta },
|
||||||
|
|
@ -279,12 +217,14 @@ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_
|
||||||
wifi_connected = true;
|
wifi_connected = true;
|
||||||
status_led_set_state(LED_STATE_CONNECTED);
|
status_led_set_state(LED_STATE_CONNECTED);
|
||||||
|
|
||||||
wifi_enable_csi_once();
|
// Start CSI Manager (Async)
|
||||||
|
csi_mgr_enable_async();
|
||||||
|
|
||||||
iperf_cfg_t cfg = { .flag = IPERF_FLAG_SERVER | IPERF_FLAG_TCP, .sport = 5001 };
|
iperf_cfg_t cfg = { .flag = IPERF_FLAG_SERVER | IPERF_FLAG_TCP, .sport = 5001 };
|
||||||
iperf_start(&cfg);
|
iperf_start(&cfg);
|
||||||
|
|
||||||
xTaskCreate(csi_dump_task, "csi_dump_task", 4096, NULL, 5, NULL);
|
// Schedule dump if needed (or rely on CLI)
|
||||||
|
csi_mgr_schedule_dump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,6 +237,7 @@ void app_main(void) {
|
||||||
// Init Subsystems
|
// Init Subsystems
|
||||||
ESP_ERROR_CHECK(csi_log_init());
|
ESP_ERROR_CHECK(csi_log_init());
|
||||||
status_led_init(RGB_LED_GPIO, HAS_RGB_LED);
|
status_led_init(RGB_LED_GPIO, HAS_RGB_LED);
|
||||||
|
csi_mgr_init(); // New Init
|
||||||
|
|
||||||
// Init GPS
|
// Init GPS
|
||||||
const gps_sync_config_t gps_cfg = {
|
const gps_sync_config_t gps_cfg = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue