fix(esp32): correct mqtt component name + %u format casts; add build-verified examples

Building veil_ris_controller/veil_sensing_detector for real against ESP-IDF
v5.4 (esp32s3 target) surfaced two compile bugs, now fixed in both the
firmware/privshield/ and wifi-veil/ copies:
- veil_sensing_detector/CMakeLists.txt: PRIV_REQUIRES esp_mqtt -> mqtt
  (esp_mqtt is not a real ESP-IDF v5.4 component name; the real one is mqtt)
- veil_ris_controller.c / veil_sensing_detector.c: ESP_LOGI("%u", ...) calls
  passed a bare uint32_t; -Werror=format= requires (unsigned) casts

Also adds esp32/examples/ — minimal ESP-IDF apps wrapping each component's
public API, added purely to prove they compile+link on a real toolchain.
Still SYNTHETIC / L0, build-only — never flashed, no hardware exists.
This commit is contained in:
ruv
2026-08-09 15:46:39 -02:30
parent 50bcf0e215
commit e737b1a7bc
22 changed files with 244 additions and 6 deletions

View File

@@ -1,2 +1,9 @@
core/test_veil_shield
*.o
# ESP-IDF example build output
esp32/examples/*/build/
esp32/examples/*/managed_components/
esp32/examples/*/sdkconfig
esp32/examples/*/sdkconfig.old
esp32/examples/*/dependencies.lock

View File

@@ -0,0 +1,22 @@
# ESP32 build-only examples
**STATUS: `SYNTHETIC / L0` — build-only, never flashed.** These two minimal
ESP-IDF apps exist only to prove `veil_ris_controller` and
`veil_sensing_detector` actually compile and link against a real ESP-IDF
toolchain (v5.4, `esp32s3` target). Building successfully is not a runtime or
on-air claim — see `../README.md`.
```
idf.py set-target esp32s3
idf.py build
```
Both were built and verified locally against ESP-IDF v5.4 (`xtensa-esp32s3-elf`,
GCC 14.2.0); the resulting `.bin`/`.elf` are attached to the GitHub release.
Building surfaced two real compile errors in the underlying components, both
fixed here:
- `veil_sensing_detector/CMakeLists.txt` declared `PRIV_REQUIRES esp_mqtt`;
the actual ESP-IDF v5.4 component is named `mqtt`.
- Two `ESP_LOGI(..., "%u", ...)` calls passed a bare `uint32_t` where the
toolchain's `-Werror=format=` requires an explicit `(unsigned)` cast.

View File

@@ -0,0 +1,13 @@
# veil_ris_controller_example — SYNTHETIC / L0, build-only.
#
# Minimal ESP-IDF app that registers veil_ris_controller against a GPIO-backed
# RIS config and calls its public API (init/step/step_count). Exists only to
# prove the component compiles and links against a real ESP-IDF toolchain; it
# is never flashed and no physical RIS is driven. See ../../README.md.
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../veil_ris_controller")
project(veil_ris_controller_example)

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "app_main.c"
INCLUDE_DIRS "."
REQUIRES veil_ris_controller
)

View File

@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT OR Apache-2.0
*
* SYNTHETIC / L0 — build-only. Exercises veil_ris_controller's public API
* against a GPIO-backed config so the component compiles and links on a real
* ESP-IDF toolchain. Never flashed; no physical RIS exists. Per the component
* README, do not treat a successful build as a runtime or on-air claim.
*/
#include "esp_log.h"
#include "veil_ris_controller.h"
static const char *TAG = "veil_ris_controller_example";
static const int kRisPins[4] = {4, 5, 6, 7};
void app_main(void)
{
veil_ris_controller_cfg_t cfg = {
.iface = VEIL_RIS_IFACE_GPIO,
.n_elements = 4,
.key = 0x5EED5EED5EED5EEDULL,
.dwell_us = 500,
.gpio_pins = kRisPins,
.spi_host = -1,
.spi_cs_gpio = -1,
.spi_clock_hz = 0,
};
ESP_ERROR_CHECK(veil_ris_controller_init(&cfg));
ESP_ERROR_CHECK(veil_ris_controller_step(NULL, 0));
ESP_LOGI(TAG, "step_count=%llu (build-only, never flashed)",
(unsigned long long)veil_ris_controller_step_count());
}

View File

