mirror of
https://github.com/ruvnet/RuView
synced 2026-07-20 17:03:24 +00:00
66e2fa0835
* docs: ADR-063 mmWave sensor fusion with WiFi CSI 60 GHz mmWave radar (Seeed MR60BHA2, HLK-LD2410/LD2450) fusion with WiFi CSI for dual-confirm fall detection, clinical-grade vitals, and self-calibrating CSI pipeline. Covers auto-detection, 6 supported sensors, Kalman fusion, extended 48-byte vitals packet, RuVector/RuvSense integration points, and 6-phase implementation plan. Based on live hardware capture from ESP32-C6 + MR60BHA2 on COM4. Co-Authored-By: claude-flow <ruv@ruv.net> * feat(firmware): ADR-063 mmWave sensor fusion — full implementation Phase 1-2 of ADR-063: mmwave_sensor.c/h: - MR60BHA2 UART parser (60 GHz: HR, BR, presence, distance) - LD2410 UART parser (24 GHz: presence, distance) - Auto-detection: probes UART for known frame headers at boot - Mock generator for QEMU testing (synthetic HR 72±2, BR 16±1) - Capability flag registration per sensor type edge_processing.c/h: - 48-byte fused vitals packet (magic 0xC5110004) - Kalman-style fusion: mmWave 80% + CSI 20% when both available - Automatic fallback to CSI-only 32-byte packet when no mmWave - Dual presence flag (Bit3 = mmwave_present) main.c: - mmwave_sensor_init() called at boot with auto-detect - Status logged in startup banner Fuzz stubs updated for mmwave_sensor API. Build verified: QEMU mock build passes. Co-Authored-By: claude-flow <ruv@ruv.net> * fix(firmware): correct MR60BHA2 + LD2410 UART protocols (ADR-063) MR60BHA2: SOF=0x01 (not 0x5359), XOR+NOT checksums on header and data, frame types 0x0A14 (BR), 0x0A15 (HR), 0x0A16 (distance), 0x0F09 (presence). Based on Seeed Arduino library research. LD2410: 256000 baud (not 115200), 0xAA report head marker, target state byte at offset 2 (after data_type + head_marker). Auto-detect: probes MR60 at 115200 first, then LD2410 at 256000. Sets final baud rate after detection. Co-Authored-By: claude-flow <ruv@ruv.net> * feat: ADR-063 Phase 6 server-side mmWave + CSI fusion bridge Python script reads both serial ports simultaneously: - COM4 (ESP32-C6 + MR60BHA2): parses ESPHome debug output for HR, BR, presence, distance - COM7 (ESP32-S3): reads CSI edge processing frames Kalman-style fusion: mmWave 80% + CSI 20% for vitals, OR gate for presence. Verified on real hardware: mmWave HR=75bpm, BR=25/min at 52cm range, CSI frames flowing concurrently. Both sensors live for 30 seconds. Co-Authored-By: claude-flow <ruv@ruv.net> * docs: ADR-064 multimodal ambient intelligence roadmap 25+ applications across 4 tiers from practical to exotic: - Tier 1 (build now): zero-FP fall detection, sleep monitoring, occupancy HVAC, baby breathing, bathroom safety - Tier 2 (research): gait analysis, stress detection, gesture control, respiratory screening, multi-room activity - Tier 3 (frontier): cardiac arrhythmia, RF tomography, sign language, cognitive load, swarm sensing - Tier 4 (exotic): emotion contagion, lucid dreaming, plant monitoring, pet behavior Priority matrix with effort estimates. All P0-P1 items work with existing hardware (ESP32-S3 + MR60BHA2 + BH1750). Co-Authored-By: claude-flow <ruv@ruv.net> * fix(ci): add ESP_ERR_NOT_FOUND to fuzz stubs mmwave_sensor stub returns ESP_ERR_NOT_FOUND which wasn't defined in the minimal esp_stubs.h for host-based fuzz testing. Co-Authored-By: claude-flow <ruv@ruv.net>
191 lines
6.5 KiB
C
191 lines
6.5 KiB
C
/**
|
|
* @file esp_stubs.h
|
|
* @brief Minimal ESP-IDF type stubs for host-based fuzz testing.
|
|
*
|
|
* Provides just enough type definitions and macros to compile
|
|
* csi_collector.c and edge_processing.c on a Linux/macOS host
|
|
* without the full ESP-IDF SDK.
|
|
*/
|
|
|
|
#ifndef ESP_STUBS_H
|
|
#define ESP_STUBS_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/* ---- esp_err.h ---- */
|
|
typedef int esp_err_t;
|
|
#define ESP_OK 0
|
|
#define ESP_FAIL (-1)
|
|
#define ESP_ERR_NO_MEM 0x101
|
|
#define ESP_ERR_INVALID_ARG 0x102
|
|
#define ESP_ERR_NOT_FOUND 0x105
|
|
|
|
/* ---- esp_log.h ---- */
|
|
#define ESP_LOGI(tag, fmt, ...) ((void)0)
|
|
#define ESP_LOGW(tag, fmt, ...) ((void)0)
|
|
#define ESP_LOGE(tag, fmt, ...) ((void)0)
|
|
#define ESP_LOGD(tag, fmt, ...) ((void)0)
|
|
#define ESP_ERROR_CHECK(x) ((void)(x))
|
|
|
|
/* ---- esp_timer.h ---- */
|
|
typedef void *esp_timer_handle_t;
|
|
|
|
/** Timer callback type (matches ESP-IDF signature). */
|
|
typedef void (*esp_timer_cb_t)(void *arg);
|
|
|
|
/** Timer creation arguments (matches ESP-IDF esp_timer_create_args_t). */
|
|
typedef struct {
|
|
esp_timer_cb_t callback;
|
|
void *arg;
|
|
const char *name;
|
|
} esp_timer_create_args_t;
|
|
|
|
/**
|
|
* Stub: returns a monotonically increasing microsecond counter.
|
|
* Declared here, defined in esp_stubs.c.
|
|
*/
|
|
int64_t esp_timer_get_time(void);
|
|
|
|
/** Stub: timer lifecycle (no-ops for fuzz testing). */
|
|
static inline esp_err_t esp_timer_create(const esp_timer_create_args_t *args, esp_timer_handle_t *h) {
|
|
(void)args; if (h) *h = (void *)1; return ESP_OK;
|
|
}
|
|
static inline esp_err_t esp_timer_start_periodic(esp_timer_handle_t h, uint64_t period) {
|
|
(void)h; (void)period; return ESP_OK;
|
|
}
|
|
static inline esp_err_t esp_timer_stop(esp_timer_handle_t h) { (void)h; return ESP_OK; }
|
|
static inline esp_err_t esp_timer_delete(esp_timer_handle_t h) { (void)h; return ESP_OK; }
|
|
|
|
/* ---- esp_wifi_types.h ---- */
|
|
|
|
/** Minimal rx_ctrl fields needed by csi_serialize_frame. */
|
|
typedef struct {
|
|
signed rssi : 8;
|
|
unsigned channel : 4;
|
|
unsigned noise_floor : 8;
|
|
unsigned rx_ant : 2;
|
|
/* Padding to fill out the struct so it compiles. */
|
|
unsigned _pad : 10;
|
|
} wifi_pkt_rx_ctrl_t;
|
|
|
|
/** Minimal wifi_csi_info_t needed by csi_serialize_frame. */
|
|
typedef struct {
|
|
wifi_pkt_rx_ctrl_t rx_ctrl;
|
|
uint8_t mac[6];
|
|
int16_t len; /**< Length of the I/Q buffer in bytes. */
|
|
int8_t *buf; /**< Pointer to I/Q data. */
|
|
} wifi_csi_info_t;
|
|
|
|
/* ---- Kconfig defaults ---- */
|
|
#ifndef CONFIG_CSI_NODE_ID
|
|
#define CONFIG_CSI_NODE_ID 1
|
|
#endif
|
|
|
|
#ifndef CONFIG_CSI_WIFI_CHANNEL
|
|
#define CONFIG_CSI_WIFI_CHANNEL 6
|
|
#endif
|
|
|
|
#ifndef CONFIG_CSI_WIFI_SSID
|
|
#define CONFIG_CSI_WIFI_SSID "test_ssid"
|
|
#endif
|
|
|
|
#ifndef CONFIG_CSI_TARGET_IP
|
|
#define CONFIG_CSI_TARGET_IP "192.168.1.1"
|
|
#endif
|
|
|
|
#ifndef CONFIG_CSI_TARGET_PORT
|
|
#define CONFIG_CSI_TARGET_PORT 5500
|
|
#endif
|
|
|
|
/* Suppress the build-time guard in csi_collector.c */
|
|
#ifndef CONFIG_ESP_WIFI_CSI_ENABLED
|
|
#define CONFIG_ESP_WIFI_CSI_ENABLED 1
|
|
#endif
|
|
|
|
/* ---- sdkconfig.h stub ---- */
|
|
/* (empty — all needed CONFIG_ macros are above) */
|
|
|
|
/* ---- FreeRTOS stubs ---- */
|
|
#define pdMS_TO_TICKS(x) ((x))
|
|
#define pdPASS 1
|
|
typedef int BaseType_t;
|
|
|
|
static inline int xPortGetCoreID(void) { return 0; }
|
|
static inline void vTaskDelay(uint32_t ticks) { (void)ticks; }
|
|
static inline BaseType_t xTaskCreatePinnedToCore(
|
|
void (*fn)(void *), const char *name, uint32_t stack,
|
|
void *arg, int prio, void *handle, int core)
|
|
{
|
|
(void)fn; (void)name; (void)stack; (void)arg;
|
|
(void)prio; (void)handle; (void)core;
|
|
return pdPASS;
|
|
}
|
|
|
|
/* ---- WiFi API stubs (no-ops) ---- */
|
|
typedef int wifi_interface_t;
|
|
typedef int wifi_second_chan_t;
|
|
#define WIFI_IF_STA 0
|
|
#define WIFI_SECOND_CHAN_NONE 0
|
|
|
|
typedef struct {
|
|
unsigned filter_mask;
|
|
} wifi_promiscuous_filter_t;
|
|
|
|
typedef int wifi_promiscuous_pkt_type_t;
|
|
#define WIFI_PROMIS_FILTER_MASK_MGMT 1
|
|
#define WIFI_PROMIS_FILTER_MASK_DATA 2
|
|
|
|
typedef struct {
|
|
int lltf_en;
|
|
int htltf_en;
|
|
int stbc_htltf2_en;
|
|
int ltf_merge_en;
|
|
int channel_filter_en;
|
|
int manu_scale;
|
|
int shift;
|
|
} wifi_csi_config_t;
|
|
|
|
typedef struct {
|
|
uint8_t primary;
|
|
} wifi_ap_record_t;
|
|
|
|
static inline esp_err_t esp_wifi_set_promiscuous(bool en) { (void)en; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_promiscuous_rx_cb(void *cb) { (void)cb; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_promiscuous_filter(wifi_promiscuous_filter_t *f) { (void)f; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_csi_config(wifi_csi_config_t *c) { (void)c; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_csi_rx_cb(void *cb, void *ctx) { (void)cb; (void)ctx; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_csi(bool en) { (void)en; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_set_channel(uint8_t ch, wifi_second_chan_t sc) { (void)ch; (void)sc; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *b, int len, bool en) { (void)ifx; (void)b; (void)len; (void)en; return ESP_OK; }
|
|
static inline esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap) { (void)ap; return ESP_FAIL; }
|
|
static inline const char *esp_err_to_name(esp_err_t code) { (void)code; return "STUB"; }
|
|
|
|
/* ---- NVS stubs ---- */
|
|
typedef uint32_t nvs_handle_t;
|
|
#define NVS_READONLY 0
|
|
static inline esp_err_t nvs_open(const char *ns, int mode, nvs_handle_t *h) { (void)ns; (void)mode; (void)h; return ESP_FAIL; }
|
|
static inline void nvs_close(nvs_handle_t h) { (void)h; }
|
|
static inline esp_err_t nvs_get_str(nvs_handle_t h, const char *k, char *v, size_t *l) { (void)h; (void)k; (void)v; (void)l; return ESP_FAIL; }
|
|
static inline esp_err_t nvs_get_u8(nvs_handle_t h, const char *k, uint8_t *v) { (void)h; (void)k; (void)v; return ESP_FAIL; }
|
|
static inline esp_err_t nvs_get_u16(nvs_handle_t h, const char *k, uint16_t *v) { (void)h; (void)k; (void)v; return ESP_FAIL; }
|
|
static inline esp_err_t nvs_get_u32(nvs_handle_t h, const char *k, uint32_t *v) { (void)h; (void)k; (void)v; return ESP_FAIL; }
|
|
static inline esp_err_t nvs_get_blob(nvs_handle_t h, const char *k, void *v, size_t *l) { (void)h; (void)k; (void)v; (void)l; return ESP_FAIL; }
|
|
|
|
/* ---- stream_sender stubs (defined in esp_stubs.c) ---- */
|
|
int stream_sender_send(const uint8_t *data, size_t len);
|
|
int stream_sender_init(void);
|
|
int stream_sender_init_with(const char *ip, uint16_t port);
|
|
void stream_sender_deinit(void);
|
|
|
|
/*
|
|
* wasm_runtime stubs: defined in esp_stubs.c.
|
|
* The actual prototype comes from ../main/wasm_runtime.h (via csi_collector.c).
|
|
* We just need the definition in esp_stubs.c to link.
|
|
*/
|
|
|
|
#endif /* ESP_STUBS_H */
|