#include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_event.h" #include "esp_log.h" #include "esp_console.h" #include "linenoise/linenoise.h" #include "nvs_flash.h" #include "esp_netif.h" #include "lwip/inet.h" // Components #include "board_config.h" #include "status_led.h" #include "gps_sync.h" #include "wifi_cfg.h" #include "csi_log.h" #include "csi_manager.h" #include "wifi_controller.h" #include "app_console.h" #include "iperf.h" static const char *TAG = "MAIN"; // --- Event Handler ------------------------------------------------- static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { // Let the controller handle mode transitions, but we handle high-level LED/App logic here if (event_base == WIFI_EVENT) { if (event_id == WIFI_EVENT_STA_START) { if (wifi_ctl_get_mode() == WIFI_CTL_MODE_STA) { status_led_set_state(LED_STATE_WAITING); } } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { if (wifi_ctl_get_mode() == WIFI_CTL_MODE_STA) { status_led_set_state(LED_STATE_FAILED); } } } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { if (wifi_ctl_get_mode() != WIFI_CTL_MODE_STA) return; ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; ESP_LOGI(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); status_led_set_state(LED_STATE_CONNECTED); // Start App Services - Only enable CSI if configured in NVS if (csi_mgr_should_enable()) { ESP_LOGI(TAG, "CSI enabled in config - starting capture"); csi_mgr_enable_async(); csi_mgr_schedule_dump(); } else { ESP_LOGI(TAG, "CSI disabled in config - skipping capture"); } // Always start iperf server iperf_cfg_t cfg = { .flag = IPERF_FLAG_SERVER | IPERF_FLAG_TCP, .sport = 5001 }; iperf_start(&cfg); } } // --- Main ---------------------------------------------------------- void app_main(void) { // 1. System Init ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); // 2. Hardware/Driver Init ESP_ERROR_CHECK(csi_log_init()); status_led_init(RGB_LED_GPIO, HAS_RGB_LED); const gps_sync_config_t gps_cfg = { .uart_port = UART_NUM_1, .tx_pin = GPS_TX_PIN, .rx_pin = GPS_RX_PIN, .pps_pin = GPS_PPS_PIN, }; gps_sync_init(&gps_cfg, true); // 3. Subsystem Init csi_mgr_init(); wifi_ctl_init(); wifi_cfg_init(); // Starts cmd_transport (UART/USB) // 4. Console/CLI Init setvbuf(stdin, NULL, _IONBF, 0); esp_console_config_t console_config = { .max_cmdline_args = 8, .max_cmdline_length = 256, }; ESP_ERROR_CHECK(esp_console_init(&console_config)); linenoiseSetMultiLine(1); esp_console_register_help_command(); // Register App Commands app_console_register_commands(); // 5. Register Events ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL)); // 6. Application Start // Display CSI config status bool csi_enabled = csi_mgr_should_enable(); ESP_LOGI(TAG, "CSI Capture: %s", csi_enabled ? "ENABLED" : "DISABLED"); if (wifi_cfg_apply_from_nvs()) { status_led_set_state(LED_STATE_WAITING); char mode[16] = {0}; uint8_t mon_ch = 36; if (wifi_cfg_get_mode(mode, &mon_ch) && strcmp(mode, "MONITOR") == 0) { wifi_ctl_auto_monitor_start(mon_ch); } } else { status_led_set_state(LED_STATE_NO_CONFIG); ESP_LOGW(TAG, "No Config Found. Waiting for setup..."); } // 7. Enter Console Loop (CRITICAL FIX) // This keeps the main task alive to process UART commands from the Python script ESP_LOGI(TAG, "Initialization complete. Entering console loop."); const char* prompt = LOG_COLOR_I "esp32> " LOG_RESET_COLOR; int probe_status = linenoiseProbe(); if (probe_status) { printf("\n" "Your terminal application does not support escape sequences.\n" "Line editing and history features are disabled.\n" "On Windows, try using Putty instead.\n"); linenoiseSetDumbMode(1); prompt = "esp32> "; } while (true) { // This blocks until a line is received from UART char* line = linenoise(prompt); if (line == NULL) { /* Break on EOF or error */ break; } if (strlen(line) > 0) { linenoiseHistoryAdd(line); // Try to run the command int ret; esp_err_t err = esp_console_run(line, &ret); if (err == ESP_ERR_NOT_FOUND) { printf("Unrecognized command\n"); } else if (err == ESP_OK && ret != ESP_OK) { printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret)); } else if (err != ESP_OK) { printf("Internal error: %s\n", esp_err_to_name(err)); } } linenoiseFree(line); } }