@@ -0,0 +1,13 @@
# veil_sensing_detector_example — SYNTHETIC / L0, build-only.
#
# Minimal ESP-IDF app that registers veil_sensing_detector with the GPIO
# trigger backend and calls its public API. Exists only to prove the
# component compiles and links against a real ESP-IDF toolchain; it is never
# flashed and no CSI is ever captured. See ../../README.md.
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../veil_sensing_detector")
project(veil_sensing_detector_example)

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "app_main.c"
INCLUDE_DIRS "."
REQUIRES veil_sensing_detector
)

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT OR Apache-2.0
*
* SYNTHETIC / L0 — build-only. Exercises veil_sensing_detector's public API
* against the GPIO trigger backend so the component compiles and links on a
* real ESP-IDF toolchain. Never flashed; no CSI is ever captured. Per the
* component README, do not treat a successful build as a runtime or on-air
* claim.
*/
#include "esp_log.h"
#include "veil_sensing_detector.h"
static const char *TAG = "veil_sensing_detector_example";
void app_main(void)
{
veil_sensing_detector_cfg_t cfg = VEIL_SENSING_DETECTOR_DEFAULT_CFG();
cfg.backend = VEIL_TRIGGER_GPIO;
cfg.gpio_num = 8;
ESP_ERROR_CHECK(veil_sensing_detector_start(&cfg));
ESP_LOGI(TAG, "rate_hz=%.2f engaged=%d (build-only, never flashed)",
veil_sensing_detector_rate_hz(), veil_sensing_detector_engaged());
}

View File

@@ -128,7 +128,7 @@ esp_err_t veil_ris_controller_init(const veil_ris_controller_cfg_t *cfg)
s_inited = true;
ESP_LOGI(TAG, "init (SYNTHETIC/L0): %u elements, dwell=%uus, keyed schedule",
(unsigned)s_cfg.n_elements, s_cfg.dwell_us);
(unsigned)s_cfg.n_elements, (unsigned)s_cfg.dwell_us);
return ESP_OK;
}

View File

@@ -15,5 +15,5 @@ idf_component_register(
# The MQTT and ESP-NOW trigger backends are optional; they are only
# referenced under CONFIG_ guards so the core build stays minimal.
REQUIRES esp_wifi esp_event esp_timer esp_driver_gpio
PRIV_REQUIRES esp_mqtt
PRIV_REQUIRES mqtt
)

View File

@@ -166,7 +166,7 @@ esp_err_t veil_sensing_detector_start(const veil_sensing_detector_cfg_t *cfg)
s_running = true;
ESP_LOGI(TAG, "started (SYNTHETIC/L0): window=%ums engage>=%.1fHz",
s_cfg.window_ms, s_cfg.trigger_rate_hz);
(unsigned)s_cfg.window_ms, s_cfg.trigger_rate_hz);
return ESP_OK;
}

View File

@@ -9,6 +9,13 @@ Cargo.lock
firmware/**/*.o
firmware/core/test_veil_shield
# ESP-IDF example build output
firmware/esp32/examples/*/build/
firmware/esp32/examples/*/managed_components/
firmware/esp32/examples/*/sdkconfig
firmware/esp32/examples/*/sdkconfig.old
firmware/esp32/examples/*/dependencies.lock
# Node / harness
node_modules/
harness/dist/

View File

@@ -0,0 +1,22 @@
# ESP32 build-only examples
**STATUS: `SYNTHETIC / L0` — build-only, never flashed.** These two minimal
ESP-IDF apps exist only to prove `veil_ris_controller` and
`veil_sensing_detector` actually compile and link against a real ESP-IDF
toolchain (v5.4, `esp32s3` target). Building successfully is not a runtime or
on-air claim — see `../README.md`.
```
idf.py set-target esp32s3
idf.py build
```
Both were built and verified locally against ESP-IDF v5.4 (`xtensa-esp32s3-elf`,
GCC 14.2.0); the resulting `.bin`/`.elf` are attached to the GitHub release.
Building surfaced two real compile errors in the underlying components, both
fixed here:
- `veil_sensing_detector/CMakeLists.txt` declared `PRIV_REQUIRES esp_mqtt`;
the actual ESP-IDF v5.4 component is named `mqtt`.
- Two `ESP_LOGI(..., "%u", ...)` calls passed a bare `uint32_t` where the
toolchain's `-Werror=format=` requires an explicit `(unsigned)` cast.

View File

@@ -0,0 +1,13 @@
# veil_ris_controller_example — SYNTHETIC / L0, build-only.
#
# Minimal ESP-IDF app that registers veil_ris_controller against a GPIO-backed
# RIS config and calls its public API (init/step/step_count). Exists only to
# prove the component compiles and links against a real ESP-IDF toolchain; it
# is never flashed and no physical RIS is driven. See ../../README.md.
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../veil_ris_controller")
project(veil_ris_controller_example)

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "app_main.c"
INCLUDE_DIRS "."
REQUIRES veil_ris_controller
)

View File

@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT OR Apache-2.0
*
* SYNTHETIC / L0 — build-only. Exercises veil_ris_controller's public API
* against a GPIO-backed config so the component compiles and links on a real
* ESP-IDF toolchain. Never flashed; no physical RIS exists. Per the component
* README, do not treat a successful build as a runtime or on-air claim.
*/
#include "esp_log.h"
#include "veil_ris_controller.h"
static const char *TAG = "veil_ris_controller_example";
static const int kRisPins[4] = {4, 5, 6, 7};
void app_main(void)
{
veil_ris_controller_cfg_t cfg = {
.iface = VEIL_RIS_IFACE_GPIO,
.n_elements = 4,
.key = 0x5EED5EED5EED5EEDULL,
.dwell_us = 500,
.gpio_pins = kRisPins,
.spi_host = -1,
.spi_cs_gpio = -1,
.spi_clock_hz = 0,
};
ESP_ERROR_CHECK(veil_ris_controller_init(&cfg));
ESP_ERROR_CHECK(veil_ris_controller_step(NULL, 0));
ESP_LOGI(TAG, "step_count=%llu (build-only, never flashed)",
(unsigned long long)veil_ris_controller_step_count());
}

