Ruview/firmware/esp32-csi-node/main/rv_feature_state.c
Claude 9648a47fdc
ADR-081: adaptive CSI mesh firmware kernel + scaffolding
Introduces a 5-layer firmware kernel that reframes the existing ESP32
modules as components of a chipset-agnostic architecture and authorizes
adaptive control + a compact feature-state stream as the default upstream.

Layers:
  L1 Radio Abstraction Layer  — rv_radio_ops_t vtable + ESP32 binding
  L2 Adaptive Controller      — fast/medium/slow loops (200ms/1s/30s)
  L3 Mesh Sensing Plane       — anchor/observer/relay/coordinator (spec)
  L4 On-device Feature Extr.  — rv_feature_state_t (magic 0xC5110006)
  L5 Rust handoff             — feature_state default; debug raw gated

Files:
  docs/adr/ADR-081-adaptive-csi-mesh-firmware-kernel.md  (new)
  firmware/esp32-csi-node/main/rv_radio_ops.h            (new)
  firmware/esp32-csi-node/main/rv_radio_ops_esp32.c      (new)
  firmware/esp32-csi-node/main/rv_feature_state.{h,c}    (new)
  firmware/esp32-csi-node/main/adaptive_controller.{h,c} (new)
  firmware/esp32-csi-node/main/main.c                    (wire L1+L2)
  firmware/esp32-csi-node/main/CMakeLists.txt            (add 4 sources)
  firmware/esp32-csi-node/main/Kconfig.projbuild         (controller knobs)
  CHANGELOG.md                                           (Unreleased)

Default policy is conservative: enable_channel_switch and
enable_role_change are off, so behavior matches today's firmware
unless an operator opts in via menuconfig. The pure
adaptive_controller_decide() is exposed for offline unit tests.

Reuses (does not rewrite): csi_collector, edge_processing (ADR-039),
swarm_bridge (ADR-066), secure_tdm (ADR-032), wasm_runtime (ADR-040).
2026-04-19 03:14:04 +00:00

44 lines
1.3 KiB
C

/**
* @file rv_feature_state.c
* @brief ADR-081 Layer 4 — Feature state packet helpers.
*/
#include "rv_feature_state.h"
#include <string.h>
uint32_t rv_feature_state_crc32(const uint8_t *data, size_t len)
{
/* IEEE CRC32 (poly 0xEDB88320), bit-by-bit. Small (~80 byte) input at
* low cadence — no need for a 1 KB lookup table. */
uint32_t crc = 0xFFFFFFFFu;
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (int b = 0; b < 8; b++) {
uint32_t mask = -(crc & 1u);
crc = (crc >> 1) ^ (0xEDB88320u & mask);
}
}
return ~crc;
}
void rv_feature_state_finalize(rv_feature_state_t *pkt,
uint8_t node_id,
uint16_t seq,
uint64_t ts_us,
uint8_t mode)
{
if (pkt == NULL) {
return;
}
pkt->magic = RV_FEATURE_STATE_MAGIC;
pkt->node_id = node_id;
pkt->mode = mode;
pkt->seq = seq;
pkt->ts_us = ts_us;
pkt->reserved = 0;
/* CRC32 over everything except the trailing crc32 field itself. */
const size_t crc_offset = sizeof(rv_feature_state_t) - sizeof(uint32_t);
pkt->crc32 = rv_feature_state_crc32((const uint8_t *)pkt, crc_offset);
}