318 lines
13 KiB
C++
318 lines
13 KiB
C++
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_event.h"
|
|
#include "esp_log.h"
|
|
#include "esp_netif.h"
|
|
#include "esp_wifi.h"
|
|
#include "esp_hosted.h"
|
|
#include "driver/uart.h"
|
|
#include "Nvs.hpp"
|
|
#include <cstring>
|
|
|
|
// UART Bridge für C6 Logs
|
|
#define C6_UART_NUM UART_NUM_1
|
|
#define C6_UART_TX_PIN 53
|
|
#define C6_UART_RX_PIN 48
|
|
#define C6_UART_BUF_SIZE 1024
|
|
|
|
static void c6_uart_bridge_task(void* arg) {
|
|
uint8_t* data = (uint8_t*)malloc(C6_UART_BUF_SIZE);
|
|
while (true) {
|
|
int len = uart_read_bytes(C6_UART_NUM, data, C6_UART_BUF_SIZE - 1, pdMS_TO_TICKS(100));
|
|
if (len > 0) {
|
|
data[len] = '\0';
|
|
printf("[C6] %s", (char*)data);
|
|
}
|
|
}
|
|
free(data);
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
static void init_c6_uart_bridge() {
|
|
uart_config_t uart_config = {
|
|
.baud_rate = 115200,
|
|
.data_bits = UART_DATA_8_BITS,
|
|
.parity = UART_PARITY_DISABLE,
|
|
.stop_bits = UART_STOP_BITS_1,
|
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
|
.source_clk = UART_SCLK_DEFAULT,
|
|
};
|
|
|
|
ESP_ERROR_CHECK(uart_driver_install(C6_UART_NUM, C6_UART_BUF_SIZE * 2, 0, 0, NULL, 0));
|
|
ESP_ERROR_CHECK(uart_param_config(C6_UART_NUM, &uart_config));
|
|
ESP_ERROR_CHECK(uart_set_pin(C6_UART_NUM, C6_UART_TX_PIN, C6_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
|
|
|
ESP_LOGI("UART", "C6 UART Bridge initialized: TX=%d, RX=%d", C6_UART_TX_PIN, C6_UART_RX_PIN);
|
|
|
|
xTaskCreate(c6_uart_bridge_task, "c6_uart", 4096, NULL, 10, NULL);
|
|
}
|
|
|
|
#define TAG "App"
|
|
|
|
EventGroupHandle_t wifiEventGroup_ = nullptr;
|
|
static constexpr int WIFI_CONNECTED_BIT = BIT0;
|
|
static constexpr int WIFI_FAIL_BIT = BIT1;
|
|
static constexpr int WIFI_SCAN_DONE_BIT = BIT2;
|
|
static constexpr int WIFI_STA_STARTED_BIT = BIT3;
|
|
|
|
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
|
|
int32_t event_id, void* event_data) {
|
|
(void)arg;
|
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
|
ESP_LOGI(TAG, "STA started");
|
|
xEventGroupSetBits(wifiEventGroup_, WIFI_STA_STARTED_BIT);
|
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
if (event_data) {
|
|
wifi_event_sta_disconnected_t* event = (wifi_event_sta_disconnected_t*)event_data;
|
|
const char* reason_str = "UNKNOWN";
|
|
switch (event->reason) {
|
|
case 1: reason_str = "UNSPECIFIED"; break;
|
|
case 2: reason_str = "AUTH_EXPIRE"; break;
|
|
case 3: reason_str = "AUTH_LEAVE"; break;
|
|
case 4: reason_str = "ASSOC_EXPIRE"; break;
|
|
case 5: reason_str = "ASSOC_TOOMANY"; break;
|
|
case 6: reason_str = "NOT_AUTHED"; break;
|
|
case 7: reason_str = "NOT_ASSOCED"; break;
|
|
case 8: reason_str = "ASSOC_LEAVE"; break;
|
|
case 15: reason_str = "4WAY_HANDSHAKE_TIMEOUT"; break;
|
|
case 16: reason_str = "GROUP_KEY_UPDATE_TIMEOUT"; break;
|
|
case 200: reason_str = "BEACON_TIMEOUT"; break;
|
|
case 201: reason_str = "NO_AP_FOUND"; break;
|
|
case 202: reason_str = "AUTH_FAIL"; break;
|
|
case 203: reason_str = "ASSOC_FAIL"; break;
|
|
case 204: reason_str = "HANDSHAKE_TIMEOUT"; break;
|
|
case 205: reason_str = "CONNECTION_FAIL"; break;
|
|
case 210: reason_str = "ROAMING/INTERNAL"; break;
|
|
}
|
|
ESP_LOGE(TAG, "WiFi DISCONNECTED: reason=%u (%s)", event->reason, reason_str);
|
|
} else {
|
|
ESP_LOGI(TAG, "WiFi disconnected (reason=unknown)");
|
|
}
|
|
xEventGroupSetBits(wifiEventGroup_, WIFI_FAIL_BIT);
|
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
|
|
ESP_LOGI(TAG, "Scan done event received");
|
|
xEventGroupSetBits(wifiEventGroup_, WIFI_SCAN_DONE_BIT);
|
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
|
|
ESP_LOGI(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
|
|
xEventGroupSetBits(wifiEventGroup_, WIFI_CONNECTED_BIT);
|
|
}
|
|
}
|
|
|
|
extern "C" void app_main(void)
|
|
{
|
|
ESP_LOGI(TAG, "Starting WiFi Scan test");
|
|
|
|
// UART Bridge für C6 Logs initialisieren
|
|
init_c6_uart_bridge();
|
|
|
|
wifiEventGroup_ = xEventGroupCreate();
|
|
|
|
//Nvs nvs;
|
|
//nvs.init();
|
|
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
|
|
esp_netif_create_default_wifi_sta();
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
// WICHTIG: Verhindere Auto-Connect aus NVS gespeicherten Credentials
|
|
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
|
ESP_LOGI(TAG, "WiFi storage set to RAM (no auto-connect from NVS)");
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, nullptr));
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, nullptr));
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
|
|
// Warte auf STA_START Event - WICHTIG für C6!
|
|
ESP_LOGI(TAG, "Waiting for STA_START event...");
|
|
EventBits_t bits = xEventGroupWaitBits(wifiEventGroup_, WIFI_STA_STARTED_BIT,
|
|
pdFALSE, pdFALSE, pdMS_TO_TICKS(10000));
|
|
if (!(bits & WIFI_STA_STARTED_BIT)) {
|
|
ESP_LOGE(TAG, "STA_START event not received within 10s!");
|
|
} else {
|
|
ESP_LOGI(TAG, "STA_START event received, WiFi ready");
|
|
}
|
|
|
|
// Sofort disconnect um sauberen Zustand zu haben
|
|
ESP_LOGI(TAG, "Forcing initial disconnect to clear state...");
|
|
esp_wifi_disconnect();
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
|
|
// MAC-Adresse ausgeben
|
|
uint8_t mac[6];
|
|
esp_wifi_get_mac(WIFI_IF_STA, mac);
|
|
ESP_LOGI(TAG, "WiFi MAC Address: %02X:%02X:%02X:%02X:%02X:%02X",
|
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
|
|
// Slave-Firmware-Version abfragen
|
|
esp_hosted_coprocessor_fwver_t slave_ver;
|
|
if (esp_hosted_get_coprocessor_fwversion(&slave_ver) == ESP_OK) {
|
|
ESP_LOGI(TAG, "Slave Firmware Version: %lu.%lu.%lu",
|
|
slave_ver.major1, slave_ver.minor1, slave_ver.patch1);
|
|
} else {
|
|
ESP_LOGW(TAG, "Could not get slave firmware version");
|
|
}
|
|
|
|
// TX Power: 78 = 19.5 dBm, 40 = 10 dBm, 20 = 5 dBm
|
|
// Versuche niedrigere TX-Leistung für Stabilität
|
|
esp_err_t pwr_err = esp_wifi_set_max_tx_power(40);
|
|
if (pwr_err != ESP_OK) {
|
|
ESP_LOGW(TAG, "Set TX power failed: %s", esp_err_to_name(pwr_err));
|
|
}
|
|
// Kleine Pause für C6 Stabilisierung
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
|
|
xEventGroupClearBits(wifiEventGroup_, WIFI_SCAN_DONE_BIT);
|
|
// WiFi Scan starten
|
|
ESP_LOGI(TAG, "Starting WiFi scan...");
|
|
wifi_scan_config_t scan_config = {};
|
|
scan_config.ssid = nullptr;
|
|
scan_config.bssid = nullptr;
|
|
scan_config.channel = 0;
|
|
scan_config.show_hidden = false;
|
|
scan_config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
|
|
scan_config.scan_time.active.min = 100;
|
|
scan_config.scan_time.active.max = 300;
|
|
|
|
esp_err_t scan_err = esp_wifi_scan_start(&scan_config, false);
|
|
if (scan_err != ESP_OK) {
|
|
ESP_LOGW(TAG, "Scan start failed: %s, retrying...", esp_err_to_name(scan_err));
|
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
|
scan_err = esp_wifi_scan_start(&scan_config, false);
|
|
if (scan_err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Scan start failed again: %s", esp_err_to_name(scan_err));
|
|
}
|
|
}
|
|
|
|
xTaskCreate([](void* arg) {
|
|
xEventGroupWaitBits(wifiEventGroup_, WIFI_SCAN_DONE_BIT,
|
|
pdTRUE, pdFALSE, pdMS_TO_TICKS(10000));
|
|
|
|
uint16_t ap_count = 0;
|
|
esp_wifi_scan_get_ap_num(&ap_count);
|
|
|
|
ESP_LOGI(TAG, "=== Found %d access points ===", ap_count);
|
|
|
|
wifi_auth_mode_t target_auth = WIFI_AUTH_WPA2_PSK;
|
|
|
|
if (ap_count > 0) {
|
|
wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count];
|
|
esp_wifi_scan_get_ap_records(&ap_count, ap_records);
|
|
for (int i = 0; i < ap_count; i++) {
|
|
const char* auth_str = "UNKNOWN";
|
|
switch (ap_records[i].authmode) {
|
|
case WIFI_AUTH_OPEN: auth_str = "OPEN"; break;
|
|
case WIFI_AUTH_WEP: auth_str = "WEP"; break;
|
|
case WIFI_AUTH_WPA_PSK: auth_str = "WPA_PSK"; break;
|
|
case WIFI_AUTH_WPA2_PSK: auth_str = "WPA2_PSK"; break;
|
|
case WIFI_AUTH_WPA_WPA2_PSK: auth_str = "WPA/WPA2_PSK"; break;
|
|
case WIFI_AUTH_WPA3_PSK: auth_str = "WPA3_PSK"; break;
|
|
case WIFI_AUTH_WPA2_WPA3_PSK: auth_str = "WPA2/WPA3_PSK"; break;
|
|
default: break;
|
|
}
|
|
ESP_LOGI(TAG, "[%2d] SSID: %-32s | RSSI: %4d | Ch: %2d | Auth: %s",
|
|
i, ap_records[i].ssid, ap_records[i].rssi,
|
|
ap_records[i].primary, auth_str);
|
|
|
|
// Merke Auth-Modus für unser Ziel-Netzwerk (muss mit TARGET_SSID übereinstimmen!)
|
|
if (strcmp((char*)ap_records[i].ssid, "boonkerzb5") == 0) {
|
|
target_auth = ap_records[i].authmode;
|
|
ESP_LOGI(TAG, ">>> Target network '%s' found! Auth mode: %d (%s)",
|
|
ap_records[i].ssid, target_auth, auth_str);
|
|
}
|
|
}
|
|
delete[] ap_records;
|
|
}
|
|
|
|
// ============================================================
|
|
// HIER SSID UND PASSWORT ANPASSEN FÜR TEST!
|
|
// ============================================================
|
|
const char* TARGET_SSID = "boonkerzb5"; // SSID hier ändern
|
|
const char* TARGET_PASSWORD = "38412914"; // Passwort hier ändern (leer für OPEN)
|
|
// ============================================================
|
|
|
|
// Jetzt verbinden
|
|
ESP_LOGI(TAG, "Connecting to %s...", TARGET_SSID);
|
|
ESP_LOGI(TAG, "Detected auth mode: %d", target_auth);
|
|
|
|
// Erst sicherstellen dass wir nicht verbunden sind
|
|
ESP_LOGI(TAG, "Ensuring disconnected state...");
|
|
esp_wifi_disconnect();
|
|
vTaskDelay(pdMS_TO_TICKS(2000)); // Warte bis C6 den Disconnect verarbeitet hat
|
|
|
|
wifi_config_t wifi_config = {};
|
|
strcpy((char*)wifi_config.sta.ssid, TARGET_SSID);
|
|
|
|
// Für OPEN-Netzwerke kein Passwort setzen!
|
|
if (target_auth == WIFI_AUTH_OPEN) {
|
|
ESP_LOGI(TAG, "Network is OPEN, not setting password");
|
|
wifi_config.sta.password[0] = '\0';
|
|
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
|
} else {
|
|
strcpy((char*)wifi_config.sta.password, TARGET_PASSWORD);
|
|
wifi_config.sta.threshold.authmode = target_auth;
|
|
}
|
|
|
|
wifi_config.sta.pmf_cfg.capable = true;
|
|
wifi_config.sta.pmf_cfg.required = false;
|
|
|
|
esp_err_t cfg_err = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
|
if (cfg_err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to set WiFi config: %s", esp_err_to_name(cfg_err));
|
|
}
|
|
|
|
// Warte nach Config-Setzen
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
|
|
// Versuche mehrmals zu verbinden
|
|
for (int retry = 0; retry < 5; retry++) {
|
|
ESP_LOGI(TAG, "Connection attempt %d/5...", retry + 1);
|
|
|
|
xEventGroupClearBits(wifiEventGroup_, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT);
|
|
|
|
esp_err_t err = esp_wifi_connect();
|
|
if (err == ESP_ERR_WIFI_CONN) {
|
|
// WiFi ist noch im "connecting" state - warte und versuche disconnect
|
|
ESP_LOGW(TAG, "WiFi still connecting, forcing disconnect...");
|
|
esp_wifi_disconnect();
|
|
vTaskDelay(pdMS_TO_TICKS(3000)); // Längere Pause für C6
|
|
continue;
|
|
}
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "esp_wifi_connect failed: %s", esp_err_to_name(err));
|
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
|
continue;
|
|
}
|
|
|
|
// Warte auf Verbindung oder Fehler
|
|
EventBits_t bits = xEventGroupWaitBits(wifiEventGroup_,
|
|
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
|
pdFALSE, pdFALSE, pdMS_TO_TICKS(15000));
|
|
|
|
if (bits & WIFI_CONNECTED_BIT) {
|
|
ESP_LOGI(TAG, "Successfully connected to WiFi!");
|
|
break;
|
|
} else {
|
|
ESP_LOGW(TAG, "Connection attempt %d failed (bits=0x%lx), retrying...", retry + 1, (unsigned long)bits);
|
|
esp_wifi_disconnect();
|
|
vTaskDelay(pdMS_TO_TICKS(3000)); // Längere Pause zwischen Versuchen
|
|
}
|
|
}
|
|
|
|
// Halte Task am Leben
|
|
while (true) {
|
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
|
}
|
|
}, "wifi_scan", 8192, nullptr, 5, nullptr);
|
|
|
|
while (true) {
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
}
|
|
}
|