From ba8477f18f5cf109bc751916d29ef3d20afe22c5 Mon Sep 17 00:00:00 2001 From: Clawdia Date: Thu, 7 May 2026 09:42:42 +0200 Subject: [PATCH] =?UTF-8?q?ESP-IDF=20Firmware=20f=C3=BCr=20ESP32-C5=20V2X-?= =?UTF-8?q?Sniffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - v2x_sniffer_main.c: Haupt-Firmware mit 802.11p PHY - v2x_db.h: V2X-Datenbank Header - Makefile: ESP-IDF Build-Konfiguration - phy_11p_set() und phy_change_channel(5900) aktiv --- Makefile | 43 +++++++++++ main/v2x_db.h | 45 ++++++++++++ main/v2x_sniffer_main.c | 154 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 Makefile create mode 100644 main/v2x_db.h create mode 100644 main/v2x_sniffer_main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9c4d4c1 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +# ESP-IDF Makefile für V2X-Sniffer + +# ESP-IDF Pfad +ESP_IDF_PATH ?= /opt/esp/idf + +# Compiler +CROSS_COMPILE ?= xtensa-esp32s3-elf- +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar + +# Ziel +TARGET = v2x_sniffer.elf +OUTPUT = v2x_sniffer.bin + +# Include-Verzeichnisse +INCLUDES = -Imain -Icomponents -Iv2x_driver + +# Compiler-Flags +CFLAGS = -Os -Wall $(INCLUDES) -DIDF_TARGET=ESP32C5 + +# Quellen +SOURCES = main/v2x_sniffer_main.c main/v2x_db.c components/v2x_driver.c + +# Zielobjekte +OBJECTS = $(SOURCES:.c=.o) + +# Build-Ziel +all: $(OUTPUT) + +$(OUTPUT): $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ + $(CROSS_COMPILE)size $@ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJECTS) $(OUTPUT) + +flash: $(OUTPUT) + esptool.py --chip esp32c5 write_flash 0x0 $(OUTPUT) + +.PHONY: all clean flash diff --git a/main/v2x_db.h b/main/v2x_db.h new file mode 100644 index 0000000..71ca84c --- /dev/null +++ b/main/v2x_db.h @@ -0,0 +1,45 @@ +#ifndef V2X_DB_H +#define V2X_DB_H + +#include +#include + +/* V2X-Datenbank Struktur */ +typedef struct { + uint32_t id; + uint64_t timestamp; + uint8_t msg_type; + uint8_t channel; + float frequency_mhz; + int8_t rssi_dbm; + float power_dbm; + uint32_t data_rate_bps; + uint16_t frame_len; + + /* C-ITS Message spezifisch */ + uint64_t station_id; + int32_t lat; + int32_t lon; + int16_t alt; + uint8_t speed; + uint16_t heading; + int8_t acceleration; + + /* Rohdaten */ + uint8_t raw_data[256]; + uint16_t raw_len; +} v2x_db_entry_t; + +/* Datenbank initialisieren */ +esp_err_t v2x_db_init(void); + +/* V2X-Nachricht in Datenbank speichern */ +esp_err_t v2x_db_insert(const v2x_frame_t *frame); + +/* Letzte N Nachrichten abfragen */ +esp_err_t v2x_db_query_recent(v2x_db_entry_t *entries, uint32_t count); + +/* Statistiken abrufen */ +esp_err_t v2x_db_get_statistics(uint32_t *total, uint32_t *cam_count, uint32_t *denm_count); + +#endif /* V2X_DB_H */ diff --git a/main/v2x_sniffer_main.c b/main/v2x_sniffer_main.c new file mode 100644 index 0000000..4d54f6a --- /dev/null +++ b/main/v2x_sniffer_main.c @@ -0,0 +1,154 @@ +/** + * V2X-Sniffer Firmware für ESP32-C5 (Lilygo T-Dongle-C5) + * + * Konfiguration: + * - phy_11p_set(1, 0) - Aktiviert 802.11p PHY + * - phy_change_channel(5900, 1, 0, 0) - Kanal 5900 MHz + * - C-ITS BSM, CAM, DENM Decodierung + * - Separate V2X-Datenbank (v2x_sniffer.db) + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "nvs_flash.h" +#include "driver/gpio.h" +#include "esp_codec_dev.h" + +/* V2X-Datenbank */ +#include "v2x_db.h" + +static const char *TAG = "V2X-Sniffer"; + +/* 802.11p V2X-Band Konfiguration */ +#define V2X_FREQUENCY_MHZ 5900 +#define V2X_CHANNEL_NUMBER 59 +#define V2X_BANDWIDTH_MHZ 10 +#define V2X_PHY_MODE 802.11p + +/* BSM (Basic Safety Message) IDs */ +#define BSM_ID_SPAT 0x01 +#define BSM_ID_MAP 0x02 +#define BSM_ID_TLMM 0x03 + +/* CAM (Cooperative Awareness Message) Container */ +#define CAM_CONTAINER_TYPE 0x04 +#define CAM_PROTOCOL_VERSION 2 + +/* DENM (Decentralized Environmental Notification Message) */ +#define DENM_EVENT_TYPE 0x05 + +typedef struct { + uint16_t message_id; + uint8_t channel; + float frequency_mhz; + int8_t rssi_dbm; + float power_dbm; + uint32_t data_rate_bps; + uint16_t frame_len; + + /* BSM/CAM spezifisch */ + uint8_t msg_type; // BSM, CAM, DENM + uint8_t protocol_version; + uint64_t station_id; + int32_t lat; // in 10^-7 Grad + int32_t lon; // in 10^-7 Grad + int16_t alt; // in dm + uint8_t speed; // in 0.01 m/s + uint16_t heading; // in 0.01 Grad + int8_t acceleration; // in 0.01 m/s^2 +} v2x_frame_t; + +/** + * Initialisiere ESP32-C5 für 802.11p V2X + */ +esp_err_t v2x_phy_init(void) { + ESP_LOGI(TAG, "Initialisiere ESP32-C5 V2X PHY..."); + + /* 802.11p PHY aktivieren */ + phy_11p_set(1, 0); + ESP_LOGI(TAG, "✓ 802.11p PHY aktiviert"); + + /* Auf Kanal 5900 MHz schalten */ + phy_change_channel(5900, 1, 0, 0); + ESP_LOGI(TAG, "✓ Kanal %d (5900 MHz) aktiv", V2X_CHANNEL_NUMBER); + + return ESP_OK; +} + +/** + * 802.11p Frames schnüffeln + */ +void v2x_sniffer_task(void *pvParameters) { + ESP_LOGI(TAG, "V2X-Sniffer gestartet!"); + + while (1) { + /* Warte auf 802.11p Frames */ + wifi_promiscuous_pkt_t *pkt = NULL; + + /* Frame empfangen und decodieren */ + if (wifi_promiscuous_get_pkt(&pkt) == ESP_OK) { + v2x_frame_t frame; + + /* BSM/CAM/DENM Header decodieren */ + frame.msg_type = pkt->ctrl & 0x0F; + frame.channel = V2X_CHANNEL_NUMBER; + frame.frequency_mhz = V2X_FREQUENCY_MHZ; + frame.rssi_dbm = pkt->rssi; + frame.power_dbm = pkt->power; + frame.data_rate_bps = 12000000; // 12 Mbps + frame.frame_len = pkt->len; + + /* In V2X-Datenbank speichern */ + v2x_db_insert(&frame); + + /* Debug-Ausgabe */ + ESP_LOGI(TAG, "V2X: %s CH=%d RSSI=%d dBm", + frame.msg_type == BSM_ID_SPAT ? "BSM" : + frame.msg_type == CAM_CONTAINER_TYPE ? "CAM" : "DENM", + frame.channel, frame.rssi_dbm); + } + + vTaskDelay(10 / portTICK_PERIOD_MS); + } +} + +/** + * Application entry point + */ +void app_main(void) { + ESP_LOGI(TAG, "V2X-Sniffer Firmware gestartet"); + + /* NVS initialisieren */ + nvs_flash_init(); + + /* WiFi initialisieren */ + esp_netif_init(); + esp_event_loop_create_default(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&cfg); + + /* V2X PHY initialisieren */ + v2x_phy_init(); + + /* Promiscuous Mode für Sniffing aktivieren */ + esp_wifi_set_promiscuous(true); + esp_wifi_set_promiscuous_rx_cb([](void *arg, wifi_promiscuous_pkt_t *pkt) { + vTaskNotifyGiveFromISR(v2x_sniffer_handle, pdTRUE); + }); + + /* V2X-Datenbank initialisieren */ + v2x_db_init(); + + /* V2X-Sniffer Task starten */ + xTaskCreate(v2x_sniffer_task, "v2x_sniffer", 4096, NULL, 5, NULL); + + ESP_LOGI(TAG, "✓ V2X-Sniffer bereit!"); +}