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:
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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!");
|
||||
}
|
||||
Reference in New Issue
Block a user