From e737b1a7bcb5b35fb8df08783c3092010c6fd0d1 Mon Sep 17 00:00:00 2001 From: ruv Date: Sun, 9 Aug 2026 15:46:39 -0230 Subject: [PATCH] fix(esp32): correct mqtt component name + %u format casts; add build-verified examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- firmware/privshield/.gitignore | 7 +++++ firmware/privshield/esp32/examples/README.md | 22 +++++++++++++ .../CMakeLists.txt | 13 ++++++++ .../main/CMakeLists.txt | 5 +++ .../main/app_main.c | 31 +++++++++++++++++++ .../CMakeLists.txt | 13 ++++++++ .../main/CMakeLists.txt | 5 +++ .../main/app_main.c | 23 ++++++++++++++ .../veil_ris_controller/veil_ris_controller.c | 2 +- .../veil_sensing_detector/CMakeLists.txt | 2 +- .../veil_sensing_detector.c | 2 +- wifi-veil/.gitignore | 7 +++++ wifi-veil/firmware/esp32/examples/README.md | 22 +++++++++++++ .../CMakeLists.txt | 13 ++++++++ .../main/CMakeLists.txt | 5 +++ .../main/app_main.c | 31 +++++++++++++++++++ .../CMakeLists.txt | 13 ++++++++ .../main/CMakeLists.txt | 5 +++ .../main/app_main.c | 23 ++++++++++++++ .../veil_ris_controller/veil_ris_controller.c | 2 +- .../veil_sensing_detector/CMakeLists.txt | 2 +- .../veil_sensing_detector.c | 2 +- 22 files changed, 244 insertions(+), 6 deletions(-) create mode 100644 firmware/privshield/esp32/examples/README.md create mode 100644 firmware/privshield/esp32/examples/veil_ris_controller_example/CMakeLists.txt create mode 100644 firmware/privshield/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt create mode 100644 firmware/privshield/esp32/examples/veil_ris_controller_example/main/app_main.c create mode 100644 firmware/privshield/esp32/examples/veil_sensing_detector_example/CMakeLists.txt create mode 100644 firmware/privshield/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt create mode 100644 firmware/privshield/esp32/examples/veil_sensing_detector_example/main/app_main.c create mode 100644 wifi-veil/firmware/esp32/examples/README.md create mode 100644 wifi-veil/firmware/esp32/examples/veil_ris_controller_example/CMakeLists.txt create mode 100644 wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt create mode 100644 wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/app_main.c create mode 100644 wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/CMakeLists.txt create mode 100644 wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt create mode 100644 wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/app_main.c diff --git a/firmware/privshield/.gitignore b/firmware/privshield/.gitignore index 4c3b6bdc..c7c1d01f 100644 --- a/firmware/privshield/.gitignore +++ b/firmware/privshield/.gitignore @@ -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 diff --git a/firmware/privshield/esp32/examples/README.md b/firmware/privshield/esp32/examples/README.md new file mode 100644 index 00000000..dcdc0aea --- /dev/null +++ b/firmware/privshield/esp32/examples/README.md @@ -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. diff --git a/firmware/privshield/esp32/examples/veil_ris_controller_example/CMakeLists.txt b/firmware/privshield/esp32/examples/veil_ris_controller_example/CMakeLists.txt new file mode 100644 index 00000000..ee5ce804 --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_ris_controller_example/CMakeLists.txt @@ -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) diff --git a/firmware/privshield/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt b/firmware/privshield/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt new file mode 100644 index 00000000..ba00bf4f --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "app_main.c" + INCLUDE_DIRS "." + REQUIRES veil_ris_controller +) diff --git a/firmware/privshield/esp32/examples/veil_ris_controller_example/main/app_main.c b/firmware/privshield/esp32/examples/veil_ris_controller_example/main/app_main.c new file mode 100644 index 00000000..7479be5b --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_ris_controller_example/main/app_main.c @@ -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()); +} diff --git a/firmware/privshield/esp32/examples/veil_sensing_detector_example/CMakeLists.txt b/firmware/privshield/esp32/examples/veil_sensing_detector_example/CMakeLists.txt new file mode 100644 index 00000000..d95523eb --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_sensing_detector_example/CMakeLists.txt @@ -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) diff --git a/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt b/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt new file mode 100644 index 00000000..55e31270 --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "app_main.c" + INCLUDE_DIRS "." + REQUIRES veil_sensing_detector +) diff --git a/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/app_main.c b/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/app_main.c new file mode 100644 index 00000000..33076772 --- /dev/null +++ b/firmware/privshield/esp32/examples/veil_sensing_detector_example/main/app_main.c @@ -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()); +} diff --git a/firmware/privshield/esp32/veil_ris_controller/veil_ris_controller.c b/firmware/privshield/esp32/veil_ris_controller/veil_ris_controller.c index 0a57064f..6d01f22e 100644 --- a/firmware/privshield/esp32/veil_ris_controller/veil_ris_controller.c +++ b/firmware/privshield/esp32/veil_ris_controller/veil_ris_controller.c @@ -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; } diff --git a/firmware/privshield/esp32/veil_sensing_detector/CMakeLists.txt b/firmware/privshield/esp32/veil_sensing_detector/CMakeLists.txt index b3cc18b5..29fdf284 100644 --- a/firmware/privshield/esp32/veil_sensing_detector/CMakeLists.txt +++ b/firmware/privshield/esp32/veil_sensing_detector/CMakeLists.txt @@ -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 ) diff --git a/firmware/privshield/esp32/veil_sensing_detector/veil_sensing_detector.c b/firmware/privshield/esp32/veil_sensing_detector/veil_sensing_detector.c index 6d86ccd3..08b5997c 100644 --- a/firmware/privshield/esp32/veil_sensing_detector/veil_sensing_detector.c +++ b/firmware/privshield/esp32/veil_sensing_detector/veil_sensing_detector.c @@ -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; } diff --git a/wifi-veil/.gitignore b/wifi-veil/.gitignore index c85ba386..23946dab 100644 --- a/wifi-veil/.gitignore +++ b/wifi-veil/.gitignore @@ -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/ diff --git a/wifi-veil/firmware/esp32/examples/README.md b/wifi-veil/firmware/esp32/examples/README.md new file mode 100644 index 00000000..dcdc0aea --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/README.md @@ -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. diff --git a/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/CMakeLists.txt b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/CMakeLists.txt new file mode 100644 index 00000000..ee5ce804 --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/CMakeLists.txt @@ -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) diff --git a/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt new file mode 100644 index 00000000..ba00bf4f --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "app_main.c" + INCLUDE_DIRS "." + REQUIRES veil_ris_controller +) diff --git a/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/app_main.c b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/app_main.c new file mode 100644 index 00000000..7479be5b --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_ris_controller_example/main/app_main.c @@ -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()); +} diff --git a/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/CMakeLists.txt b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/CMakeLists.txt new file mode 100644 index 00000000..d95523eb --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/CMakeLists.txt @@ -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) diff --git a/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt new file mode 100644 index 00000000..55e31270 --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "app_main.c" + INCLUDE_DIRS "." + REQUIRES veil_sensing_detector +) diff --git a/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/app_main.c b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/app_main.c new file mode 100644 index 00000000..33076772 --- /dev/null +++ b/wifi-veil/firmware/esp32/examples/veil_sensing_detector_example/main/app_main.c @@ -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()); +} diff --git a/wifi-veil/firmware/esp32/veil_ris_controller/veil_ris_controller.c b/wifi-veil/firmware/esp32/veil_ris_controller/veil_ris_controller.c index 0a57064f..6d01f22e 100644 --- a/wifi-veil/firmware/esp32/veil_ris_controller/veil_ris_controller.c +++ b/wifi-veil/firmware/esp32/veil_ris_controller/veil_ris_controller.c @@ -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; } diff --git a/wifi-veil/firmware/esp32/veil_sensing_detector/CMakeLists.txt b/wifi-veil/firmware/esp32/veil_sensing_detector/CMakeLists.txt index b3cc18b5..29fdf284 100644 --- a/wifi-veil/firmware/esp32/veil_sensing_detector/CMakeLists.txt +++ b/wifi-veil/firmware/esp32/veil_sensing_detector/CMakeLists.txt @@ -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 ) diff --git a/wifi-veil/firmware/esp32/veil_sensing_detector/veil_sensing_detector.c b/wifi-veil/firmware/esp32/veil_sensing_detector/veil_sensing_detector.c index 6d86ccd3..08b5997c 100644 --- a/wifi-veil/firmware/esp32/veil_sensing_detector/veil_sensing_detector.c +++ b/wifi-veil/firmware/esp32/veil_sensing_detector/veil_sensing_detector.c @@ -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; }