View File

@@ -0,0 +1,13 @@
# veil_sensing_detector_example — SYNTHETIC / L0, build-only.
#
# Minimal ESP-IDF app that registers veil_sensing_detector with the GPIO
# trigger backend and calls its public API. Exists only to prove the
# component compiles and links against a real ESP-IDF toolchain; it is never
# flashed and no CSI is ever captured. See ../../README.md.
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../veil_sensing_detector")
project(veil_sensing_detector_example)

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "app_main.c"
INCLUDE_DIRS "."
REQUIRES veil_sensing_detector
)

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT OR Apache-2.0
*
* SYNTHETIC / L0 — build-only. Exercises veil_sensing_detector's public API
* against the GPIO trigger backend so the component compiles and links on a
* real ESP-IDF toolchain. Never flashed; no CSI is ever captured. Per the
* component README, do not treat a successful build as a runtime or on-air
* claim.
*/
#include "esp_log.h"
#include "veil_sensing_detector.h"
static const char *TAG = "veil_sensing_detector_example";
void app_main(void)
{
veil_sensing_detector_cfg_t cfg = VEIL_SENSING_DETECTOR_DEFAULT_CFG();
cfg.backend = VEIL_TRIGGER_GPIO;
cfg.gpio_num = 8;
ESP_ERROR_CHECK(veil_sensing_detector_start(&cfg));
ESP_LOGI(TAG, "rate_hz=%.2f engaged=%d (build-only, never flashed)",
veil_sensing_detector_rate_hz(), veil_sensing_detector_engaged());
}

View File

@@ -128,7 +128,7 @@ esp_err_t veil_ris_controller_init(const veil_ris_controller_cfg_t *cfg)
s_inited = true;
ESP_LOGI(TAG, "init (SYNTHETIC/L0): %u elements, dwell=%uus, keyed schedule",
(unsigned)s_cfg.n_elements, s_cfg.dwell_us);
(unsigned)s_cfg.n_elements, (unsigned)s_cfg.dwell_us);
return ESP_OK;
}

View File

@@ -15,5 +15,5 @@ idf_component_register(
# The MQTT and ESP-NOW trigger backends are optional; they are only
# referenced under CONFIG_ guards so the core build stays minimal.
REQUIRES esp_wifi esp_event esp_timer esp_driver_gpio
PRIV_REQUIRES esp_mqtt
PRIV_REQUIRES mqtt
)

View File

@@ -166,7 +166,7 @@ esp_err_t veil_sensing_detector_start(const veil_sensing_detector_cfg_t *cfg)
s_running = true;
ESP_LOGI(TAG, "started (SYNTHETIC/L0): window=%ums engage>=%.1fHz",
s_cfg.window_ms, s_cfg.trigger_rate_hz);
(unsigned)s_cfg.window_ms, s_cfg.trigger_rate_hz);
return ESP_OK;
}