ESP-IDF Firmware für ESP32-C5 V2X-Sniffer

- 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
This commit is contained in:
Clawdia
2026-05-07 09:42:42 +02:00
parent 6f0f5931ed
commit ba8477f18f
3 changed files with 242 additions and 0 deletions
+43
View File
@@ -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
+45
View File
@@ -0,0 +1,45 @@
#ifndef V2X_DB_H
#define V2X_DB_H
#include <stdint.h>
#include <stdbool.h>
/* 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 */
+154
View File
@@ -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 <stdio.h>
#include <string.h>
#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!");
}