180 lines
4.6 KiB
C
180 lines
4.6 KiB
C
#include "csi_log.h"
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "esp_partition.h"
|
|
#include "esp_log.h"
|
|
|
|
static const char *TAG = "storage";
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint32_t seq;
|
|
int32_t ts_us;
|
|
int8_t rssi;
|
|
uint8_t reserved;
|
|
uint16_t len; // CSI payload length in bytes
|
|
} csi_record_hdr_t;
|
|
|
|
static const esp_partition_t *s_csi_part = NULL;
|
|
static size_t s_csi_offset = 0; // bytes written this run
|
|
static uint32_t s_csi_seq = 0;
|
|
|
|
esp_err_t csi_log_init(void)
|
|
{
|
|
s_csi_part = esp_partition_find_first(
|
|
ESP_PARTITION_TYPE_DATA,
|
|
0x40, // subtype from partitions.csv
|
|
"storage");
|
|
|
|
if (!s_csi_part) {
|
|
ESP_LOGE(TAG, "csi_log partition not found");
|
|
return ESP_ERR_NOT_FOUND;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "csi_log size=%u bytes, addr=0x%08x",
|
|
(unsigned)s_csi_part->size,
|
|
(unsigned)s_csi_part->address);
|
|
|
|
// Erase once per experiment
|
|
esp_err_t err = esp_partition_erase_range(
|
|
s_csi_part,
|
|
0,
|
|
s_csi_part->size);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "erase failed: %s", esp_err_to_name(err));
|
|
s_csi_part = NULL;
|
|
return err;
|
|
}
|
|
|
|
s_csi_offset = 0;
|
|
s_csi_seq = 0;
|
|
return ESP_OK;
|
|
}
|
|
|
|
void csi_log_append_record(const wifi_csi_info_t *info)
|
|
{
|
|
if (!s_csi_part || !info) {
|
|
return;
|
|
}
|
|
|
|
// Basic sanity bounds
|
|
if (info->len == 0 || info->len > 512) {
|
|
return;
|
|
}
|
|
|
|
csi_record_hdr_t hdr = {
|
|
.seq = s_csi_seq++,
|
|
.ts_us = (int32_t)info->rx_ctrl.timestamp,
|
|
.rssi = info->rx_ctrl.rssi,
|
|
.reserved = 0,
|
|
.len = info->len,
|
|
};
|
|
|
|
uint16_t rec_bytes = sizeof(hdr) + info->len;
|
|
size_t needed = s_csi_offset + 2 /*len field*/ + rec_bytes;
|
|
|
|
if (needed > s_csi_part->size) {
|
|
static bool warned = false;
|
|
if (!warned) {
|
|
ESP_LOGW(TAG, "csi_log full, dropping subsequent records");
|
|
warned = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
esp_err_t err;
|
|
|
|
// Write record length (header+payload)
|
|
err = esp_partition_write(s_csi_part, s_csi_offset,
|
|
&rec_bytes, sizeof(rec_bytes));
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "write rec_len failed: %s", esp_err_to_name(err));
|
|
return;
|
|
}
|
|
s_csi_offset += sizeof(rec_bytes);
|
|
|
|
// Write header
|
|
err = esp_partition_write(s_csi_part, s_csi_offset,
|
|
&hdr, sizeof(hdr));
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "write hdr failed: %s", esp_err_to_name(err));
|
|
return;
|
|
}
|
|
s_csi_offset += sizeof(hdr);
|
|
|
|
// Write payload
|
|
err = esp_partition_write(s_csi_part, s_csi_offset,
|
|
info->buf, info->len);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "write payload failed: %s", esp_err_to_name(err));
|
|
return;
|
|
}
|
|
s_csi_offset += info->len;
|
|
}
|
|
|
|
void csi_log_dump_over_uart(void)
|
|
{
|
|
if (!s_csi_part) {
|
|
printf("CSI_DUMP_ERROR no_partition\n");
|
|
return;
|
|
}
|
|
|
|
printf("CSI_DUMP_BEGIN %u\n", (unsigned)s_csi_offset);
|
|
|
|
size_t pos = 0;
|
|
while (pos + 2 <= s_csi_offset) {
|
|
uint16_t rec_bytes = 0;
|
|
esp_err_t err = esp_partition_read(
|
|
s_csi_part, pos, &rec_bytes, sizeof(rec_bytes));
|
|
if (err != ESP_OK) {
|
|
printf("CSI_DUMP_ERROR read_len %s\n", esp_err_to_name(err));
|
|
break;
|
|
}
|
|
pos += sizeof(rec_bytes);
|
|
|
|
if (rec_bytes < sizeof(csi_record_hdr_t) ||
|
|
pos + rec_bytes > s_csi_offset) {
|
|
break;
|
|
}
|
|
|
|
csi_record_hdr_t hdr;
|
|
err = esp_partition_read(
|
|
s_csi_part, pos, &hdr, sizeof(hdr));
|
|
if (err != ESP_OK) {
|
|
printf("CSI_DUMP_ERROR read_hdr %s\n", esp_err_to_name(err));
|
|
break;
|
|
}
|
|
pos += sizeof(hdr);
|
|
|
|
uint16_t csi_len = hdr.len;
|
|
if (csi_len > rec_bytes - sizeof(hdr)) {
|
|
break;
|
|
}
|
|
|
|
static uint8_t buf[512];
|
|
if (csi_len > sizeof(buf)) {
|
|
csi_len = sizeof(buf);
|
|
}
|
|
|
|
err = esp_partition_read(
|
|
s_csi_part, pos, buf, csi_len);
|
|
if (err != ESP_OK) {
|
|
printf("CSI_DUMP_ERROR read_csi %s\n", esp_err_to_name(err));
|
|
break;
|
|
}
|
|
pos += (rec_bytes - sizeof(hdr)); // skip to record boundary
|
|
|
|
// Text record line
|
|
printf("R %" PRIu32 " %" PRId32 " %d %u ",
|
|
hdr.seq, hdr.ts_us, hdr.rssi, (unsigned)csi_len);
|
|
for (int i = 0; i < csi_len; i++) {
|
|
printf("%02X", buf[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
printf("CSI_DUMP_END\n");
|
|
}
|