You are using staging server - a separate instance of the ESP Component Registry that allows you to try distribution tools and processes without affecting the real registry.

francescopace/espectre

3.0.0-rc2-7-ga75f4d1.develop

Pre-release
uploaded 10 hours ago
ESPectre SDK for Wi-Fi motion detection on ESP32 devices.

Api

# ESPectre SDK C++ API

Version: `3.0.0-rc2-7-ga75f4d1.develop`

Source commit: `a75f4d16f537acf39dce6899021abde401b02813`

[SDK guide](README.md)

## Contents

- [ESPectre SDK](#indexpage)
- [Deprecated List](#deprecated)
- [Integration details](#sdk_integration)
- [espectre](#namespaceespectre)
- [espectre::detail](#namespaceespectre_1_1detail)
- [espectre::task\_scheduling](#namespaceespectre_1_1task__scheduling)
- [espectre::BaseDetector](#classespectre_1_1_base_detector)
- [espectre::CsiTrafficService](#classespectre_1_1_csi_traffic_service)
- [espectre::CsiTrafficServiceConfig](#structespectre_1_1_csi_traffic_service_config)
- [espectre::DeviceConfigCommandResult](#structespectre_1_1_device_config_command_result)
- [espectre::DirectHttpServiceConfig](#structespectre_1_1_direct_http_service_config)
- [espectre::DirectHttpServiceDiagnostics](#structespectre_1_1_direct_http_service_diagnostics)
- [espectre::DirectRequest](#structespectre_1_1_direct_request)
- [espectre::DirectWifiSnapshot](#structespectre_1_1_direct_wifi_snapshot)
- [espectre::EspIdfDirectHttpService](#classespectre_1_1_esp_idf_direct_http_service)
- [espectre::EspIdfMqttTransport](#classespectre_1_1_esp_idf_mqtt_transport)
- [espectre::EspIdfPeerDiscoveryService](#classespectre_1_1_esp_idf_peer_discovery_service)
- [espectre::EspectreApiEventDescriptor](#structespectre_1_1_espectre_api_event_descriptor)
- [espectre::EspectreApiRoute](#structespectre_1_1_espectre_api_route)
- [espectre::EspectreCapabilityProfile](#structespectre_1_1_espectre_capability_profile)
- [espectre::EspectreCommand](#structespectre_1_1_espectre_command)
- [espectre::EspectreDeviceConfig](#structespectre_1_1_espectre_device_config)
- [espectre::EspectreDeviceInfo](#structespectre_1_1_espectre_device_info)
- [espectre::EspectreExtensionRoute](#structespectre_1_1_espectre_extension_route)
- [espectre::EspectreNetworkInfo](#structespectre_1_1_espectre_network_info)
- [espectre::EspectreProtocolExtension](#structespectre_1_1_espectre_protocol_extension)
- [espectre::FrontendCommandContext](#structespectre_1_1_frontend_command_context)
- [espectre::FrontendCommandEngine](#classespectre_1_1_frontend_command_engine)
- [espectre::FrontendCommandResult](#structespectre_1_1_frontend_command_result)
- [espectre::FrontendDeviceConfigDefaults](#structespectre_1_1_frontend_device_config_defaults)
- [espectre::FrontendHaDiagnosticSensor](#structespectre_1_1_frontend_ha_diagnostic_sensor)
- [espectre::FrontendHaDiscoveryMessage](#structespectre_1_1_frontend_ha_discovery_message)
- [espectre::FrontendHaMqttSettings](#structespectre_1_1_frontend_ha_mqtt_settings)
- [espectre::FrontendWifiStationOptions](#structespectre_1_1_frontend_wifi_station_options)
- [espectre::HighAccuracyDetector](#classespectre_1_1_high_accuracy_detector)
- [espectre::ICsiTrafficGenerator](#classespectre_1_1_i_csi_traffic_generator)
- [espectre::ICsiTrafficIngress](#classespectre_1_1_i_csi_traffic_ingress)
- [espectre::IDirectHttpService](#classespectre_1_1_i_direct_http_service)
- [espectre::IDirectHttpService::DeferredRequestResult](#structespectre_1_1_i_direct_http_service_1_1_deferred_request_result)
- [espectre::IEspectreRuntime](#classespectre_1_1_i_espectre_runtime)
- [espectre::IMqttTransport](#classespectre_1_1_i_mqtt_transport)
- [espectre::IPeerDiscoveryService](#classespectre_1_1_i_peer_discovery_service)
- [espectre::IRuntimeListener](#classespectre_1_1_i_runtime_listener)
- [espectre::IUdpDatagramSocket](#classespectre_1_1_i_udp_datagram_socket)
- [espectre::JsonObjectField](#structespectre_1_1_json_object_field)
- [espectre::LightweightDetector](#classespectre_1_1_lightweight_detector)
- [espectre::LogSink](#structespectre_1_1_log_sink)
- [espectre::MdnsBootstrapResponder](#classespectre_1_1_mdns_bootstrap_responder)
- [espectre::MdnsDiscoveryService](#classespectre_1_1_mdns_discovery_service)
- [espectre::MdnsDiscoveryServiceConfig](#structespectre_1_1_mdns_discovery_service_config)
- [espectre::MqttPayloadAssembler](#classespectre_1_1_mqtt_payload_assembler)
- [espectre::MqttTransportDiagnostics](#structespectre_1_1_mqtt_transport_diagnostics)
- [espectre::PeerDiscoveryCandidate](#structespectre_1_1_peer_discovery_candidate)
- [espectre::PeerDiscoverySnapshot](#structespectre_1_1_peer_discovery_snapshot)
- [espectre::PendingEvent](#classespectre_1_1_pending_event)
- [espectre::PendingQueue](#classespectre_1_1_pending_queue)
- [espectre::RawCsiHttpFramePrefix](#structespectre_1_1_raw_csi_http_frame_prefix)
- [espectre::RawCsiPacketView](#structespectre_1_1_raw_csi_packet_view)
- [espectre::RawCsiRecordHeaderV7](#structespectre_1_1_raw_csi_record_header_v7)
- [espectre::RawCsiRecordHeaderV8](#structespectre_1_1_raw_csi_record_header_v8)
- [espectre::RawCsiSessionConfig](#structespectre_1_1_raw_csi_session_config)
- [espectre::RawCsiSessionController](#classespectre_1_1_raw_csi_session_controller)
- [espectre::RawCsiSessionDiagnostics](#structespectre_1_1_raw_csi_session_diagnostics)
- [espectre::RuntimeCapabilities](#structespectre_1_1_runtime_capabilities)
- [espectre::RuntimeConfig](#structespectre_1_1_runtime_config)
- [espectre::RuntimeDiagnosticsSample](#structespectre_1_1_runtime_diagnostics_sample)
- [espectre::RuntimeDiagnosticsSampler](#classespectre_1_1_runtime_diagnostics_sampler)
- [espectre::RuntimeDiagnosticsSnapshot](#structespectre_1_1_runtime_diagnostics_snapshot)
- [espectre::RuntimeDirectHttpBridge](#classespectre_1_1_runtime_direct_http_bridge)
- [espectre::RuntimeDirectHttpBridgeConfig](#structespectre_1_1_runtime_direct_http_bridge_config)
- [espectre::RuntimeEventMailbox](#classespectre_1_1_runtime_event_mailbox)
- [espectre::RuntimeFrontendController](#classespectre_1_1_runtime_frontend_controller)
- [espectre::RuntimeSnapshot](#structespectre_1_1_runtime_snapshot)
- [espectre::StandaloneWifiAccessPoint](#structespectre_1_1_standalone_wifi_access_point)
- [espectre::StandaloneWifiConfig](#structespectre_1_1_standalone_wifi_config)
- [espectre::StandaloneWifiInfo](#structespectre_1_1_standalone_wifi_info)
- [espectre::StandaloneWifiService](#classespectre_1_1_standalone_wifi_service)
- [espectre::StoredWifiConfig](#structespectre_1_1_stored_wifi_config)
- [espectre::TemporalCsiSampler](#classespectre_1_1_temporal_csi_sampler)
- [espectre::TrafficGeneratorManager](#classespectre_1_1_traffic_generator_manager)
- [espectre::UdpDatagramPeer](#structespectre_1_1_udp_datagram_peer)
- [espectre::WiFiLifecycleManager](#classespectre_1_1_wi_fi_lifecycle_manager)
- [espectre::WifiBssidPinService](#classespectre_1_1_wifi_bssid_pin_service)
- [espectre::WifiBssidPinServiceConfig](#structespectre_1_1_wifi_bssid_pin_service_config)
- [espectre::WifiBssidPinStationState](#structespectre_1_1_wifi_bssid_pin_station_state)
- [espectre::WifiProvisioningDefaults](#structespectre_1_1_wifi_provisioning_defaults)
- [espectre::WifiProvisioningService](#classespectre_1_1_wifi_provisioning_service)
- [espectre::detail::PendingEventLock](#classespectre_1_1detail_1_1_pending_event_lock)
- [espectre\_diagnostic\_field\_t](#structespectre__diagnostic__field__t)
- [base\_detector.h](#base__detector_8h)
- [csi\_capture\_profile.h](#csi__capture__profile_8h)
- [csi\_format.h](#csi__format_8h)
- [csi\_raw\_record.h](#csi__raw__record_8h)
- [csi\_traffic\_service.h](#csi__traffic__service_8h)
- [csi\_traffic\_types.h](#csi__traffic__types_8h)
- [csi\_types.h](#csi__types_8h)
- [detector\_limits.h](#detector__limits_8h)
- [detector\_types.h](#detector__types_8h)
- [device\_config\_store.h](#device__config__store_8h)
- [device\_identity.h](#device__identity_8h)
- [diagnostic\_fields.h](#diagnostic__fields_8h)
- [direct\_http\_protocol.h](#direct__http__protocol_8h)
- [direct\_http\_service.h](#direct__http__service_8h)
- [direct\_http\_service\_esp\_idf.h](#direct__http__service__esp__idf_8h)
- [direct\_wifi\_snapshot\_esp\_idf.h](#direct__wifi__snapshot__esp__idf_8h)
- [espectre\_banner.h](#espectre__banner_8h)
- [espectre\_core\_sdk.h](#espectre__core__sdk_8h)
- [espectre\_log.h](#espectre__log_8h)
- [espectre\_mqtt\_sdk.h](#espectre__mqtt__sdk_8h)
- [espectre\_protocol.h](#espectre__protocol_8h)
- [espectre\_sdk.h](#espectre__sdk_8h)
- [espectre\_sdk\_version.h](#espectre__sdk__version_8h)
- [espectre\_services\_sdk.h](#espectre__services__sdk_8h)
- [filter\_config.h](#filter__config_8h)
- [frontend\_bootstrap\_helpers.h](#frontend__bootstrap__helpers_8h)
- [frontend\_command\_engine.h](#frontend__command__engine_8h)
- [frontend\_ha\_mqtt\_helpers.h](#frontend__ha__mqtt__helpers_8h)
- [frontend\_mqtt\_helpers.h](#frontend__mqtt__helpers_8h)
- [high\_accuracy\_detector.h](#high__accuracy__detector_8h)
- [lightweight\_detector.h](#lightweight__detector_8h)
- [mdns\_bootstrap\_responder.h](#mdns__bootstrap__responder_8h)
- [mdns\_discovery\_service.h](#mdns__discovery__service_8h)
- [mqtt\_payload\_assembler.h](#mqtt__payload__assembler_8h)
- [mqtt\_transport.h](#mqtt__transport_8h)
- [mqtt\_transport\_esp\_idf.h](#mqtt__transport__esp__idf_8h)
- [nvs\_helpers.h](#nvs__helpers_8h)
- [peer\_discovery.h](#peer__discovery_8h)
- [peer\_discovery\_service\_esp\_idf.h](#peer__discovery__service__esp__idf_8h)
- [pending\_event.h](#pending__event_8h)
- [pending\_queue.h](#pending__queue_8h)
- [protocol\_json.h](#protocol__json_8h)
- [raw\_csi.h](#raw__csi_8h)
- [raw\_csi\_session\_controller.h](#raw__csi__session__controller_8h)
- [runtime\_capabilities.h](#runtime__capabilities_8h)
- [runtime\_config\_utils.h](#runtime__config__utils_8h)
- [runtime\_diagnostics.h](#runtime__diagnostics_8h)
- [runtime\_direct\_http\_bridge.h](#runtime__direct__http__bridge_8h)
- [runtime\_event\_mailbox.h](#runtime__event__mailbox_8h)
- [runtime\_events.h](#runtime__events_8h)
- [runtime\_frontend\_controller.h](#runtime__frontend__controller_8h)
- [runtime\_interface.h](#runtime__interface_8h)
- [runtime\_sensing\_kconfig.h](#runtime__sensing__kconfig_8h)
- [runtime\_sensing\_schema.h](#runtime__sensing__schema_8h)
- [runtime\_snapshot.h](#runtime__snapshot_8h)
- [runtime\_time.h](#runtime__time_8h)
- [standalone\_wifi\_service.h](#standalone__wifi__service_8h)
- [task\_scheduling\_config.h](#task__scheduling__config_8h)
- [temporal\_csi\_sampler.h](#temporal__csi__sampler_8h)
- [traffic\_generator\_manager.h](#traffic__generator__manager_8h)
- [udp\_datagram\_socket.h](#udp__datagram__socket_8h)
- [wifi\_band\_helpers.h](#wifi__band__helpers_8h)
- [wifi\_bssid\_pin\_service.h](#wifi__bssid__pin__service_8h)
- [wifi\_lifecycle.h](#wifi__lifecycle_8h)
- [wifi\_provisioning\_service.h](#wifi__provisioning__service_8h)
- [wifi\_tx\_rate.h](#wifi__tx__rate_8h)


<a id="indexpage"></a>

## ESPectre SDK

  

This reference covers the supported integration surface only. Every declaration included in the reference follows the SDK version contract; implementation dependencies that merely ship in the bundle are internal and may change in any release.

 

Start with the [SDK README](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/SDK.md>) for installation and a minimal application. Use [espectre\_sdk.h](#espectre__sdk_8h) for the sensing runtime, [espectre\_core\_sdk.h](#espectre__core__sdk_8h) for custom capture pipelines, [espectre\_services\_sdk.h](#espectre__services__sdk_8h) for optional services, and [espectre\_mqtt\_sdk.h](#espectre__mqtt__sdk_8h) for the ESP-IDF MQTT implementation.

 

[Integration details](#sdk_integration) documents lifecycle, threading, source compatibility, and advanced integration contracts for this version of the SDK.

 

<a id="deprecated"></a>

## Deprecated List

  

Member [espectre::espectre\_device\_id\_from\_mac](#namespaceespectre_1adc03ef2a0c49d818c944747283819e1a) (const uint8\_t \*mac, size\_t mac\_len)

 

<a id="deprecated_1_deprecated000001"></a>

Runtime firmware uses the cached, domain-separated SHA-256 pseudonym from [`derive_runtime_device_id()`](#namespaceespectre_1a34031a60d78bbb6306047b3540b4f905) instead.

 

Member [espectre::ESPECTRE\_DIRECT\_MAX\_METHOD\_SIZE](#namespaceespectre_1a53e26f01271bcce51eabeb7f765385a1)

 

<a id="deprecated_1_deprecated000003"></a>

Command names are validated by the canonical registry.

 

Member [espectre::ESPECTRE\_DIRECT\_MAX\_REQUEST\_ID\_SIZE](#namespaceespectre_1a90f09ac217de8fc9fe33fa72d0dca455)

 

<a id="deprecated_1_deprecated000002"></a>

Use [`ESPECTRE_COMMAND_ID_MAX_LENGTH`](#namespaceespectre_1aa9bcecab1d67487af0b736b8637b6138); Direct uses the canonical limit.

 

<a id="sdk_integration"></a>

## Integration details

 

This guide covers the lifecycle, ownership, and compatibility contracts for the SDK sources identified by this reference.

  

Start with the [SDK README](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/SDK.md>) for installation and a minimal application.

 

<a id="sdk_integration_1integration_logging"></a>

### Logging



All SDK facades expose the portable logging contract in [`core/espectre_log.h`](#espectre__log_8h). ESPectre does not install a sink or fall back to `stdio`, so integrations that do not need logs have no logger dependency and do not evaluate filtered log arguments. To receive shared logs, register a complete `LogSink` before runtime setup:



```cpp
espectre::LogSink sink{
    product_context,
    &product_log_enabled,
    &product_log_write,
};
if (!espectre::set_log_sink(sink)) {
  return false;
}
```



The `enabled` callback decides whether a level and tag should be formatted. The `write` callback receives the level, tag, source line, format string, and a `va_list` that remains valid only for that call. ESPectre copies the callback value but does not own its context. Keep the context alive until `clear_log_sink()`, and register, replace, or clear the sink only while no runtime is active. Callbacks may arrive from the runtime owner task, ESP-IDF service tasks, or CSI capture paths, so they must be thread-safe, bounded, non-blocking, and must not call the ESPectre logger recursively.



For ESP-IDF Log v2, your sink can pass the callback's `va_list` to `esp_log_va`. ESP-IDF adds the standard level, timestamp, tag, and line ending. The included example shows how to register this adapter; declare the `log` dependency in your application component.

 

<a id="sdk_integration_1integration_supported_hardware"></a>

### Supported hardware



The targets listed in [Requirements](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/SDK.md#requirements>) use standard single-antenna Wi-Fi CSI with AGC active and 20 MHz bandwidth. No extra sensors or radio hardware are required.



Set `RuntimeConfig::wifi_band_policy` to choose `BAND_2G`, `BAND_5G`, or `AUTO`. A directly constructed `RuntimeConfig` defaults to `BAND_2G` on every target. `make_runtime_sensing_config_from_kconfig()` reads the selected band from Kconfig, whose default is `AUTO` on ESP32-C5 and `BAND_2G` on the other supported targets. The runtime applies the selected policy and pins 20 MHz bandwidth on the active band or bands. Unsupported policies fail setup instead of falling back silently, and packets outside the selected capture profile are dropped and counted.



Set `RuntimeConfig::csi_capture_profile` before setup to choose `CsiCapturePolicy::AUTO`, `LLTF`, or `HT_VHT`. `AUTO` uses LLTF20 for internal `wifi_raw`, VHT20 on a supported 5 GHz link, and HT20 otherwise, including on ESP32 and ESP32-S2. `LLTF` always selects LLTF20; `HT_VHT` selects VHT20 on a supported 5 GHz link and HT20 otherwise. All three policies work with automatic band selection on ESP32-C5. `wifi_raw` requires `AUTO` or `LLTF`. There is no runtime profile setter or persisted profile override. The canonical `device` resource reports the effective profile as the read-only `csi_profile`. [CSI.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/CSI.md#capture-profiles>) describes capture behavior and normalization.

 

<a id="sdk_integration_1integration_runtime_contract"></a>

### Runtime contract

 

<a id="sdk_integration_1integration_threading"></a>

### Threading



The control surface is single-owner. Internal bounded mailboxes protect callback-to-loop handoff, but they do not make control calls thread-safe.



- Run `setup()`, `loop()`, and `shutdown()` on one task.

- Every `IRuntimeListener` callback is delivered on the caller's task: from `loop()` for sensing events, or inline on the task that invoked a control method. Work raised in the Wi-Fi CSI callback is deferred through an internal mailbox first, so no listener callback runs in interrupt or Wi-Fi driver context.

- Keep callbacks bounded and non-blocking. A slow callback delays the next `loop()` iteration; sufficiently long work can fill the bounded CSI mailbox and drop incoming frames. Queue network publication, NVS writes, and other potentially blocking work for a separate task.

- Call `set_*_runtime()` only from the owner task. Queue commands received by network callbacks and apply them from that task's loop.

- Raw CSI packet callbacks are the deliberate exception: they run synchronously in the Wi-Fi CSI capture context. Keep them bounded, non-blocking, and allocation-free, and copy accepted samples into a preallocated bounded queue when another task must process them. Returning false reports a caller-owned drop or backpressure event; it does not stop collection.



Stopping raw collection synchronizes with any packet callback already in progress before releasing its context. The caller can reclaim that context after `stop_raw_collection()` succeeds. Raw callbacks must follow the owner-task rule for runtime controls; they must not stop collection themselves.

 

<a id="sdk_integration_1integration_advanced_task_scheduling"></a>

### Advanced task scheduling



Full-runtime ESP-IDF integrations expose ESPectre-owned FreeRTOS priorities under the `Advanced task scheduling` menu. These settings are compile-time policies, not runtime controls. Values range from `1` to `10`; higher-priority tasks preempt lower-priority work. Change them only with workload-specific validation because an unsuitable priority can starve sensing, Direct delivery, managed traffic, or system networking. ESP-IDF continues to own the internal Wi-Fi and lwIP task priorities.



The shared runtime defines these priorities:



| Kconfig option | Default | Owner |
| --- | --- | --- |
| [`CONFIG_ESPECTRE_DIRECT_HTTPD_TASK_PRIORITY`](#task__scheduling__config_8h_1a1c07ae2423b6566d454316bfd9a8dcfa) | `1` | Direct HTTP server |
| [`CONFIG_ESPECTRE_DIRECT_WORKER_TASK_PRIORITY`](#task__scheduling__config_8h_1ab21ce3fdcc4837c2a0aecb8b3b58ca04) | `2` | Direct control responses and SSE delivery |
| [`CONFIG_ESPECTRE_RAW_WORKER_TASK_PRIORITY`](#task__scheduling__config_8h_1ac541f938b4a9aee9eb3e7edc08296acd) | `3` | Raw CSI HTTP delivery |
| [`CONFIG_ESPECTRE_TRAFFIC_TASK_PRIORITY`](#task__scheduling__config_8h_1a89bc52af94882fc610139f6ac25a80c8) | `1` | Managed PING or DNS traffic |



Your application owns the task that calls `RuntimeFrontendController::loop()`. Select its priority as part of your scheduling policy; the SDK's task settings do not set that priority.



The Direct HTTP server defaults to priority `1` on every target. Custom integrations can override it after workload-specific validation. Existing `sdkconfig` files retain explicitly saved priorities; set [`CONFIG_ESPECTRE_DIRECT_HTTPD_TASK_PRIORITY=1`](#task__scheduling__config_8h_1a1c07ae2423b6566d454316bfd9a8dcfa) to adopt the shared default in those builds.



See [ALGORITHMS.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/ALGORITHMS.md#motion-hit-filtering>) for how evaluation cadence and hit filtering determine publish delay.

 

<a id="sdk_integration_1integration_raw_csi_storage"></a>

### Raw CSI storage



`prepare_ht20_detector_input` prepares a private centered buffer after the raw branch: it handles both LLTF edge tones and hardware-invalid classic +1, using explicit source metadata. The existing `impute_ht20_lltf_detector_bins` helper remains a compatible LLTF-only wrapper. See [CSI.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/CSI.md#detector-input-and-raw-collection>) for the shared preparation policy.



The built-in capture pipeline normalizes LLTF, HT, and VHT samples to `HT20_CSI_LEN`: 128 bytes containing 64 complex subcarriers. `RawCsiPacketView` exposes this normalized view. Size capture queues for the normalized payload. `RAW_CSI_MAX_PAYLOAD_BYTES` defines the separate 512-byte payload limit for stored and transmitted records.



`EspIdfDirectHttpService` uses a 16-slot raw queue with 128 payload bytes per slot and sends records in batches of up to four. It allocates raw buffers when a session starts and releases them when it stops.



The queue can overflow during a stalled send, regardless of each slot's payload capacity. Inspect `raw_csi.raw_drop_total` separately from capture-quality rejections; see [CSI.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/CSI.md#capture-quality>).

 

<a id="sdk_integration_1integration_lifecycle"></a>

### Lifecycle



`set_config()` -&gt; `setup(listener)` -&gt; `loop()` repeatedly -&gt; `shutdown()`. Create the default station interface and ESP event loop before `setup()`. Prefer setup before association so the CSI radio policy is applied at `WIFI_EVENT_STA_START`; setup after association is also supported and restores the station's current IPv4 state. The controller is reusable after `shutdown()`: the configuration survives and `set_config()` becomes effective again. `setup()` is idempotent, and a failed `setup()` leaves the controller un-setup so you can fix the config and retry.



Register an optional `LogSink` before `setup()`. Do not replace or clear it until every runtime and callback source using it has shut down.



High Accuracy preserves the configured or live threshold when sensing starts, Wi-Fi reconnects, or raw collection ends. Explicit recalibration and switching detectors restore the detector's default threshold. Lightweight continues to derive its threshold through startup calibration.

 

<a id="sdk_integration_1integration_errors"></a>

### Errors



The control surface reports failure through `bool` returns and never throws. Runtime-backend, temporal-sampler, and detector storage allocations are non-throwing; an allocation failure makes `setup()` return false and reports the fault synchronously to the listener. A `false` means the call was rejected or could not be applied, and the runtime is unchanged. There are four reasons a control call returns false:



1. The value is outside the range published in [`runtime_sensing_schema.h`](#runtime__sensing__schema_8h).

2. The active runtime does not advertise the matching capability.

3. The backend refused the change.

4. `setup()` could not allocate the runtime's bounded working storage.



Asynchronous failures arrive instead through `IRuntimeListener::on_runtime_fault()`. Calibration outcome is reported by `on_calibration_finished(snapshot, success)`; a `false` there is not fatal, the runtime keeps sensing with the configured threshold.

 

<a id="sdk_integration_1integration_capabilities"></a>

### Capabilities



`RuntimeCapabilities` defaults every flag to false, so a runtime declares what it offers rather than inheriting a permissive default. Read `controller.capabilities()` after `setup()` and expose only what it advertises. The controller already refuses capability-gated calls; this check keeps unsupported controls out of the product interface.

 

<a id="sdk_integration_1integration_diagnostics"></a>

### Diagnostics



The runtime exposes cumulative capture and link counters separately from the sensing snapshot. `RuntimeFrontendController::diagnostics()` reads the totals, and `diagnostics_sample()` returns the runtime's shared one-second sample. For a custom sampling interval, `RuntimeDiagnosticsSampler` turns two reads into rates without requiring a separate timer:



```cpp
// once, at application startup
sampler_.reset(runtime_.diagnostics(), now_ms);

// whenever the existing periodic sensing callback runs
latest_ = sampler_.sample(runtime_.diagnostics(), now_ms);
```



`RuntimeDiagnosticsSample::csi_admitted_pps` is the detector input rate after temporal admission. `csi_accepted_pps` is the identity-accepted supply. Compare admitted PPS with `RuntimeConfig::csi_target_pps` together with `csi_occupancy_ratio`, callback-queue overflow, same-slot excess, missing-slot, stale, and out-of-order rates when a deployment underperforms. `RuntimeDiagnosticsSnapshot` exposes the cumulative callback-queue drop counter and its current occupancy and capacity; `RuntimeDiagnosticsSample::csi_pending_frame_drop_pps` derives the overflow rate. Occupancy is diagnostic telemetry and does not change the device send rate. [API.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/API.md#diagnostics>) owns the corresponding wire field names, units, and optionality.



SDK transport adapters should pass parsed requests through `FrontendCommandEngine` and preserve the canonical distinction between requester-scoped query results and state changes published to active transports. [API.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/API.md#contract-principles>) owns the message fields and cross-transport semantics; [ARCHITECTURE.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/ARCHITECTURE.md#shared-protocol-and-transport-services>) owns command-engine and adapter placement.



The shipped ESP-IDF runtime always collects these counters and bounded performance windows. `RuntimeDiagnosticsSnapshot` also reports heap, CPU frequency, loop load and timing, detector timing, CSI provenance classification, and provenance rejection. [API.md](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/API.md#diagnostics>) defines their transport representation; the sampling contract follows below.

 

<a id="sdk_integration_1integration_performance_sampling"></a>

### Performance sampling



C++ runtime implementations use `RuntimePerformanceDiagnostics` to aggregate runtime-loop load and timing plus sampled detector evaluation timing in bounded 10-second windows. `RuntimeDiagnosticsSnapshot` combines the latest complete window with current, minimum, and largest-block heap values and configured CPU frequency. The runtime also derives a one-second `RuntimeDiagnosticsSample` from cumulative counters. Read this shared sample across your transport adapters to keep their observation windows consistent. Collection is unconditional and does not emit a periodic debug log.



`runtime_load_percent` measures wall time spent inside the ESPectre runtime loop, not whole-system CPU utilization. Wi-Fi callbacks only normalize and enqueue CSI; detector processing, inference, state transitions, and listener callback delivery run in the owning loop task. Transport work on private tasks is outside this measurement. Detector timing is sampled on an evaluation tick after approximately 1,000 detector packets. For High Accuracy, it covers ML feature extraction, inference, and state update.

 

<a id="sdk_integration_1integration_transport_adapters"></a>

### Transport adapters



`RuntimeDirectHttpBridgeConfig::loop_time_ms_getter` optionally supplies the latest complete application loop duration in milliseconds. Measure the loop body that calls the runtime and processes application events; exclude work on other tasks and time between loop calls. If you omit the callback, selecting `loop_time_ms` returns `null`. This measurement is independent of the runtime performance-window average exposed as `loop_avg_us`.



The shared Direct service owns HTTP request lifetime, SSE delivery, deferred responses, and the owner-bound raw CSI session used by ESPectre. The ESP-IDF implementation assigns an opaque monotonically increasing token to each live connection, removes inbound work by token rather than file descriptor, and completes deferred work only while that token still identifies the originating client. The default interface implementation reports deferred delivery as unsupported, preserving source compatibility for transports that implement only synchronous requests.

 

<a id="sdk_integration_1integration_protocol_extensions"></a>

### Protocol extensions



All command parameters use `EspectreCommandValidator`: the parser checks JSON syntax and request structure, then invokes the callback registered on the SDK or application route. The callback receives decoded `JsonObjectField` values, validates parameters, and fills the command before dispatch. It must not change device state. For extension commands, `extension_parameters` initially contains the original request, including the MQTT envelope; the validator may replace it with normalized JSON built from the decoded fields. The SDK validator checks parameter types and ranges, including thresholds in `0–1` and motion hit counts in `1–20`.



`FrontendCommandEngine::execute()` and application extension handlers require a successfully parsed command. They check capabilities and operational state without repeating parameter validation. Direct runtime and service APIs retain their own argument checks because integrators can call them without a protocol parser.



`EspectreCapabilityProfile::extension` accepts an optional `EspectreProtocolExtension` supplied by your application. Each route declares its HTTP method and path, resource or operation name, command name, asynchronous behavior, MQTT availability, raw-collection policy, and parameter validator. The extension also lists its event names. `validate_protocol_extension()` rejects invalid descriptors and collisions with SDK routes, command names, resources, or events.



Use the same immutable catalog for capability output, `DirectHttpServiceConfig::protocol_extension`, `direct_http_request_to_command()`, and `parse_espectre_command()`. Keep it alive while the adapters use it. Direct and MQTT then validate parameters through the same callback, and an unregistered extension command is rejected. Your application enforces each route's MQTT availability, implements its commands, and publishes extension events through the normal transports. Advertise only extensions your application has enabled.



Your application owns firmware updates. You can use protocol extensions to expose its update commands while keeping the update mechanism and release policy in your application.



`RuntimeFrontendController::quiesce()` is a generic suspension operation: it disables telemetry and sensing services and stops active raw collection while retaining the configured backend. The caller restores its desired service and telemetry gates when resuming. It is useful before a firmware update or another temporary activity that needs CSI and sensing traffic to stop.

 

<a id="sdk_integration_1integration_versioning"></a>

### Versioning



Supply your application version explicitly through `EspectreDeviceInfo::firmware_version` and discovery or provisioning configuration. The SDK does not read the ESP-IDF application descriptor to determine it.



[`ESPECTRE_SDK_VERSION_STRING`](#espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74) identifies the SDK sources you compiled against. Use the component-wise [`ESPECTRE_SDK_VERSION_AT_LEAST(major, minor, patch)`](#espectre__sdk__version_8h_1a84f438434c7a7b020e175e84ae3ca6e8) to guard code that needs a given release. [`ESPECTRE_SDK_VERSION_NUMBER`](#espectre__sdk__version_8h_1addabd247bcb8243d35a37657c029571b) retains the historical `MMmmpp` packing for compatibility and compact telemetry, but it is not an ordering contract because Semantic Versioning components are not limited to two digits.



ESPectre uses Semantic Versioning for the published C++ source API:



- Patch releases preserve source compatibility and documented lifecycle, validation, ownership, threading, capability, and error semantics. Detector coefficients and generated model weights may change when validation gates demonstrate a compatible quality fix; exact floating-point telemetry is not a compatibility guarantee.

- Minor releases may append fields, add callbacks with default implementations, and add types, functions, or overloads. Existing calls keep their meaning, closed enums do not gain values, and removals require a prior deprecation in a released minor version.

- Major releases may remove deprecated APIs or otherwise break source compatibility, with migration notes in `CHANGELOG.md`.

- Prerelease and rolling `preview` or `develop` bundles may change before the corresponding final release. The compatibility promise begins at the final numeric release.



The SDK is distributed and consumed as source. It does not promise a stable binary ABI: rebuild the SDK and integration together with the same C++ standard library and ESP-IDF toolchain. Construct public configuration and snapshot structs with their defaults, then assign named fields as shown in this guide; positional aggregate initialization is outside the compatibility contract so new fields can be appended safely.



Everything reachable from [`espectre_sdk.h`](#espectre__sdk_8h) belongs to the stable runtime surface. The public methods and configuration types exposed by [`espectre_services_sdk.h`](#espectre__services__sdk_8h) and [`espectre_mqtt_sdk.h`](#espectre__mqtt__sdk_8h) follow the same source-compatibility rules for optional ESP-IDF services. [`espectre_core_sdk.h`](#espectre__core__sdk_8h) is a separate opt-in for custom capture pipelines. Its detector classes and documented public methods follow the same rules. Feature trackers, generated weights, and headers included only as implementation dependencies are not independent extension points.



The SDK reads its identity only from [`runtime/espectre_sdk_version.h`](#espectre__sdk__version_8h) and explicit compiler definitions. It does not inspect Git, source refs, environment variables, or the application version. Published SDK bundles stamp the release identity into that header and `idf_component.yml`; the CI packaging tools determine the identity before producing the bundle.



Integrators can stamp the same header or override all four macros together: [`ESPECTRE_SDK_VERSION_STRING`](#espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74), [`ESPECTRE_SDK_VERSION_MAJOR`](#espectre__sdk__version_8h_1a1c56ebb77dae087ea795df71afe1b36a), [`ESPECTRE_SDK_VERSION_MINOR`](#espectre__sdk__version_8h_1ab49f9a44dcd3be82d3b3e742d9334c23), and [`ESPECTRE_SDK_VERSION_PATCH`](#espectre__sdk__version_8h_1a74f3ae0b42f726bf3302abae42655339). A complete compiler override takes precedence over the packaged values. The string and numeric components must describe the same SDK release, and definitions must be consistent across the SDK and its consumers.



Without a complete identity, the SDK uses `"0.0.0"` and zero for all numeric version components. Incomplete overrides also fall back to these values rather than mixing metadata from different sources or failing compilation. `espectre_sdk_version()` always returns a non-null string; `"0.0.0"` means the SDK version is unknown, and version guards for newer releases evaluate to false. A source checkout without stamped metadata therefore reports `"0.0.0"`, even if it has Git tags.



The SDK manifest exposes the packaged identity once as `version`; `release_tag` names the GitHub release that carries the assets and may differ for rolling channels. The generated API index uses `sdk_version` to identify the source revision used to build that reference. Official release tooling still requires and validates the published version. Rolling GitHub tags remain `snapshot` for `preview` and `snapshot-dev` for `develop`. SDK identity is separate from the application version supplied by the integrator and `ESPECTRE_PROTOCOL_VERSION`, which versions the wire format.

 

<a id="sdk_integration_1integration_advanced_integrations"></a>

### Advanced integrations



The core-only path and source-list builds let an application supply more of the capture and build infrastructure. The following sections distinguish component-relative paths from repository and bundle commands.

 

<a id="sdk_integration_1integration_core_only"></a>

### Core-only



If your firmware already owns Wi-Fi and CSI capture, include [`espectre_core_sdk.h`](#espectre__core__sdk_8h) and consume the detectors directly. The `core` detectors accept normalized CSI payloads and expose motion state, movement metric, and threshold control. The same facade exposes `TemporalCsiSampler`, which applies the production fixed-grid admission before `process_packet()`.



Detector and sampler working buffers use non-throwing allocation. Check `detector.is_valid()` after construction and the result of `sampler.configure(...)` before starting a custom pipeline; a false result means the requested bounded storage was unavailable. These objects are movable and intentionally non-copyable because their buffers own live temporal state.



The sampler tracks timing and slots; your integration stores the selected CSI payload. Handle each input in this order:



1. Call `admit()` before replacing the stored payload.

2. If `admit()` returns `true`, consume the stored payload: clear detector history when `reset_required()` is true, call `advance_missing_slots(missing_slots_before())`, and then call `process_packet()`.

3. If `gap_reset_required()` is true, clear detector history again before admitting post-gap data.

4. If `selected_current()` is true, replace the stored payload with the current normalized CSI.



At the end of a finite stream, call `flush()` and consume the stored payload if it returns `true`.



After each `update_state()`, re-read `get_threshold()`: Lightweight can lower it without a setter call, and the core-only path has no `on_threshold_changed()` hook. The sampler owns admission only; use `runtime/esp_idf/csi_pipeline.cpp` as the reference for CSI normalization, evaluation cadence, and hit filtering before committing to custom wiring.



A core-only integration that captures LLTF owns the same two-view boundary. Normalize the payload into the centered HT20 convention, call `zero_ht20_lltf_missing_bins()` on the raw view, copy that payload into the detector buffer, and call `impute_ht20_lltf_detector_bins()` only on the detector copy.

 

<a id="sdk_integration_1integration_build_integration"></a>

### Build integration



Component Manager configures the registered component automatically. The following alternatives apply when you vendor SDK sources or maintain your own CMake target. Set the SDK root to the directory containing `espectre_sources.cmake`: the root of the registry archive, or `src/cpp/` in a GitHub/web bundle.



- **Core-only CMake**: include `espectre_sources.cmake` from the SDK root, compile `ESPECTRE_CORE_SOURCES`, and add `ESPECTRE_SHARED_INCLUDE_DIRS`. No ESP-IDF runtime sources are required.

- **Full-runtime CMake / ESP-IDF**: compile `ESPECTRE_CORE_SOURCES` and `ESPECTRE_RUNTIME_ESP_IDF_SOURCES`, then add `ESPECTRE_RUNTIME_FRONTEND_SUPPORT_SOURCES` or the per-capability Direct HTTP, MQTT, and provisioning lists only when the integration uses them. Add `ESPECTRE_SHARED_INCLUDE_DIRS` and the dependencies listed under [Optional capability groups](<https://github.com/francescopace/espectre/blob/a75f4d16f537acf39dce6899021abde401b02813/docs/SDK.md#optional-capability-groups>).

- **Vendored ESP-IDF component**: copy the SDK root to your project's `components/espectre/` directory and add [`espectre`](#namespaceespectre) to your own component's `REQUIRES`. The sensing runtime is always built; the optional groups are opt-in under the "ESPectre SDK" menuconfig menu.

- **Toolchain**: C++17, ESP-IDF `>=5.5.5,<5.6.0` for the `runtime/esp_idf` services. Repository builds use ESP-IDF `5.5.5`.



Source-list integrations and vendored ESP-IDF components use the version header directly; no version resolution step is required. For a GitHub/web SDK bundle extracted into `espectre/`, a complete core-only target is:



```cpp
set(ESPECTRE_CPP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/espectre/src/cpp")
include("${ESPECTRE_CPP_ROOT}/espectre_sources.cmake")
add_library(espectre_core STATIC ${ESPECTRE_CORE_SOURCES})
target_compile_features(espectre_core PUBLIC cxx_std_17)
target_include_directories(espectre_core PUBLIC ${ESPECTRE_SHARED_INCLUDE_DIRS})
```



Link the application target to `espectre_core` to inherit the includes and C++ standard. Adjust `ESPECTRE_CPP_ROOT` to the SDK's location. If overriding the packaged SDK identity, apply all four version macros with `target_compile_definitions(espectre_core PUBLIC ...)` so consumers inherit them. The same approach works for a full-runtime source-list target.



The shared component does not require ESP-IDF's `log` component. A product that registers an `esp_log` adapter declares that dependency in its application component.



`ESPECTRE_SHARED_INCLUDE_DIRS` puts the SDK root on the include path, so both the flat form ([`#include "runtime_interface.h"`](#runtime__interface_8h)) and the layer-prefixed form ([`#include "runtime/runtime_interface.h"`](#runtime__interface_8h)) work. Prefer the prefixed form: the shared tree contains generic basenames such as `utils.h` and `filters.h`, and the prefix keeps them from colliding with headers of your own.

 

<a id="sdk_integration_1integration_published_sdk_channels"></a>

### Published SDK channels



The GitHub/web SDK bundles provide source archives for vendoring and evaluation. They use the repository-style layout below, separately from the registry component, and follow the firmware release channels:



| Channel | Source | Intended use |
| --- | --- | --- |
| `release` | latest tagged semver GitHub Release and `https://espectre.dev/artifacts/sdk/release/` | Final numeric versions are production candidates; prerelease tags are published explicitly as evaluation builds |
| `preview` | rolling `snapshot` GitHub prerelease and `https://espectre.dev/artifacts/sdk/preview/` | Validate `main` before the next release |
| `develop` | rolling `snapshot-dev` GitHub prerelease and `https://espectre.dev/artifacts/sdk/develop/` | Pre-main validation from `develop` |



Rolling releases publish `sdk-manifest-preview.json` and `sdk-manifest-develop.json`; the manifest filename follows the channel, while `release_tag` retains the GitHub tag shown above. Tagged releases publish `sdk-manifest-<release-tag>.json`.



Each GitHub/web SDK bundle includes:



- `docs/SDK.md`

- [`src/cpp/espectre_sdk.h`](#espectre__sdk_8h)

- [`src/cpp/espectre_core_sdk.h`](#espectre__core__sdk_8h)

- [`src/cpp/espectre_services_sdk.h`](#espectre__services__sdk_8h)

- [`src/cpp/espectre_mqtt_sdk.h`](#espectre__mqtt__sdk_8h)

- `src/cpp/core/`

- `src/cpp/runtime/`

- `src/cpp/runtime/esp_idf/espectre_config/`

- `src/cpp/espectre_sources.cmake`

- `src/cpp/CMakeLists.txt`

- `src/cpp/idf_component.yml`

- `src/cpp/Kconfig.projbuild`

- `src/cpp/Doxyfile`

- `src/cpp/sdk_integration.dox`

- generated `src/cpp/core/ml_weights.h`

- `LICENSE`, `LICENSING.md`, and `THIRD_PARTY_NOTICES.md`



The published bundle is a versioned C++ source SDK with stamped packaging metadata, ready to vendor or unpack into your firmware tree. ESPectre is compiled together with the product firmware; the bundle does not include chip-specific precompiled libraries or promise binary ABI compatibility. In the bundled copy of this guide, repository-relative links point to GitHub URLs pinned to the commit or release tag used for that package. The `.tar.gz` and `.zip` archives are generated deterministically from the source commit timestamp, and the SDK manifest records a SHA-256 digest for each archive so consumers can verify downloaded bytes.

 

<a id="namespaceespectre"></a>

## espectre

  [`espectre::BaseDetector`](#classespectre_1_1_base_detector)

[`espectre::CsiTrafficService`](#classespectre_1_1_csi_traffic_service)

[`espectre::CsiTrafficServiceConfig`](#structespectre_1_1_csi_traffic_service_config)

[`espectre::DeviceConfigCommandResult`](#structespectre_1_1_device_config_command_result)

[`espectre::DirectHttpServiceConfig`](#structespectre_1_1_direct_http_service_config)

[`espectre::DirectHttpServiceDiagnostics`](#structespectre_1_1_direct_http_service_diagnostics)

[`espectre::DirectRequest`](#structespectre_1_1_direct_request)

[`espectre::DirectWifiSnapshot`](#structespectre_1_1_direct_wifi_snapshot)

[`espectre::EspectreApiEventDescriptor`](#structespectre_1_1_espectre_api_event_descriptor)

[`espectre::EspectreApiRoute`](#structespectre_1_1_espectre_api_route)

[`espectre::EspectreCapabilityProfile`](#structespectre_1_1_espectre_capability_profile)

[`espectre::EspectreCommand`](#structespectre_1_1_espectre_command)

[`espectre::EspectreDeviceConfig`](#structespectre_1_1_espectre_device_config)

[`espectre::EspectreDeviceInfo`](#structespectre_1_1_espectre_device_info)

[`espectre::EspectreExtensionRoute`](#structespectre_1_1_espectre_extension_route)

[`espectre::EspectreNetworkInfo`](#structespectre_1_1_espectre_network_info)

[`espectre::EspectreProtocolExtension`](#structespectre_1_1_espectre_protocol_extension)

[`espectre::EspIdfDirectHttpService`](#classespectre_1_1_esp_idf_direct_http_service)

[`espectre::EspIdfMqttTransport`](#classespectre_1_1_esp_idf_mqtt_transport)

[`espectre::EspIdfPeerDiscoveryService`](#classespectre_1_1_esp_idf_peer_discovery_service)

[`espectre::FrontendCommandContext`](#structespectre_1_1_frontend_command_context)

[`espectre::FrontendCommandEngine`](#classespectre_1_1_frontend_command_engine)

[`espectre::FrontendCommandResult`](#structespectre_1_1_frontend_command_result)

[`espectre::FrontendDeviceConfigDefaults`](#structespectre_1_1_frontend_device_config_defaults)

[`espectre::FrontendHaDiagnosticSensor`](#structespectre_1_1_frontend_ha_diagnostic_sensor)

[`espectre::FrontendHaDiscoveryMessage`](#structespectre_1_1_frontend_ha_discovery_message)

[`espectre::FrontendHaMqttSettings`](#structespectre_1_1_frontend_ha_mqtt_settings)

[`espectre::FrontendWifiStationOptions`](#structespectre_1_1_frontend_wifi_station_options)

[`espectre::HighAccuracyDetector`](#classespectre_1_1_high_accuracy_detector)

[`espectre::ICsiTrafficGenerator`](#classespectre_1_1_i_csi_traffic_generator)

[`espectre::ICsiTrafficIngress`](#classespectre_1_1_i_csi_traffic_ingress)

[`espectre::IDirectHttpService`](#classespectre_1_1_i_direct_http_service)

[`espectre::IEspectreRuntime`](#classespectre_1_1_i_espectre_runtime)

[`espectre::IMqttTransport`](#classespectre_1_1_i_mqtt_transport)

[`espectre::IPeerDiscoveryService`](#classespectre_1_1_i_peer_discovery_service)

[`espectre::IRuntimeListener`](#classespectre_1_1_i_runtime_listener)

[`espectre::IUdpDatagramSocket`](#classespectre_1_1_i_udp_datagram_socket)

[`espectre::JsonObjectField`](#structespectre_1_1_json_object_field)

[`espectre::LightweightDetector`](#classespectre_1_1_lightweight_detector)

[`espectre::LogSink`](#structespectre_1_1_log_sink)

[`espectre::MdnsBootstrapResponder`](#classespectre_1_1_mdns_bootstrap_responder)

[`espectre::MdnsDiscoveryService`](#classespectre_1_1_mdns_discovery_service)

[`espectre::MdnsDiscoveryServiceConfig`](#structespectre_1_1_mdns_discovery_service_config)

[`espectre::MqttPayloadAssembler`](#classespectre_1_1_mqtt_payload_assembler)

[`espectre::MqttTransportDiagnostics`](#structespectre_1_1_mqtt_transport_diagnostics)

[`espectre::PeerDiscoveryCandidate`](#structespectre_1_1_peer_discovery_candidate)

[`espectre::PeerDiscoverySnapshot`](#structespectre_1_1_peer_discovery_snapshot)

[`espectre::PendingEvent`](#classespectre_1_1_pending_event)

[`espectre::PendingQueue`](#classespectre_1_1_pending_queue)

[`espectre::RawCsiHttpFramePrefix`](#structespectre_1_1_raw_csi_http_frame_prefix)

[`espectre::RawCsiPacketView`](#structespectre_1_1_raw_csi_packet_view)

[`espectre::RawCsiRecordHeaderV7`](#structespectre_1_1_raw_csi_record_header_v7)

[`espectre::RawCsiRecordHeaderV8`](#structespectre_1_1_raw_csi_record_header_v8)

[`espectre::RawCsiSessionConfig`](#structespectre_1_1_raw_csi_session_config)

[`espectre::RawCsiSessionController`](#classespectre_1_1_raw_csi_session_controller)

[`espectre::RawCsiSessionDiagnostics`](#structespectre_1_1_raw_csi_session_diagnostics)

[`espectre::RuntimeCapabilities`](#structespectre_1_1_runtime_capabilities)

[`espectre::RuntimeConfig`](#structespectre_1_1_runtime_config)

[`espectre::RuntimeDiagnosticsSample`](#structespectre_1_1_runtime_diagnostics_sample)

[`espectre::RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler)

[`espectre::RuntimeDiagnosticsSnapshot`](#structespectre_1_1_runtime_diagnostics_snapshot)

[`espectre::RuntimeDirectHttpBridge`](#classespectre_1_1_runtime_direct_http_bridge)

[`espectre::RuntimeDirectHttpBridgeConfig`](#structespectre_1_1_runtime_direct_http_bridge_config)

[`espectre::RuntimeEventMailbox`](#classespectre_1_1_runtime_event_mailbox)

[`espectre::RuntimeFrontendController`](#classespectre_1_1_runtime_frontend_controller)

[`espectre::RuntimeSnapshot`](#structespectre_1_1_runtime_snapshot)

[`espectre::StandaloneWifiAccessPoint`](#structespectre_1_1_standalone_wifi_access_point)

[`espectre::StandaloneWifiConfig`](#structespectre_1_1_standalone_wifi_config)

[`espectre::StandaloneWifiInfo`](#structespectre_1_1_standalone_wifi_info)

[`espectre::StandaloneWifiService`](#classespectre_1_1_standalone_wifi_service)

[`espectre::StoredWifiConfig`](#structespectre_1_1_stored_wifi_config)

[`espectre::TemporalCsiSampler`](#classespectre_1_1_temporal_csi_sampler)

[`espectre::TrafficGeneratorManager`](#classespectre_1_1_traffic_generator_manager)

[`espectre::UdpDatagramPeer`](#structespectre_1_1_udp_datagram_peer)

[`espectre::WifiBssidPinService`](#classespectre_1_1_wifi_bssid_pin_service)

[`espectre::WifiBssidPinServiceConfig`](#structespectre_1_1_wifi_bssid_pin_service_config)

[`espectre::WifiBssidPinStationState`](#structespectre_1_1_wifi_bssid_pin_station_state)

[`espectre::WiFiLifecycleManager`](#classespectre_1_1_wi_fi_lifecycle_manager)

[`espectre::WifiProvisioningDefaults`](#structespectre_1_1_wifi_provisioning_defaults)

[`espectre::WifiProvisioningService`](#classespectre_1_1_wifi_provisioning_service)

[`espectre::detail`](#namespaceespectre_1_1detail)

[`espectre::task_scheduling`](#namespaceespectre_1_1task__scheduling)



<a id="namespaceespectre_1ae9a5c52124fc67ad49536d43fd6d0077"></a>

### `format_espectre_device_id`


```cpp
std::string espectre::format_espectre_device_id(uint64_t device_id)
```

 

Format a device id in its canonical wire form.

   

<a id="namespaceespectre_1a56f23162b469f148e7bfeca818d5105b"></a>

### `parse_espectre_device_id`


```cpp
bool espectre::parse_espectre_device_id(const std::string &value, uint64_t *device_id)
```

 

Parse a device id from its wire form.

  

**Parameters**

- `value`: Formatted device id, as produced by [`format_espectre_device_id()`](#namespaceespectre_1ae9a5c52124fc67ad49536d43fd6d0077).
- `device_id`: Written only when parsing succeeds.

 

**Returns:** false on a malformed value, leaving the output untouched.

  

<a id="namespaceespectre_1adc03ef2a0c49d818c944747283819e1a"></a>

### `espectre_device_id_from_mac`


```cpp
uint64_t espectre::espectre_device_id_from_mac(const uint8_t *mac, size_t mac_len)
```

 

Pack the first six MAC bytes into the historical numeric representation.

  

**Deprecated:** 

Runtime firmware uses the cached, domain-separated SHA-256 pseudonym from [`derive_runtime_device_id()`](#namespaceespectre_1a34031a60d78bbb6306047b3540b4f905) instead.

  

<a id="namespaceespectre_1ae5c4f0a710fbd64b9efdda153e83b3b3"></a>

### `espectre_device_name`


```cpp
std::string espectre::espectre_device_name(uint64_t device_id, const char *chip=nullptr)
```

 

Conventional device name derived from the immutable device identifier.

   

<a id="namespaceespectre_1a975d496a575840d95675209e1294dda1"></a>

### `espectre_effective_device_id_u64`


```cpp
uint64_t espectre::espectre_effective_device_id_u64(const EspectreDeviceConfig &config)
```

 

The id actually in use.

  

Frontend startup replaces the zero sentinel.

  

<a id="namespaceespectre_1a7132956b729065dbed22f00e9edd8e7b"></a>

### `espectre_effective_device_id`


```cpp
std::string espectre::espectre_effective_device_id(const EspectreDeviceConfig &config)
```

 

[`espectre_effective_device_id_u64()`](#namespaceespectre_1a975d496a575840d95675209e1294dda1) in wire form.

   

<a id="namespaceespectre_1acaed5bdf8f0dd7e1592aa8c49fbc73be"></a>

### `espectre_effective_device_label`


```cpp
std::string espectre::espectre_effective_device_label(const EspectreDeviceConfig &config)
```

 

The configured label, or the effective device id when no label is set.

   

<a id="namespaceespectre_1aeaa6010650a78e01b8ad2c078335d102"></a>

### `normalize_protocol_device_info`


```cpp
EspectreDeviceInfo espectre::normalize_protocol_device_info(const EspectreDeviceInfo &info, const RuntimeSnapshot *snapshot, const char *default_frontend, const char *default_chip=nullptr)
```

 

Fill in the parts of a device info block the frontend did not set.

  

Takes the detector from `snapshot`, and `default_frontend` / `default_chip` where the caller left the field empty, so each frontend only states what is genuinely its own.

 

**Parameters**

- `info`: What the frontend knows about itself.
- `snapshot`: Source of the detector name. May be `nullptr` when no snapshot exists yet.
- `default_frontend`: Frontend name used when `info.frontend` is empty.
- `default_chip`: Chip name used when `info.chip` is empty.

 

**Returns:** A copy of `info` with the gaps filled.

  

<a id="namespaceespectre_1ac1edf42e0c351a6a291c91e0bf1ec7b0"></a>

### `clear_espectre_mqtt_config`


```cpp
void espectre::clear_espectre_mqtt_config(EspectreDeviceConfig *config)
```

 

Erase broker settings while preserving identity, for a config reset.

   

<a id="namespaceespectre_1a7d53b6c1f2382ba21a1bc8e3bd41d962"></a>

### `validate_espectre_mqtt_config`


```cpp
bool espectre::validate_espectre_mqtt_config(const EspectreDeviceConfig &config, std::string *error=nullptr)
```

 

Validate the complete MQTT endpoint in a device configuration.

  

The endpoint requires an exact `mqtt` or `mqtts` scheme, a DNS hostname, IPv4 address, or IPv6 address without URI framing, and a non-zero port.

 

**Parameters**

- `config`: Device configuration carrying the MQTT endpoint.
- `error`: Receives a human-readable reason on failure. May be `nullptr`.

 

**Returns:** `true` only when the complete endpoint is valid.

  

<a id="namespaceespectre_1abc400447710392b7e9d5cba40dbe685f"></a>

### `espectre_mqtt_configured`


```cpp
bool espectre::espectre_mqtt_configured(const EspectreDeviceConfig &config)
```

 

Return whether `config` contains a complete, valid MQTT endpoint.

   


<a id="namespaceespectre_1a32edcf9be1977beb72e27fd4900afc37"></a>

### `espectre_topic`


```cpp
std::string espectre::espectre_topic(const EspectreDeviceConfig &config, const char *suffix)
```

 

Build a full topic from this device's prefix and a trailing segment.

   

<a id="namespaceespectre_1af7d9b8dfa07f2d15f8ab478be3aafb48"></a>

### `espectre_health_payload`


```cpp
std::string espectre::espectre_health_payload(const EspectreDeviceConfig &config, bool online, uint32_t timestamp_ms)
```

 

Availability payload.

  

Publish it retained so late subscribers see it.

  

<a id="namespaceespectre_1aaf2c60d3cf259dfc145c5aa55b49162d"></a>

### `espectre_device_payload`


```cpp
std::string espectre::espectre_device_payload(const EspectreDeviceConfig &config, const EspectreDeviceInfo &info)
```

 

Stable device identity and build description.

  

Publish retained on connect.

  

<a id="namespaceespectre_1a2d5f998a0d1b9266434071e44192dee0"></a>

### `espectre_capabilities_payload`


```cpp
std::string espectre::espectre_capabilities_payload(const EspectreDeviceConfig &config, const EspectreDeviceInfo &info, const EspectreCapabilityProfile &capabilities)
```

 

Filtered command, event, feature, and configuration catalog.

   

<a id="namespaceespectre_1a10c3fe709e07f14529952203afcc3e8d"></a>

### `espectre_capabilities_payload`


```cpp
std::string espectre::espectre_capabilities_payload(const EspectreDeviceConfig &config, const EspectreDeviceInfo &info, bool supports_status=true, bool supports_config=false, bool supports_sensing_control=false, bool supports_wifi_bssid=false, bool supports_mqtt_config=false, bool supports_peer_discovery=false, bool supports_raw_csi=false, const EspectreProtocolExtension *extension=nullptr)
```

 

Compatibility overload for existing SDK consumers.

  

New code should pass an [`EspectreCapabilityProfile`](#structespectre_1_1_espectre_capability_profile) so readable sections and individual commands are represented independently.

  

<a id="namespaceespectre_1aec53df228c0e4a8235a57886f272fc16"></a>

### `espectre_motion_payload`


```cpp
std::string espectre::espectre_motion_payload(const EspectreDeviceConfig &config, const RuntimeSnapshot &snapshot, uint32_t timestamp_ms, uint32_t uptime_s, const char *frontend)
```

 

Current motion state and score.

  

The payload behind every detector evaluation.

  

<a id="namespaceespectre_1a6bc2369abcef6f55305c1f528ee32d2b"></a>

### `espectre_diagnostics_payload`


```cpp
std::string espectre::espectre_diagnostics_payload(const EspectreDeviceConfig &config, const RuntimeSnapshot &snapshot, uint32_t timestamp_ms, uint32_t uptime_s, float free_memory_kb, float loop_time_ms, const RuntimeDiagnosticsSample *diagnostics=nullptr)
```

 

Health counters plus optional rate and link diagnostics.

  

`diagnostics` carries CSI and link rates from [`RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler). Pass `nullptr` only for a frontend that does not expose extended diagnostics.

  

<a id="namespaceespectre_1a23723f52835cb183d122bbaf8c5348f7"></a>

### `espectre_command_result_payload`


```cpp
std::string espectre::espectre_command_result_payload(const EspectreDeviceConfig &config, const EspectreCommand &command, bool accepted, const char *code, const char *message, const std::string &data_json={})
```

 

Acknowledge a command, echoing its `command_id`.

  

Publish one for every command you parse, accepted or not; clients correlate on the id and otherwise cannot tell rejection from packet loss.

  

<a id="namespaceespectre_1ad3b52b52f70db1fa6a3a65c861702371"></a>

### `espectre_command_request_payload`


```cpp
std::string espectre::espectre_command_request_payload(const std::string &command_id, const std::string &command, const std::string &params_json="{}")
```

 

Build the canonical flat command request carried by MQTT and Direct HTTP.

   

<a id="namespaceespectre_1a7a2bb328d061562636f101a7201f5d72"></a>

### `espectre_fault_payload`


```cpp
std::string espectre::espectre_fault_payload(const EspectreDeviceConfig &config, const char *message, uint32_t timestamp_ms)
```

 

Runtime fault event shared by every transport.

   

<a id="namespaceespectre_1ab3c981ce263a1f565b33cdd705306a45"></a>

### `espectre_message_catalog_payload`


```cpp
std::string espectre::espectre_message_catalog_payload(const EspectreProtocolExtension *extension=nullptr)
```

 

Executable transport-neutral message samples used by the C++/Python parity gate.

   


<a id="namespaceespectre_1affd612c44046053715f0e4947c579959"></a>

### `parse_espectre_command`


```cpp
bool espectre::parse_espectre_command(const std::string &payload, EspectreCommand *command, std::string *error, const EspectreProtocolExtension *extension=nullptr)
```

 

Parse a JSON command payload from the MQTT command topic.

  

**Parameters**

- `payload`: Raw message body as received.
- `command`: Populated only on success. Check the `has_*` flags to see which fields the peer actually sent.
- `error`: Receives a human-readable reason on failure. May be `nullptr`.
- `extension`: Optional frontend routes and their parameter validators.

 

**Returns:** false on malformed input or an unknown command.

  

<a id="namespaceespectre_1a3719c5d411370f85344e700a2eb961a5"></a>

### `parse_espectre_command_request`


```cpp
bool espectre::parse_espectre_command_request(const std::string &command_id, const std::string &command_name, const std::string &params_json, EspectreCommand *command, std::string *error, const std::string &protocol_version=ESPECTRE_PROTOCOL_VERSION, const EspectreProtocolExtension *extension=nullptr)
```

 

Parse an already separated command name plus a JSON parameter object.

  

Frontend adapters use this after separating a canonical flat request into internal fields. Validation follows canonical envelope order: correlation identifier, protocol version, command name, and parameters.

  

<a id="namespaceespectre_1a688469ee24c9b9691d715dc273feaf95"></a>

### `parse_espectre_config_command`


```cpp
bool espectre::parse_espectre_config_command(const std::string &command, EspectreDeviceConfig *config, std::string *error)
```

 

Parse a legacy ASCII `SET_DEVICE_CONFIG:` command.

  

Carries one `key=value` pair, applied in place. A rejected command writes nothing.

 

**Parameters**

- `command`: Full command string, including the `SET_DEVICE_CONFIG:` prefix.
- `config`: Updated in place on success.
- `error`: Receives a human-readable reason on failure. May be `nullptr`.

  

<a id="namespaceespectre_1a89f2455d1366f9cca351588f426b9425"></a>

### `parse_espectre_mqtt_config_command`


```cpp
bool espectre::parse_espectre_mqtt_config_command(const std::string &command, EspectreDeviceConfig *config, std::string *error)
```

 

Parse a `SET_MQTT_CONFIG:` command, carrying the broker settings.

  

The complete command is parsed and validated before `config` is changed, so rejection leaves the previous value intact. `scheme`, `host`, and `port` are required; the rest keep their previous values.

  


<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22a"></a>

### `RawCsiChipType`


```cpp
enum class RawCsiChipType : uint8_t
```

   

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aa696b031073e74bf2cb98e5ef201d4aa3"></a>

`UNKNOWN = 0`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aa789c376b43dbba68180fd04da73286da"></a>

`ESP32 = 1`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aab9eeaf6a16ca49f37df57620aed91b62"></a>

`S2 = 2`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aa1cf733d786a614c74862934365c1b5ca"></a>

`RESERVED_LEGACY_S2 = S2`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aae2ab7c65b21ed8cc1c3b642b5e36429e"></a>

`S3 = 3`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aa3abe124ecc82bf2c2e22e6058f38c50c"></a>

`C3 = 4`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aafea813d4ddba3c46cf8b8e664b92cdaa"></a>

`C5 = 5`

  

<a id="namespaceespectre_1a83022e1a22fdb212c86c99fc85d8b22aa7e8b9f5cab4a8fe24fad9fe4b7452702"></a>

`C6 = 6`

  

<a id="namespaceespectre_1a967920764a50523f0ce8f7c5e36a3a21"></a>

### `RawCsiRecordFlags`


```cpp
enum RawCsiRecordFlags : uint8_t
```

   

<a id="namespaceespectre_1a967920764a50523f0ce8f7c5e36a3a21a8d36260ce1b4352270abab92bfd65e38"></a>

`RAW_CSI_FLAG_FIRST_WORD_INVALID = 1u << 0`

  

<a id="namespaceespectre_1a967920764a50523f0ce8f7c5e36a3a21a4e720bd9bc21639dc5557441624cef2a"></a>

`RAW_CSI_FLAG_WIFI_RX_TS_VALID = 1u << 1`

  

<a id="namespaceespectre_1a967920764a50523f0ce8f7c5e36a3a21ad3840b82f9a900c6c97204ff67f6b8be"></a>

`RAW_CSI_FLAG_WIFI_RX_START_TS_NS_VALID = 1u << 2`

  

<a id="namespaceespectre_1a967920764a50523f0ce8f7c5e36a3a21a0051718291384eb75885c9b62e79cfa2"></a>

`RAW_CSI_FLAG_FRESH = 1u << 3`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363"></a>

### `RawCsiPhyMode`


```cpp
enum class RawCsiPhyMode : uint8_t
```

   

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a696b031073e74bf2cb98e5ef201d4aa3"></a>

`UNKNOWN = 0`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a456d016bd133625e5036aa9a556f2730"></a>

`LEGACY = 1`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a90d64eeba8247d656ef6b4800ec0f52f"></a>

`HT = 2`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a2d425dd35e072d51beffedbbefe7b7d9"></a>

`VHT = 3`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a384604b568b86c1b44f899ad0bb52cde"></a>

`HE_SU = 4`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a03deb58782326a275810c5b0d35b125c"></a>

`HE_MU = 5`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363ad5a697bbf088741bb5857cc870674d51"></a>

`HE_ERSU = 6`

  

<a id="namespaceespectre_1a679285b0ae641ff6d1446f1a7cb6a363a803d1726aa04a7d2ced45ac2099bb57d"></a>

`HE_TB = 7`

  

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9e"></a>

### `RawCsiLtfType`


```cpp
enum class RawCsiLtfType : uint8_t
```

   

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9ea696b031073e74bf2cb98e5ef201d4aa3"></a>

`UNKNOWN = 0`

  

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9ea23995e76e6c517049199861bd20a5f7f"></a>

`LLTF = 1`

  

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9ea1d815e95673dac609a01bfb986c2cceb"></a>

`HT_LTF = 2`

  

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9ea7b3f0f06d9c6307397f670944b74eabd"></a>

`VHT_LTF = 3`

  

<a id="namespaceespectre_1a04fa1bf9323c3efd3ff9998892a32e9ea2115a1e7b50842efe5fd7f8ee5793795"></a>

`HE_LTF = 4`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97"></a>

### `RawCsiChannelWidth`


```cpp
enum class RawCsiChannelWidth : uint8_t
```

   

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97a696b031073e74bf2cb98e5ef201d4aa3"></a>

`UNKNOWN = 0`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97a6776ebfc3912b4527d387fd703a69587"></a>

`MHZ_20 = 1`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97a0fac4da3580d6b66a5c1dc27478b7290"></a>

`MHZ_40 = 2`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97a5d49cf11445a99bc8fed070ce53db290"></a>

`MHZ_80 = 3`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97adc07c66d483ad17443b20de9fa00d9f8"></a>

`MHZ_160 = 4`

  

<a id="namespaceespectre_1a74c31f33edc1dcd2760c4cf242d01c97a6a082d35c82fdef562036b955f5b2836"></a>

`MHZ_80_80 = 5`

  

<a id="namespaceespectre_1adb2211d7a11969b4ed8db08213d7b086"></a>

### `WifiBandPolicy`


```cpp
enum class WifiBandPolicy : uint8_t
```

 

Wi-Fi band selection requested by the embedding frontend.

   

<a id="namespaceespectre_1adb2211d7a11969b4ed8db08213d7b086ae5b0b1eaa95367f057b2c7cc12ec2301"></a>

`BAND_2G = 0`

 

Restrict association to 2.4 GHz.

  

This is the validated production default.

 

<a id="namespaceespectre_1adb2211d7a11969b4ed8db08213d7b086ac18a21d672f2013842acfe84a52dd1ff"></a>

`BAND_5G = 1`

 

Restrict association to 5 GHz.

  

Supported only by dual-band targets.

 

<a id="namespaceespectre_1adb2211d7a11969b4ed8db08213d7b086ae1f2d5134ed2543d38a0de9751cf75d9"></a>

`AUTO = 2`

 

Let a dual-band radio choose between 2.4 GHz and 5 GHz.

  

<a id="namespaceespectre_1aa28375cf8afd113582387290089d9d09"></a>

### `RuntimeOperationState`


```cpp
enum class RuntimeOperationState : uint8_t
```

   

<a id="namespaceespectre_1aa28375cf8afd113582387290089d9d09a9f53d28f082938342669ff6fa150947a"></a>

`SENSING = 0U`

  

<a id="namespaceespectre_1aa28375cf8afd113582387290089d9d09ad22e88ebf186a446048c76b8d21ca82d"></a>

`RAW_COLLECTION = 1U`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894b"></a>

### `RawCsiStopReason`


```cpp
enum class RawCsiStopReason : uint8_t
```

   

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba889d4358e2fdc68185c59ee7e3173f58"></a>

`REQUESTED = 0U`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba7ed8690dbfd5c0f83297bcefef1838b1"></a>

`OWNER_DISCONNECTED`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894bacad7f17799e0f75686d4c2b5487c0222"></a>

`RAW_DISCONNECTED`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba5b37c1f5e31bc66cb745596d15f9eb77"></a>

`WIFI_LOST`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba18ec90ed92f5ba900fc659058639a089"></a>

`CHANNEL_CHANGED`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba9781bf1cfd0bd74625eb7706e7851862"></a>

`BIND_TIMEOUT`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894ba5764d112dd5a2400b2474fe0655aa647"></a>

`SLOW_CLIENT`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894bab9984206799a7f9fe4bd1b6c18db8112"></a>

`SHUTDOWN`

  

<a id="namespaceespectre_1af156112b0ff4ebaccc0dd4792a7b894bae8c0c70879b5895c615677261d64a1ee"></a>

`INTERNAL_ERROR`

  

<a id="namespaceespectre_1a55fec3458e3b4db441f3bc69b8b4d531"></a>

### `CsiCaptureProfile`


```cpp
enum class CsiCaptureProfile : uint8_t
```

   

<a id="namespaceespectre_1a55fec3458e3b4db441f3bc69b8b4d531a24f04967c622932f7e0d14c6c6116bb9"></a>

`HT20 = 0`

  

<a id="namespaceespectre_1a55fec3458e3b4db441f3bc69b8b4d531a730bbbd2dbfeb3f9e7bbfc62c5d691dd"></a>

`LLTF20 = 1`

  

<a id="namespaceespectre_1a55fec3458e3b4db441f3bc69b8b4d531a6044439528133be9d5881fe2ffa3a740"></a>

`VHT20 = 2`

  

<a id="namespaceespectre_1a3ac8602b3ece6440ded84d1b663b0645"></a>

### `CsiCapturePolicy`


```cpp
enum class CsiCapturePolicy : uint8_t
```

 

Build-time policy resolved to a physical capture profile after association.

   

<a id="namespaceespectre_1a3ac8602b3ece6440ded84d1b663b0645ae1f2d5134ed2543d38a0de9751cf75d9"></a>

`AUTO = 0`

  

<a id="namespaceespectre_1a3ac8602b3ece6440ded84d1b663b0645a23995e76e6c517049199861bd20a5f7f"></a>

`LLTF = 1`

  

<a id="namespaceespectre_1a3ac8602b3ece6440ded84d1b663b0645aac7a6fd4ec8779cfac29a9102c93df3d"></a>

`HT_VHT = 2`

  

<a id="namespaceespectre_1afb21c6ff9f89b2890a6dd58404ee699e"></a>

### `RuntimeSubcarrierSource`


```cpp
enum class RuntimeSubcarrierSource
```

 

How the runtime chose the subcarriers it measures on.

   

<a id="namespaceespectre_1afb21c6ff9f89b2890a6dd58404ee699ea920d0b6839b502ede5a4d04e019a6e2f"></a>

`FIXED_DEFAULT`

 

The fixed band validated for the shipped detectors.

  

Currently the only mode.

 

<a id="namespaceespectre_1ae6098340c58c0355e67beaa092880c6b"></a>

### `DetectionAlgorithm`


```cpp
enum class DetectionAlgorithm
```

 

Which detector runs.

  

See `docs/ALGORITHMS.md` for how they differ.

  

<a id="namespaceespectre_1ae6098340c58c0355e67beaa092880c6ba56ab46ae63b63cb014aef408f34863a9"></a>

`LIGHTWEIGHT`

 

Lightweight feature fusion.

  

Self-calibrates, and needs no training data. Default.

 

<a id="namespaceespectre_1ae6098340c58c0355e67beaa092880c6ba3b9afd5243cb84a8cbef8865bce2b816"></a>

`HIGH_ACCURACY`

 

High-accuracy neural detector using the trained weights in `core/ml_weights.h`.

  

<a id="namespaceespectre_1a48f4895df7004a72b7dc785b22155aff"></a>

### `RuntimeProfile`


```cpp
enum class RuntimeProfile
```

 

Which runtime backend the controller builds.

   

<a id="namespaceespectre_1a48f4895df7004a72b7dc785b22155affa9f53d28f082938342669ff6fa150947a"></a>

`SENSING`

 

Detect motion on-device and report state.

  

The normal profile.

 

<a id="namespaceespectre_1a5146ba176f5482339fc09cdc7d18a858"></a>

### `RuntimeTrafficMode`


```cpp
enum class RuntimeTrafficMode
```

 

Which packet the internal generator sends to solicit CSI from the AP.

   

<a id="namespaceespectre_1a5146ba176f5482339fc09cdc7d18a858ae07ff41a486c27c095a15898dcca34d1"></a>

`PING`

 

ICMP echo.

  

Default.

 

<a id="namespaceespectre_1a5146ba176f5482339fc09cdc7d18a858aed5f2bdecbd4bd349d09412d1ff6a6fb"></a>

`DNS`

 

DNS queries over connectionless UDP.

  

<a id="namespaceespectre_1a5146ba176f5482339fc09cdc7d18a858a8ad9afc2b5c72f5ed884633f4b187446"></a>

`DNS_TCP`

 

Length-prefixed DNS queries over a persistent TCP connection.

  

<a id="namespaceespectre_1a5146ba176f5482339fc09cdc7d18a858a470317edc5e9cd9b77e1c82fc82879de"></a>

`WIFI_RAW`

 

Raw Wi-Fi Null Data frames addressed to the associated AP.

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93e"></a>

### `RuntimeConfigError`


```cpp
enum class RuntimeConfigError : uint8_t
```

 

Machine-readable reason a [`RuntimeConfig`](#structespectre_1_1_runtime_config) cannot be applied.

   

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eab50339a10e1de285ac99d4c3990b8693"></a>

`NONE = 0`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eaab2b3623c16387eb098cd272eec17e69"></a>

`RUNTIME_PROFILE`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eadb9ba49fd4f85872bd7304b9ce73532b"></a>

`WIFI_BAND_POLICY`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eabb9749dba30f14d44df3d90ff2f49347"></a>

`DETECTION_ALGORITHM`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea27eed88a405a5a259e3ef61b30a00774"></a>

`SEGMENTATION_THRESHOLD`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea80da7e62ceda7e8dc0eb0585fa571560"></a>

`SEGMENTATION_WINDOW_SIZE_MS`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eadc199c0de12fee330627b30dea330860"></a>

`CSI_TARGET_PPS`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eae056f1164f35461290677cb1f67ef46c"></a>

`TRAFFIC_GENERATOR_MODE`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea4b750c13b2c5e301094abb4bad75983b"></a>

`CSI_TRAFFIC_MODE`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eac49034d17b98b5149a39f1a81fc810d2"></a>

`CSI_TRAFFIC_UDP_PORT`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea775c24445714bd79b49d74b40ce5b984"></a>

`CSI_TRAFFIC_MULTICAST_GROUP`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea5a0515c621312c6f547a75ca3179a5d8"></a>

`EVALUATION_INTERVAL_MS`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eadc4869da089da59f51f497b0428ddc37"></a>

`MOTION_HITS`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea0b76f6df73c97bc34b5b05f921ba26ab"></a>

`LOWPASS_CUTOFF`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea20fa3b1aa41abbfaa8ec4bea23294cdf"></a>

`HAMPEL_WINDOW`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93eac9f13f6f6e556f06cf8f11c44e878cf6"></a>

`HAMPEL_THRESHOLD`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea36cb89ee1128f761a86aa8488f6a7dff"></a>

`TRAFFIC_GENERATOR_TARGET_IP`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ea10dc1b07406c7d3f6d4bc6fbd4bbffdf"></a>

`CSI_CAPTURE_PROFILE`

  

<a id="namespaceespectre_1afaec94f4ee217bc8f3f8f5214443c93ead0b82b03047ac28ad4989621265b475f"></a>

`CSI_CAPTURE_PROFILE_TRAFFIC`

  

<a id="namespaceespectre_1a68df0c8c5edce8a6115aacc583567f54"></a>

### `CsiTrafficMode`


```cpp
enum class CsiTrafficMode
```

 

Where the CSI-bearing traffic comes from.

  

CSI is only produced when packets actually arrive, so something has to keep the link busy. This picks who does it.

  

<a id="namespaceespectre_1a68df0c8c5edce8a6115aacc583567f54a182fa1c42a2468f8488e6dcf75a81b81"></a>

`INTERNAL`

 

The runtime generates its own traffic at `csi_target_pps`.

  

Default, and the only self-sufficient mode.

 

<a id="namespaceespectre_1a68df0c8c5edce8a6115aacc583567f54a3932d629fb5e2be9d09b3a4485b3cc9d"></a>

`EXTERNAL`

 

Another device supplies exact UDP markers or unicast ICMP Echo Requests; the runtime does not start its internal generator.

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8"></a>

### `EspectreDirectMethod`


```cpp
enum class EspectreDirectMethod : uint8_t
```

   

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a4a82c34eb02c0a85df93d1ce03d8cb73"></a>

`CAPABILITIES = 0`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a551b723eafd6a31d444fcb2f5920fbd3"></a>

`INFO`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a5f241c8c8f985b3c51e05d39cf030f4c"></a>

`STATUS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a73e99d350a4aa6f1a5af04ec29173f73"></a>

`CONFIG`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8ab84a5c31b5eb0f818f696c05c86cdc12"></a>

`DIAGNOSTICS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a6c64768599b8a2e5122925893460dea5"></a>

`SET_SENSING`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a1b4ee44dec7b7dc5418ea6a2a1657cea"></a>

`SET_DEVICE_LABEL`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a1e11be2ec8de268d919215833fb1a548"></a>

`SET_THRESHOLD`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a886b96586a5750ee3fa941509fce3583"></a>

`SET_MOTION_HITS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a64ecc60dfa1e5eef76e5ed276b19f502"></a>

`SET_DETECTOR`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8aa59a90d8e320711bc5365ecb24ec0f4e"></a>

`RECALIBRATE`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8ada16c5572a2d2983a2189d55399d72a4"></a>

`START_RAW_STREAM`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a08a5be2be93c4e9dcd813383eb4231fa"></a>

`STOP_RAW_STREAM`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a2ef8964eae44eee3b531dee68c528b6c"></a>

`SET_CSI_TRAFFIC_MODE`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a3f95f7923d4f70750d2d491cc662d6da"></a>

`SET_TRAFFIC_GENERATOR_MODE`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a1c09b3b226ddea0b13c18f4e294b4205"></a>

`WIFI_ACCESS_POINTS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a950b1d4cdc7a4119ca268ccc34cb51c5"></a>

`SCAN_WIFI_ACCESS_POINTS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a9de29080e74b98b067c928209641ee96"></a>

`SET_WIFI_BSSID`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8af1547d17befcf56ea02805e78b8a0a36"></a>

`CLEAR_WIFI_BSSID`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8af9f8177feaa1ee5fcc28d65333f4b285"></a>

`CLEAR_WIFI_CONFIG`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a1ff395f3838c8af5d53a3d0cbe18368d"></a>

`SET_MQTT_CONFIG`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8aa6cb515e3f7b084732d0890c5763eb20"></a>

`CLEAR_MQTT_CONFIG`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a1211f2728fa92bbcd91b84b900a5e464"></a>

`DISCOVER_PEERS`

  

<a id="namespaceespectre_1afca4c79a12b4b401c979d6232c2a0bd8a4905ac9d6a22bdfc1ae096094ce6248d"></a>

`COUNT`

  

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8"></a>

### `EspectreConfigSection`


```cpp
enum class EspectreConfigSection : uint8_t
```

   

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8ae5f5cd9fe71ac064a678f27c7d539ae8"></a>

`RUNTIME = 0`

  

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8ae10b6ab6a278644ce40631f62f360b6d"></a>

`DEVICE`

  

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8a2f0b4d2c0c3d64bbb2cd525dbba8b0d0"></a>

`WIFI`

  

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8aab0a7cf5deeda86b66467df64c3b6122"></a>

`MQTT`

  

<a id="namespaceespectre_1afc7c8d567fb0888be484d8ebdda994a8a4905ac9d6a22bdfc1ae096094ce6248d"></a>

`COUNT`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ff"></a>

### `EspectreEvent`


```cpp
enum class EspectreEvent : uint8_t
```

   

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffabb3d2d909c73fe49800949a344775f8b"></a>

`TELEMETRY = 0`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffa5f241c8c8f985b3c51e05d39cf030f4c"></a>

`STATUS`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffa551b723eafd6a31d444fcb2f5920fbd3"></a>

`INFO`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffa73e99d350a4aa6f1a5af04ec29173f73"></a>

`CONFIG`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffa893b3aaf1661e3717b18e8335ff93a72"></a>

`FAULT`

  

<a id="namespaceespectre_1a8c8b3454eae8a719a4f529bf205bf0ffa4905ac9d6a22bdfc1ae096094ce6248d"></a>

`COUNT`

  

<a id="namespaceespectre_1a673de3f0a8dc83c71f9a080a6e195084"></a>

### `EspectreApiRouteKind`


```cpp
enum class EspectreApiRouteKind : uint8_t
```

   

<a id="namespaceespectre_1a673de3f0a8dc83c71f9a080a6e195084a4f49da9035f276c0947466eb7c42249a"></a>

`RESOURCE = 0`

  

<a id="namespaceespectre_1a673de3f0a8dc83c71f9a080a6e195084ad6a0beecbcc46b64a23307ffc084ed36"></a>

`OPERATION`

  

<a id="namespaceespectre_1a673de3f0a8dc83c71f9a080a6e195084a2f05998d2a71cdc19b7109549bbe2646"></a>

`STREAM`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846"></a>

### `JsonValueType`


```cpp
enum class JsonValueType : uint8_t
```

   

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846a63b588d5559f64f89a416e656880b949"></a>

`STRING = 0`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846a34f55eca38e0605a84f169ff61a2a396"></a>

`NUMBER`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846ac48d5da12d702e73d6966069f2687376"></a>

`BOOLEAN`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846aa9f0aff2067f91437e50e4872b229e6a"></a>

`NULL_VALUE`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846a8eee8e217391199668cbac89472ace53"></a>

`OBJECT`

  

<a id="namespaceespectre_1ac017ab0ef298a8a5cd2ba8876dc67846acb4fb1757fb37c43cded35d3eb857c43"></a>

`ARRAY`

  

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadb"></a>

### `LogLevel`


```cpp
enum class LogLevel : uint8_t
```

 

Severity attached to one ESPectre log message.

   

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadbabb1ca97ec761fc37101737ba0aa2e7c5"></a>

`ERROR = 1`

  

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadba059e9861e0400dfbe05c98a841f3f96b"></a>

`WARNING = 2`

  

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadba551b723eafd6a31d444fcb2f5920fbd3"></a>

`INFO = 3`

  

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadbadc30ec20708ef7b0f641ef78b7880a15"></a>

`DEBUG = 4`

  

<a id="namespaceespectre_1adfd78003c463a47035e2de0ecd39cadbaec1f06e9fb39c4ef0729b3c7c9c8e8cc"></a>

`VERBOSE = 5`

  

<a id="namespaceespectre_1a7d37681f3243ed6bdd97aee1ed776857"></a>

### `MotionState`


```cpp
enum class MotionState
```

 

Debounced detector state.

   

<a id="namespaceespectre_1a7d37681f3243ed6bdd97aee1ed776857aa5daf7f2ebbba4975d61dab1c40188c7"></a>

`IDLE`

  

<a id="namespaceespectre_1a7d37681f3243ed6bdd97aee1ed776857af96e6ea7a7375bd60bad3f3caae3cf27"></a>

`MOTION`

  

<a id="namespaceespectre_1a1a2af5566391edd860e3585c8f8b4bb3"></a>

### `Ht20BinLayout`


```cpp
enum class Ht20BinLayout : uint8_t
```

   

<a id="namespaceespectre_1a1a2af5566391edd860e3585c8f8b4bb3a696b031073e74bf2cb98e5ef201d4aa3"></a>

`UNKNOWN = 0`

  

<a id="namespaceespectre_1a1a2af5566391edd860e3585c8f8b4bb3a21c97af368df9b59d1244bd698506814"></a>

`CENTERED`

  

<a id="namespaceespectre_1a1a2af5566391edd860e3585c8f8b4bb3a21994d6177b29e1128b2d7f0f8342057"></a>

`CLASSIC`

  

<a id="namespaceespectre_1a66960f4a1cf7a867acd1d1a7c9f52d18"></a>

### `MdnsResponderMode`


```cpp
enum class MdnsResponderMode : uint8_t
```

   

<a id="namespaceespectre_1a66960f4a1cf7a867acd1d1a7c9f52d18a2a353b2cdb13a76f32641ff7f25e4cea"></a>

`OWN_RESPONDER = 0`

  

<a id="namespaceespectre_1a66960f4a1cf7a867acd1d1a7c9f52d18af8944176f9ecbfea29c227b401ad4a92"></a>

`USE_EXISTING_RESPONDER`

  

<a id="namespaceespectre_1afb799961d21e38195f1ad899880c3189"></a>

### `UdpReceiveResult`


```cpp
enum class UdpReceiveResult
```

   

<a id="namespaceespectre_1afb799961d21e38195f1ad899880c3189a0334b8669eb43f45f9bccb223186be65"></a>

`PACKET`

  

<a id="namespaceespectre_1afb799961d21e38195f1ad899880c3189aba2b45bdc11e2a4a6e86aab2ac693cbb"></a>

`EMPTY`

  

<a id="namespaceespectre_1afb799961d21e38195f1ad899880c3189abb1ca97ec761fc37101737ba0aa2e7c5"></a>

`ERROR`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291fa"></a>

### `WifiBssidPinApplyState`


```cpp
enum class WifiBssidPinApplyState : uint8_t
```

   

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faaa5daf7f2ebbba4975d61dab1c40188c7"></a>

`IDLE = 0`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faa4ea687957de9caaad1e098e3e95aae9e"></a>

`VERIFYING`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faa704940fadc36a1ea05e200e3ccaeb298"></a>

`ROLLING_BACK`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faaa949e143063cf0e9ab61dc7004280c35"></a>

`APPLIED`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faaed701d1c3d474e00c7a2f416f8d6858c"></a>

`ROLLED_BACK`

  

<a id="namespaceespectre_1afd04e6f466bb9a85e3f867421d5291faab0abcd2350d0f34995a7eb78c6a3c035"></a>

`RECOVERY_REQUIRED`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339"></a>

### `WifiProvisioningApplyState`


```cpp
enum class WifiProvisioningApplyState : uint8_t
```

   

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339aa5daf7f2ebbba4975d61dab1c40188c7"></a>

`IDLE = 0`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339a4ea687957de9caaad1e098e3e95aae9e"></a>

`VERIFYING`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339a704940fadc36a1ea05e200e3ccaeb298"></a>

`ROLLING_BACK`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339aa949e143063cf0e9ab61dc7004280c35"></a>

`APPLIED`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339aed701d1c3d474e00c7a2f416f8d6858c"></a>

`ROLLED_BACK`

  

<a id="namespaceespectre_1a31d1131642dc8c0436b043e4c899c339ab0abcd2350d0f34995a7eb78c6a3c035"></a>

`RECOVERY_REQUIRED`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aa"></a>

### `FrontendCommandChange`


```cpp
enum class FrontendCommandChange : uint8_t
```

   

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaab50339a10e1de285ac99d4c3990b8693"></a>

`NONE = 0U`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaa785a1e256fca0cd6be7b3dced4281845"></a>

`HEALTH = 1U << 0U`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaae10b6ab6a278644ce40631f62f360b6d"></a>

`DEVICE = 1U << 1U`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaa9f53d28f082938342669ff6fa150947a"></a>

`SENSING = 1U << 2U`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaa2f0b4d2c0c3d64bbb2cd525dbba8b0d0"></a>

`WIFI = 1U << 3U`

  

<a id="namespaceespectre_1aa730eb411cfeec940ccae2c21b7fa2aaaab0a7cf5deeda86b66467df64c3b6122"></a>

`MQTT = 1U << 4U`

  

<a id="namespaceespectre_1a78137e71d7f05fcbfbda841d3a1fc91b"></a>

### `FrontendCommandOrigin`


```cpp
enum class FrontendCommandOrigin : uint8_t
```

   

<a id="namespaceespectre_1a78137e71d7f05fcbfbda841d3a1fc91ba4c5d06b02c97731aaa976179c62dcf76"></a>

`DIRECT = 0U`

  

<a id="namespaceespectre_1a78137e71d7f05fcbfbda841d3a1fc91baab0a7cf5deeda86b66467df64c3b6122"></a>

`MQTT`

  

<a id="namespaceespectre_1a78137e71d7f05fcbfbda841d3a1fc91bac31870dbba5ac72e2f563d5d66586fcd"></a>

`ESPHOME`

  

<a id="namespaceespectre_1a78137e71d7f05fcbfbda841d3a1fc91baa8a5f21c20fd888a9397997f73863e73"></a>

`MATTER`

  


<a id="namespaceespectre_1a7b0352147eec65c1f73a9d8714c4596d"></a>

### `raw_csi_packet_callback_t`


```cpp
using espectre::raw_csi_packet_callback_t = bool (*)(void *context, const RawCsiPacketView &packet)
```

 

Consume one packet synchronously from the Wi-Fi CSI capture context.

  

The callback must remain bounded, non-blocking, and allocation-free. It may copy the packet into a preallocated bounded queue for another task. Returning false reports that the consumer did not accept this packet, for example because that queue was full; collection continues, and the consumer owns any drop or backpressure accounting.

 

**Parameters**

- `context`: Opaque caller-owned value supplied to `start_raw_collection()`.
- `packet`: Callback-scoped normalized CSI view.

 

**Returns:** true when the consumer accepted the packet, or false when it dropped it. The runtime does not stop collection on false.

  

<a id="namespaceespectre_1a9f2afa911ec48980e30f5e049d6d89ee"></a>

### `runtime_diagnostic_visitor_t`


```cpp
using espectre::runtime_diagnostic_visitor_t = std::function<void(const char *key, const char *value)>
```

   

<a id="namespaceespectre_1a478bd5431108f78995bfb1c53acc3e25"></a>

### `EspectreCommandValidator`


```cpp
using espectre::EspectreCommandValidator = bool (*)(const std::vector<JsonObjectField> &fields,
                                       EspectreCommand *command, std::string *error)
```

 

Validate decoded parameters and populate the command before dispatch.

  

The parser supplies valid JSON fields and the command identity. MQTT fields also contain its envelope. Validators must not execute commands or change device state. Ignore command output after a rejected validation.

  

<a id="namespaceespectre_1a47f56ef0a5dfb7004c12e04f60fcc511"></a>

### `LogEnabledCallback`


```cpp
using espectre::LogEnabledCallback = bool (*)(void *context, LogLevel level, const char *tag)
```

 

Return whether a sink accepts a message with the supplied level and tag.

   

<a id="namespaceespectre_1af956f386b6f44926d0860f7ca0dffdd0"></a>

### `LogWriteCallback`


```cpp
using espectre::LogWriteCallback = void (*)(void *context, LogLevel level, const char *tag, int line,
                                 const char *format, va_list args)
```

 

Consume one enabled ESPectre log message before the supplied argument list expires.

   

<a id="namespaceespectre_1a1eaac1c4c744a0c2aa7a1013a884087e"></a>

### `SelectedSubcarriers`


```cpp
using espectre::SelectedSubcarriers = std::array<uint8_t, HT20_SELECTED_BAND_SIZE>
```

   

<a id="namespaceespectre_1a813ec6a7ade93fd50621b8138c0ebe92"></a>

### `FrontendMqttConnectedCallback`


```cpp
using espectre::FrontendMqttConnectedCallback = std::function<void(bool)>
```

   

<a id="namespaceespectre_1a5c8f69b635e49d299f2dadb56b43074d"></a>

### `MdnsTxtRecords`


```cpp
using espectre::MdnsTxtRecords = std::vector<std::pair<std::string, std::string>>
```

   

<a id="namespaceespectre_1aaca2bec6937994f03279640eba6ea6a2"></a>

### `standalone_wifi_callback_t`


```cpp
using espectre::standalone_wifi_callback_t = std::function<void()>
```

   

<a id="namespaceespectre_1a841cce05055be401e9d7f541f67c0f17"></a>

### `standalone_wifi_scan_callback_t`


```cpp
using espectre::standalone_wifi_scan_callback_t = 
std::function<void(esp_err_t, const std::vector<StandaloneWifiAccessPoint> &)>
```

   

<a id="namespaceespectre_1a8b131fc80e5f6619153aaf47d7a61dc9"></a>

### `csi_traffic_packet_callback_t`


```cpp
using espectre::csi_traffic_packet_callback_t = void (*)(void *, const UdpDatagramPeer &, uint64_t)
```

   

<a id="namespaceespectre_1a64ef59dbd1b0e33b0d19ba5ead0b9301"></a>

### `wifi_connected_callback_t`


```cpp
using espectre::wifi_connected_callback_t = std::function<void(const esp_netif_ip_info_t &)>
```

   

<a id="namespaceespectre_1ab5095f85174c76bb5eef718e24479044"></a>

### `wifi_disconnected_callback_t`


```cpp
using espectre::wifi_disconnected_callback_t = std::function<void()>
```

   

<a id="namespaceespectre_1a2eaa099b9086c9f90afcc8001d90afdc"></a>

### `wifi_csi_rx_refresh_callback_t`


```cpp
using espectre::wifi_csi_rx_refresh_callback_t = std::function<void(esp_err_t)>
```

   

<a id="namespaceespectre_1a4666885dc63b45f88f0a23b60f45943f"></a>

### `DeviceConfigClearHandler`


```cpp
using espectre::DeviceConfigClearHandler = std::function<bool(EspectreDeviceConfig *cleared_config, std::string *message)>
```

   

<a id="namespaceespectre_1a12fe9dc717767084708d9b055d94b2d5"></a>

### `DeviceConfigUpdateHandler`


```cpp
using espectre::DeviceConfigUpdateHandler = std::function<bool(EspectreDeviceConfig *updated_config, std::string *message)>
```

   

<a id="namespaceespectre_1a99ebf34bc489f9258115ae3fc39c84cc"></a>

### `FrontendReadPayloadCallback`


```cpp
using espectre::FrontendReadPayloadCallback = std::function<std::string(const EspectreCommand &command)>
```

   

<a id="namespaceespectre_1a8e42108419d4fce5a5d1a958dd7674b0"></a>

### `FrontendDeviceLabelCallback`


```cpp
using espectre::FrontendDeviceLabelCallback = std::function<bool(const std::string &device_label, std::string *message)>
```

   

<a id="namespaceespectre_1a7ef25a2cd5bc69f39d5c604bfa7205c1"></a>

### `FrontendThresholdCallback`


```cpp
using espectre::FrontendThresholdCallback = std::function<bool(float threshold, std::string *message)>
```

   

<a id="namespaceespectre_1ac9bb8399a317cda44a26fabc384d9415"></a>

### `FrontendMotionHitsCallback`


```cpp
using espectre::FrontendMotionHitsCallback = 
std::function<bool(uint8_t motion_on_hits, uint8_t motion_off_hits, std::string *message)>
```

   

<a id="namespaceespectre_1af9058d4f4142a049749b9c713347e627"></a>

### `FrontendCsiTrafficModeCallback`


```cpp
using espectre::FrontendCsiTrafficModeCallback = std::function<bool(CsiTrafficMode mode, std::string *message)>
```

   

<a id="namespaceespectre_1aee0a6f6948263baac5f2cb015603cdf7"></a>

### `FrontendTrafficGeneratorModeCallback`


```cpp
using espectre::FrontendTrafficGeneratorModeCallback = std::function<bool(RuntimeTrafficMode mode, std::string *message)>
```

   

<a id="namespaceespectre_1aeb40ee64d61b2f1df17f0a2fdd91edbc"></a>

### `FrontendDetectorCallback`


```cpp
using espectre::FrontendDetectorCallback = std::function<bool(DetectionAlgorithm algorithm, std::string *message)>
```

   

<a id="namespaceespectre_1aa3d2cbbf3ae5675785b1f944ffedfd84"></a>

### `FrontendRecalibrateCallback`


```cpp
using espectre::FrontendRecalibrateCallback = std::function<bool(std::string *message)>
```

   

<a id="namespaceespectre_1ae7042efa563d462c22f07520e14049af"></a>

### `FrontendWifiBssidCallback`


```cpp
using espectre::FrontendWifiBssidCallback = 
std::function<bool(const EspectreCommand &command, std::string *message)>
```

   

<a id="namespaceespectre_1a9bd446908b7d5f2991698aa087668f76"></a>

### `FrontendMqttConfigCallback`


```cpp
using espectre::FrontendMqttConfigCallback = 
std::function<bool(const EspectreCommand &command, bool clear, std::string *message)>
```

   

<a id="namespaceespectre_1a0dde9bbbb9dbdb4c4fe1502ddf47ea7a"></a>

### `FrontendSensingControlCallback`


```cpp
using espectre::FrontendSensingControlCallback = std::function<bool(bool enabled, std::string *message)>
```

   

<a id="namespaceespectre_1adb9cf94c891937db2c4ded369dbdc673"></a>

### `FrontendRawStreamCallback`


```cpp
using espectre::FrontendRawStreamCallback = std::function<bool(const EspectreCommand &command,
                                                     const struct FrontendCommandContext &context,
                                                     std::string *code,
                                                     std::string *message,
                                                     std::string *data_json)>
```

   

<a id="namespaceespectre_1a664f7aebe8d7f8986a2d83e28357cc87"></a>

### `FrontendCommandCapabilities`


```cpp
using espectre::FrontendCommandCapabilities = EspectreCapabilityProfile
```

   


<a id="namespaceespectre_1a186d8ab957e623995b7886680bed2b29"></a>

### `RAW_CSI_RECORD_MAGIC`


```cpp
constexpr uint16_t espectre::RAW_CSI_RECORD_MAGIC = 0x4353U
```

   

<a id="namespaceespectre_1ad09e1e1069d9051c3062cc0a5d1811c8"></a>

### `RAW_CSI_RECORD_VERSION_V7`


```cpp
constexpr uint8_t espectre::RAW_CSI_RECORD_VERSION_V7 = 7U
```

   

<a id="namespaceespectre_1aa6cd6c48916e2a6c73f2a3368ba29afe"></a>

### `RAW_CSI_RECORD_VERSION_V8`


```cpp
constexpr uint8_t espectre::RAW_CSI_RECORD_VERSION_V8 = 8U
```

   

<a id="namespaceespectre_1acab3236d6dc24a0de6613d494177569a"></a>

### `RAW_CSI_RECORD_VERSION`


```cpp
constexpr uint8_t espectre::RAW_CSI_RECORD_VERSION = RAW_CSI_RECORD_VERSION_V8
```

   

<a id="namespaceespectre_1a24dad547c0781d8f0f29395e0bed182f"></a>

### `RAW_CSI_MAX_PAYLOAD_BYTES`


```cpp
constexpr size_t espectre::RAW_CSI_MAX_PAYLOAD_BYTES = 512U
```

   

<a id="namespaceespectre_1a6d19fef4bba723c7e98adda2a45aed2c"></a>

### `RAW_CSI_MAX_RECORD_BYTES`


```cpp
constexpr size_t espectre::RAW_CSI_MAX_RECORD_BYTES                                              =
sizeof(RawCsiRecordHeaderV8) + RAW_CSI_MAX_PAYLOAD_BYTES
```

   

<a id="namespaceespectre_1ad97c50bf378e0be4ecca2d57aae35f21"></a>

### `ESPECTRE_RAW_CSI_ENDPOINT`


```cpp
constexpr char espectre::ESPECTRE_RAW_CSI_ENDPOINT[][] = "/espectre/v1/csi"
```

   

<a id="namespaceespectre_1a1571e2dbb44f5b5edacc83b4d1539ea9"></a>

### `ESPECTRE_RAW_CSI_PROTOCOL_VERSION`


```cpp
constexpr uint8_t espectre::ESPECTRE_RAW_CSI_PROTOCOL_VERSION = 1U
```

   

<a id="namespaceespectre_1a2c47aea6a64e9bbf1699a0066f9c437f"></a>

### `ESPECTRE_RAW_CSI_RECORD_VERSION`


```cpp
constexpr uint8_t espectre::ESPECTRE_RAW_CSI_RECORD_VERSION = RAW_CSI_RECORD_VERSION_V8
```

   

<a id="namespaceespectre_1a74df0adfb1aeee5b74d72ff5650afc51"></a>

### `ESPECTRE_RAW_CSI_SESSION_ID_BYTES`


```cpp
constexpr size_t espectre::ESPECTRE_RAW_CSI_SESSION_ID_BYTES = 16U
```

   

<a id="namespaceespectre_1ad78ee1950a9973d84c25e6b5e925aff4"></a>

### `ESPECTRE_RAW_CSI_RESPONSE_MAGIC`


```cpp
constexpr uint32_t espectre::ESPECTRE_RAW_CSI_RESPONSE_MAGIC = 0x52505345U
```

   

<a id="namespaceespectre_1a212cc7fe3aa038d9e1326fc8037ee3db"></a>

### `RUNTIME_CSI_CAPTURE_PROFILE_DEFAULT_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_CAPTURE_PROFILE_DEFAULT_NAME = "auto"
```

   

<a id="namespaceespectre_1a177c18a106b6080f362093d71a68fabf"></a>

### `RUNTIME_TRAFFIC_GENERATOR_MODE_PING_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_TRAFFIC_GENERATOR_MODE_PING_NAME = "ping"
```

   

<a id="namespaceespectre_1a15bc0df459745afa7ae4f9e4c6f34b5f"></a>

### `RUNTIME_TRAFFIC_GENERATOR_MODE_DNS_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_TRAFFIC_GENERATOR_MODE_DNS_NAME = "dns"
```

   

<a id="namespaceespectre_1ae6e8beabd6199438e40524e01b53c22b"></a>

### `RUNTIME_TRAFFIC_GENERATOR_MODE_DNS_TCP_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_TRAFFIC_GENERATOR_MODE_DNS_TCP_NAME = "dns_tcp"
```

   

<a id="namespaceespectre_1a4013ba85b37d675d5a44588073b4b670"></a>

### `RUNTIME_TRAFFIC_GENERATOR_MODE_WIFI_RAW_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_TRAFFIC_GENERATOR_MODE_WIFI_RAW_NAME = "wifi_raw"
```

   

<a id="namespaceespectre_1ae798b6e9325d406dacc0ab49f991df26"></a>

### `RUNTIME_TRAFFIC_GENERATOR_MODE_DEFAULT_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_TRAFFIC_GENERATOR_MODE_DEFAULT_NAME = "ping"
```

   

<a id="namespaceespectre_1a179de174b71994ed18e239601491ab91"></a>

### `RUNTIME_CSI_TRAFFIC_MODE_INTERNAL_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_TRAFFIC_MODE_INTERNAL_NAME = "internal"
```

   

<a id="namespaceespectre_1a1866c478c4d98eef98482efc5ebce402"></a>

### `RUNTIME_CSI_TRAFFIC_MODE_EXTERNAL_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_TRAFFIC_MODE_EXTERNAL_NAME = "external"
```

   

<a id="namespaceespectre_1af1010e88aab1404158dafb05148f7dd3"></a>

### `RUNTIME_CSI_TRAFFIC_MODE_DEFAULT_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_TRAFFIC_MODE_DEFAULT_NAME = "internal"
```

   

<a id="namespaceespectre_1af8f4e638e243e4b5a4cc9f781821abd6"></a>

### `RUNTIME_DETECTION_ALGORITHM_LIGHTWEIGHT_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_DETECTION_ALGORITHM_LIGHTWEIGHT_NAME = "lightweight"
```

   

<a id="namespaceespectre_1a5827219e367d7820fa6e9e996e16ea27"></a>

### `RUNTIME_DETECTION_ALGORITHM_HIGH_ACCURACY_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_DETECTION_ALGORITHM_HIGH_ACCURACY_NAME = "high_accuracy"
```

   

<a id="namespaceespectre_1a44d5c8854bb3a570793dcee5542244d5"></a>

### `RUNTIME_DETECTION_ALGORITHM_DEFAULT_NAME`


```cpp
constexpr const char* const espectre::RUNTIME_DETECTION_ALGORITHM_DEFAULT_NAME = "lightweight"
```

   

<a id="namespaceespectre_1afd6e4e1d251c290d51df4263fda0750d"></a>

### `RUNTIME_THRESHOLD_MIN`


```cpp
constexpr float espectre::RUNTIME_THRESHOLD_MIN = 0.0f
```

   

<a id="namespaceespectre_1a5a433a007084875084bee62d094cab95"></a>

### `RUNTIME_THRESHOLD_MAX`


```cpp
constexpr float espectre::RUNTIME_THRESHOLD_MAX = 1.0f
```

   

<a id="namespaceespectre_1a2f7c72dc6bebf5bf906536101a6b1345"></a>

### `RUNTIME_HIGH_ACCURACY_THRESHOLD_MAX`


```cpp
constexpr float espectre::RUNTIME_HIGH_ACCURACY_THRESHOLD_MAX = 1.0f
```

   

<a id="namespaceespectre_1a2cda86143a5ad864c80703cc65563842"></a>

### `RUNTIME_SEGMENTATION_THRESHOLD_DEFAULT`


```cpp
constexpr float espectre::RUNTIME_SEGMENTATION_THRESHOLD_DEFAULT = LIGHTWEIGHT_DEFAULT_THRESHOLD
```

   

<a id="namespaceespectre_1a52a4b7aecae39731e6a111f3257cf2ad"></a>

### `RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_MIN`


```cpp
constexpr uint32_t espectre::RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_MIN = 1000U
```

   

<a id="namespaceespectre_1ae31d05500f149e912a2a10de932f07ff"></a>

### `RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_MAX`


```cpp
constexpr uint32_t espectre::RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_MAX = 2000U
```

   

<a id="namespaceespectre_1a4b04a641c87173cd9e19c8365116de0d"></a>

### `RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_DEFAULT`


```cpp
constexpr uint32_t espectre::RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_DEFAULT = 1000U
```

   

<a id="namespaceespectre_1abcca8e8bd6537b2fed9f7dc11e62236c"></a>

### `RUNTIME_CSI_TARGET_PPS_MIN`


```cpp
constexpr uint32_t espectre::RUNTIME_CSI_TARGET_PPS_MIN = 1U
```

   

<a id="namespaceespectre_1a403c34b91ec353131e952dac15bf2ff4"></a>

### `RUNTIME_CSI_TARGET_PPS_MAX`


```cpp
constexpr uint32_t espectre::RUNTIME_CSI_TARGET_PPS_MAX = 500U
```

   

<a id="namespaceespectre_1a583bc098543bc63653f26960274b2ad1"></a>

### `RUNTIME_CSI_TARGET_PPS_DEFAULT`


```cpp
constexpr uint32_t espectre::RUNTIME_CSI_TARGET_PPS_DEFAULT = 100U
```

   

<a id="namespaceespectre_1adac330f75e60dcf8bbc56efa51cac931"></a>

### `RUNTIME_HEARTBEAT_INTERVAL_MS`


```cpp
constexpr uint32_t espectre::RUNTIME_HEARTBEAT_INTERVAL_MS = 1000U
```

   

<a id="namespaceespectre_1aa957a79703f3f36f20564faaf6993407"></a>

### `RUNTIME_EVALUATION_INTERVAL_MS_MIN`


```cpp
constexpr uint32_t espectre::RUNTIME_EVALUATION_INTERVAL_MS_MIN = 10
```

   

<a id="namespaceespectre_1a76f1e1c451892d2a18476282920c5083"></a>

### `RUNTIME_EVALUATION_INTERVAL_MS_MAX`


```cpp
constexpr uint32_t espectre::RUNTIME_EVALUATION_INTERVAL_MS_MAX = 10000
```

   

<a id="namespaceespectre_1abc8035d1720779136e60e9a88a0e8379"></a>

### `RUNTIME_EVALUATION_INTERVAL_MS_DEFAULT`


```cpp
constexpr uint32_t espectre::RUNTIME_EVALUATION_INTERVAL_MS_DEFAULT = 250
```

   

<a id="namespaceespectre_1a7f65a463577a02ef0bdfe49dd9d8c1a5"></a>

### `RUNTIME_MOTION_HITS_MIN`


```cpp
constexpr uint8_t espectre::RUNTIME_MOTION_HITS_MIN = 1
```

   

<a id="namespaceespectre_1a42ac71e1ad53db97efbf0898dfba62a0"></a>

### `RUNTIME_MOTION_HITS_MAX`


```cpp
constexpr uint8_t espectre::RUNTIME_MOTION_HITS_MAX = 20
```

   

<a id="namespaceespectre_1a028b847c20853cced681ca0ff3ad147c"></a>

### `RUNTIME_MOTION_ON_HITS_DEFAULT`


```cpp
constexpr uint8_t espectre::RUNTIME_MOTION_ON_HITS_DEFAULT = 4
```

   

<a id="namespaceespectre_1a40824ccf41b07b064f7525a39576cf94"></a>

### `RUNTIME_MOTION_OFF_HITS_DEFAULT`


```cpp
constexpr uint8_t espectre::RUNTIME_MOTION_OFF_HITS_DEFAULT = 3
```

   

<a id="namespaceespectre_1a6dc500d40bcaf9eb8c919fe6e09cd022"></a>

### `RUNTIME_LOWPASS_ENABLED_DEFAULT`


```cpp
constexpr bool espectre::RUNTIME_LOWPASS_ENABLED_DEFAULT = false
```

   

<a id="namespaceespectre_1a0b99ade66a66ac0a13036513a81f6603"></a>

### `RUNTIME_LOWPASS_CUTOFF_MIN`


```cpp
constexpr float espectre::RUNTIME_LOWPASS_CUTOFF_MIN = 5.0f
```

   

<a id="namespaceespectre_1af586a478157c4558cda661fa83d923cd"></a>

### `RUNTIME_LOWPASS_CUTOFF_MAX`


```cpp
constexpr float espectre::RUNTIME_LOWPASS_CUTOFF_MAX = 20.0f
```

   

<a id="namespaceespectre_1a772d7d6b6983a5c8494423e18fffaf53"></a>

### `RUNTIME_LOWPASS_CUTOFF_DEFAULT`


```cpp
constexpr float espectre::RUNTIME_LOWPASS_CUTOFF_DEFAULT = 11.0f
```

   

<a id="namespaceespectre_1af46a5471c983b1f109895d59157feb20"></a>

### `RUNTIME_HAMPEL_ENABLED_DEFAULT`


```cpp
constexpr bool espectre::RUNTIME_HAMPEL_ENABLED_DEFAULT = true
```

   

<a id="namespaceespectre_1a47c2f441115ede397c06d5bc899ec450"></a>

### `RUNTIME_HAMPEL_WINDOW_MIN`


```cpp
constexpr uint8_t espectre::RUNTIME_HAMPEL_WINDOW_MIN = 3
```

   

<a id="namespaceespectre_1a49f3bcfd4d73eab0387bdddee7ee938b"></a>

### `RUNTIME_HAMPEL_WINDOW_MAX`


```cpp
constexpr uint8_t espectre::RUNTIME_HAMPEL_WINDOW_MAX = 11
```

   

<a id="namespaceespectre_1a288d1fd358e79e234ddeb67716b7a409"></a>

### `RUNTIME_HAMPEL_WINDOW_DEFAULT`


```cpp
constexpr uint8_t espectre::RUNTIME_HAMPEL_WINDOW_DEFAULT = 7
```

   

<a id="namespaceespectre_1ae5995a8c638215586d44542666335423"></a>

### `RUNTIME_HAMPEL_THRESHOLD_MIN`


```cpp
constexpr float espectre::RUNTIME_HAMPEL_THRESHOLD_MIN = 1.0f
```

   

<a id="namespaceespectre_1a0791cf4717749234bd7f410e0835296a"></a>

### `RUNTIME_HAMPEL_THRESHOLD_MAX`


```cpp
constexpr float espectre::RUNTIME_HAMPEL_THRESHOLD_MAX = 10.0f
```

   

<a id="namespaceespectre_1aef979169064e256a1dc21d83268a8413"></a>

### `RUNTIME_HAMPEL_THRESHOLD_DEFAULT`


```cpp
constexpr float espectre::RUNTIME_HAMPEL_THRESHOLD_DEFAULT = 5.0f
```

   

<a id="namespaceespectre_1a7c7e37b036bf9c750ffad94cc3f38f9b"></a>

### `RUNTIME_NETWORK_PORT_MIN`


```cpp
constexpr uint16_t espectre::RUNTIME_NETWORK_PORT_MIN = 1U
```

   

<a id="namespaceespectre_1a0f402dae6c22e383c6b47630879afa75"></a>

### `RUNTIME_NETWORK_PORT_MAX`


```cpp
constexpr uint16_t espectre::RUNTIME_NETWORK_PORT_MAX = UINT16_MAX
```

   

<a id="namespaceespectre_1aa38060237841c079d8afb7e5ad41071b"></a>

### `RUNTIME_CSI_TRAFFIC_UDP_PORT_DEFAULT`


```cpp
constexpr uint16_t espectre::RUNTIME_CSI_TRAFFIC_UDP_PORT_DEFAULT = 5555
```

   

<a id="namespaceespectre_1a65e83d64d1c3f527d18a1da78e0b8dab"></a>

### `RUNTIME_CSI_TRAFFIC_MULTICAST_GROUP_DEFAULT`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_TRAFFIC_MULTICAST_GROUP_DEFAULT = "239.255.0.1"
```

   

<a id="namespaceespectre_1a7d2c42f00556433c50808762f93556bc"></a>

### `RUNTIME_CSI_TRAFFIC_MARKER_BYTES`


```cpp
constexpr uint8_t espectre::RUNTIME_CSI_TRAFFIC_MARKER_BYTES[][] = {0xF0U, 0x9FU, 0x91U, 0xBBU}
```

   

<a id="namespaceespectre_1a0217d11161d783391700195752d0abe9"></a>

### `RUNTIME_CSI_TRAFFIC_MARKER_LENGTH`


```cpp
constexpr size_t espectre::RUNTIME_CSI_TRAFFIC_MARKER_LENGTH = 4U
```

   

<a id="namespaceespectre_1a08717633496abf2eeb11f9a12f83c3e2"></a>

### `RUNTIME_CSI_TRAFFIC_MARKER_UTF8`


```cpp
constexpr const char* const espectre::RUNTIME_CSI_TRAFFIC_MARKER_UTF8 = "👻"
```

   

<a id="namespaceespectre_1ac0d561a007409fc2c0a940f9e5db2c8d"></a>

### `RUNTIME_CSI_TRAFFIC_EXPECTED_PAYLOAD_MAX`


```cpp
constexpr size_t espectre::RUNTIME_CSI_TRAFFIC_EXPECTED_PAYLOAD_MAX = 16U
```

   

<a id="namespaceespectre_1a647011431c82d51c8630e5304f968023"></a>

### `ESPECTRE_DEVICE_LABEL_MAX_LENGTH`


```cpp
constexpr size_t espectre::ESPECTRE_DEVICE_LABEL_MAX_LENGTH = 32U
```

 

Matter Basic Information NodeLabel limit, shared by all Direct frontends.

   

<a id="namespaceespectre_1a44771ad0a8deef4590f951be92242be3"></a>

### `ESPECTRE_COMMAND_MAX_PAYLOAD_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_COMMAND_MAX_PAYLOAD_SIZE = 2048U
```

 

Maximum serialized command-request size accepted by every transport.

   

<a id="namespaceespectre_1a27be540efef19a111bae40cf08a98cfe"></a>

### `ESPECTRE_PROTOCOL_VERSION`


```cpp
constexpr const char* espectre::ESPECTRE_PROTOCOL_VERSION = "1.0"
```

 

Protocol version reported by capabilities and discovery.

   

<a id="namespaceespectre_1a28134da0cfd709e9903630c9a4e1ffcd"></a>

### `ESPECTRE_DNS_SD_TXT_SCHEMA_VERSION`


```cpp
constexpr const char* espectre::ESPECTRE_DNS_SD_TXT_SCHEMA_VERSION = "1"
```

 

DNS-SD TXT record schema advertised as the RFC 6763 `txtvers` value.

   

<a id="namespaceespectre_1aa9bcecab1d67487af0b736b8637b6138"></a>

### `ESPECTRE_COMMAND_ID_MAX_LENGTH`


```cpp
constexpr size_t espectre::ESPECTRE_COMMAND_ID_MAX_LENGTH = 64U
```

 

Maximum canonical command correlation identifier length.

   

<a id="namespaceespectre_1a26505654b6fa88f6cc3c9f86b64958e9"></a>

### `ESPECTRE_TOPIC_PREFIX`


```cpp
constexpr const char* espectre::ESPECTRE_TOPIC_PREFIX = "espectre/v1/devices"
```

 

Default MQTT topic root.

  

Override per device with [`EspectreDeviceConfig::topic_prefix`](#structespectre_1_1_espectre_device_config_1ae89cde8ec77492cd8dd8fb315206630f).

  

<a id="namespaceespectre_1a86c5bfd099c8fce0440c7bf8aab22d86"></a>

### `ESPECTRE_DEFAULT_DEVICE_ID`


```cpp
constexpr uint64_t espectre::ESPECTRE_DEFAULT_DEVICE_ID = 0U
```

 

Sentinel meaning "use the runtime-generated device id".

   

<a id="namespaceespectre_1a13bc6643d765f244dd767ad20084a3fd"></a>

### `ESPECTRE_DEFAULT_DEVICE_LABEL`


```cpp
constexpr const char* espectre::ESPECTRE_DEFAULT_DEVICE_LABEL = ""
```

 

Empty label, meaning the device id is used as the display name.

   

<a id="namespaceespectre_1a3bc81a65899ce7cc811b7897ea57bedb"></a>

### `ESPECTRE_DIRECT_HTTP_PORT`


```cpp
constexpr uint16_t espectre::ESPECTRE_DIRECT_HTTP_PORT = 0xF47BU
```

 

ESPectre service port: low 16 bits of U+1F47B GHOST (0xF47B).

   

<a id="namespaceespectre_1a9b21dc9879a1b2d70a1582f213c49a2b"></a>

### `ESPECTRE_DIRECT_HTTP_BASE_ENDPOINT`


```cpp
constexpr const char* espectre::ESPECTRE_DIRECT_HTTP_BASE_ENDPOINT = "/espectre/v1"
```

   

<a id="namespaceespectre_1a09e93416235f3d4fe07de4eee57db81f"></a>

### `ESPECTRE_DIRECT_HTTP_EVENTS_ENDPOINT`


```cpp
constexpr const char* espectre::ESPECTRE_DIRECT_HTTP_EVENTS_ENDPOINT = "/espectre/v1/events"
```

   

<a id="namespaceespectre_1a1c5ba9b3707b5eb96b6f3bab004fcfcd"></a>

### `ESPECTRE_DIRECT_HTTP_TRANSPORT`


```cpp
constexpr const char* espectre::ESPECTRE_DIRECT_HTTP_TRANSPORT = "http"
```

   

<a id="namespaceespectre_1adfc7361b80006da4cca67b96224221d9"></a>

### `ESPECTRE_DIRECT_MAX_REQUEST_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_DIRECT_MAX_REQUEST_SIZE = ESPECTRE_COMMAND_MAX_PAYLOAD_SIZE
```

   

<a id="namespaceespectre_1adb8f7243a68de4e7cd7ebad471875d51"></a>

### `ESPECTRE_DIRECT_MAX_RESPONSE_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_DIRECT_MAX_RESPONSE_SIZE = 8192U
```

   

<a id="namespaceespectre_1a90f09ac217de8fc9fe33fa72d0dca455"></a>

### `ESPECTRE_DIRECT_MAX_REQUEST_ID_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_DIRECT_MAX_REQUEST_ID_SIZE = ESPECTRE_COMMAND_ID_MAX_LENGTH
```

  

**Deprecated:** 

Use [`ESPECTRE_COMMAND_ID_MAX_LENGTH`](#namespaceespectre_1aa9bcecab1d67487af0b736b8637b6138); Direct uses the canonical limit.

  

<a id="namespaceespectre_1a53e26f01271bcce51eabeb7f765385a1"></a>

### `ESPECTRE_DIRECT_MAX_METHOD_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_DIRECT_MAX_METHOD_SIZE = 64U
```

  

**Deprecated:** 

Command names are validated by the canonical registry.

  

<a id="namespaceespectre_1a0480250c15d0e8b1a160fc5a825823bf"></a>

### `LIGHTWEIGHT_DEFAULT_THRESHOLD`


```cpp
constexpr float espectre::LIGHTWEIGHT_DEFAULT_THRESHOLD = 0.6621854538596202f
```

   

<a id="namespaceespectre_1ad5207970e48af47dc7eb1604269bdc58"></a>

### `LIGHTWEIGHT_MIN_THRESHOLD`


```cpp
constexpr float espectre::LIGHTWEIGHT_MIN_THRESHOLD = 0.0f
```

   

<a id="namespaceespectre_1ad092437163d2cdb5c5df9649cdd4c66d"></a>

### `LIGHTWEIGHT_MAX_THRESHOLD`


```cpp
constexpr float espectre::LIGHTWEIGHT_MAX_THRESHOLD = 1.0f
```

   

<a id="namespaceespectre_1a738158b5a07a1d20dd13553fefe9aba4"></a>

### `LIGHTWEIGHT_STARTUP_THRESHOLD_FACTOR`


```cpp
constexpr float espectre::LIGHTWEIGHT_STARTUP_THRESHOLD_FACTOR = 1.0f
```

   

<a id="namespaceespectre_1aa2efb98c798884ab306a6643c116b2a0"></a>

### `HIGH_ACCURACY_DEFAULT_THRESHOLD`


```cpp
constexpr float espectre::HIGH_ACCURACY_DEFAULT_THRESHOLD = 0.5f
```

   

<a id="namespaceespectre_1a9133aa008e101764566e0cb2742e7184"></a>

### `HIGH_ACCURACY_MIN_THRESHOLD`


```cpp
constexpr float espectre::HIGH_ACCURACY_MIN_THRESHOLD = 0.0f
```

   

<a id="namespaceespectre_1a8300aec6a3a88076cfd2a44a2aa1484e"></a>

### `HIGH_ACCURACY_MAX_THRESHOLD`


```cpp
constexpr float espectre::HIGH_ACCURACY_MAX_THRESHOLD = 1.0f
```

   

<a id="namespaceespectre_1af86772d17580cec4bfe57f8481c5c88c"></a>

### `HIGH_ACCURACY_METRIC_SCALE`


```cpp
constexpr float espectre::HIGH_ACCURACY_METRIC_SCALE = 1.0f
```

   

<a id="namespaceespectre_1ade1005795568ea8d80776ac6b6c222c8"></a>

### `LOWPASS_CUTOFF_DEFAULT`


```cpp
constexpr float espectre::LOWPASS_CUTOFF_DEFAULT = 11.0f
```

   

<a id="namespaceespectre_1aac038424c0e9b371ea394c5def3b5158"></a>

### `LOWPASS_CUTOFF_MIN`


```cpp
constexpr float espectre::LOWPASS_CUTOFF_MIN = 5.0f
```

   

<a id="namespaceespectre_1a4accb9aa168687b87a9c3b8202af831c"></a>

### `LOWPASS_CUTOFF_MAX`


```cpp
constexpr float espectre::LOWPASS_CUTOFF_MAX = 20.0f
```

   

<a id="namespaceespectre_1a71e1289119eb2029acb401ef6d5b0aec"></a>

### `LOWPASS_SAMPLE_RATE`


```cpp
constexpr float espectre::LOWPASS_SAMPLE_RATE = 100.0f
```

   

<a id="namespaceespectre_1a5cf095597de0a42f1bbe7f2838440b19"></a>

### `HAMPEL_TURBULENCE_WINDOW_MIN`


```cpp
constexpr uint8_t espectre::HAMPEL_TURBULENCE_WINDOW_MIN = 3U
```

   

<a id="namespaceespectre_1a43683e30117786c03a0f4d5a05bee629"></a>

### `HAMPEL_TURBULENCE_WINDOW_MAX`


```cpp
constexpr uint8_t espectre::HAMPEL_TURBULENCE_WINDOW_MAX = 11U
```

   

<a id="namespaceespectre_1a6014322636960da116aac379b07e896e"></a>

### `HAMPEL_TURBULENCE_WINDOW_DEFAULT`


```cpp
constexpr uint8_t espectre::HAMPEL_TURBULENCE_WINDOW_DEFAULT = 7U
```

   

<a id="namespaceespectre_1aaaab9e2cd7ff1dda6dccd548c48dfd97"></a>

### `HAMPEL_TURBULENCE_THRESHOLD_DEFAULT`


```cpp
constexpr float espectre::HAMPEL_TURBULENCE_THRESHOLD_DEFAULT = 5.0f
```

   

<a id="namespaceespectre_1a173e10371ac46c7dcb7e9fa395102541"></a>

### `HT20_NUM_SUBCARRIERS`


```cpp
constexpr uint16_t espectre::HT20_NUM_SUBCARRIERS = 64U
```

   

<a id="namespaceespectre_1ad7a70d37c99a12759ec87883d9bf5651"></a>

### `HT20_CSI_LEN`


```cpp
constexpr uint16_t espectre::HT20_CSI_LEN = 128U
```

   

<a id="namespaceespectre_1abc9115b9cb972953049e3dee66e7aa16"></a>

### `HT20_CSI_LEN_DOUBLE`


```cpp
constexpr uint16_t espectre::HT20_CSI_LEN_DOUBLE = 256U
```

   

<a id="namespaceespectre_1a95d2500724b3e1de4424ce0ec2dc4aae"></a>

### `HT20_CSI_LEN_SHORT`


```cpp
constexpr uint16_t espectre::HT20_CSI_LEN_SHORT = 114U
```

   

<a id="namespaceespectre_1aaa977261eaadbc6e80a6a9d0201b061d"></a>

### `LLTF20_CSI_LEN_SHORT`


```cpp
constexpr uint16_t espectre::LLTF20_CSI_LEN_SHORT = 106U
```

   

<a id="namespaceespectre_1a3807e5300bedcf7488f0db72003bab08"></a>

### `HT20_CSI_LEN_SHORT_DOUBLE`


```cpp
constexpr uint16_t espectre::HT20_CSI_LEN_SHORT_DOUBLE = 228U
```

   

<a id="namespaceespectre_1a591e14532ba43e92d1c5d222343a48f5"></a>

### `HT20_CSI_LEN_SHORT_LEFT_PAD`


```cpp
constexpr uint8_t espectre::HT20_CSI_LEN_SHORT_LEFT_PAD = 8U
```

   

<a id="namespaceespectre_1acd18a86eaa0c26991bb7007b43c0c653"></a>

### `HT20_GUARD_BAND_LOW`


```cpp
constexpr uint8_t espectre::HT20_GUARD_BAND_LOW = 4U
```

   

<a id="namespaceespectre_1ab563bdf9c7b5fc82fac271db91e70349"></a>

### `HT20_GUARD_BAND_HIGH`


```cpp
constexpr uint8_t espectre::HT20_GUARD_BAND_HIGH = 60U
```

   

<a id="namespaceespectre_1ae8f908725d3ea09ffe13d62ab0b3afbd"></a>

### `HT20_DC_SUBCARRIER`


```cpp
constexpr uint8_t espectre::HT20_DC_SUBCARRIER = 32U
```

   

<a id="namespaceespectre_1a634c531cce6a62b80e8e6b30cd9c68e2"></a>

### `HT20_SELECTED_BAND_SIZE`


```cpp
constexpr uint8_t espectre::HT20_SELECTED_BAND_SIZE = 12U
```

   

<a id="namespaceespectre_1ab5d5a6532e6d524fa4932baec3f9c86f"></a>

### `DEFAULT_SUBCARRIERS`


```cpp
constexpr uint8_t espectre::DEFAULT_SUBCARRIERS[HT20_SELECTED_BAND_SIZE][HT20_SELECTED_BAND_SIZE]                                              = {
    4U, 8U, 13U, 18U, 23U, 28U, 36U, 41U, 46U, 51U, 56U, 60U,
}
```

   

<a id="namespaceespectre_1af5dd9de9f8a533814ab31e3a9b488355"></a>

### `LIGHTWEIGHT_AUTOCORR_CENTER`


```cpp
constexpr float espectre::LIGHTWEIGHT_AUTOCORR_CENTER = 0.3919344866784947f
```

   

<a id="namespaceespectre_1ae572d68a06e48c1544396336d7c412aa"></a>

### `LIGHTWEIGHT_AUTOCORR_SCALE`


```cpp
constexpr float espectre::LIGHTWEIGHT_AUTOCORR_SCALE = 0.3798648330757351f
```

   

<a id="namespaceespectre_1a5e4947ea9b5684a8fbd155531a727666"></a>

### `LIGHTWEIGHT_AUTOCORR_WEIGHT`


```cpp
constexpr float espectre::LIGHTWEIGHT_AUTOCORR_WEIGHT = 5.083034533668216f
```

   

<a id="namespaceespectre_1aca6d5e503235ecac39b4e8ec723ba222"></a>

### `LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_CENTER`


```cpp
constexpr float espectre::LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_CENTER = 0.24612139211074338f
```

   

<a id="namespaceespectre_1a1b4a48f416593b0a97f723dc2f4def92"></a>

### `LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_SCALE`


```cpp
constexpr float espectre::LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_SCALE = 0.20056599613462603f
```

   

<a id="namespaceespectre_1a47e21f8dcc7a45f3a90efcbae0803d6e"></a>

### `LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_WEIGHT`


```cpp
constexpr float espectre::LIGHTWEIGHT_TURB_IQR_OVER_MEAN_AGGR_WEIGHT = 4.997501915217463f
```

   

<a id="namespaceespectre_1a183fb0399b6369183f9ee7b498d27379"></a>

### `LIGHTWEIGHT_INTERCEPT`


```cpp
constexpr float espectre::LIGHTWEIGHT_INTERCEPT = 1.0776769868761f
```

   

<a id="namespaceespectre_1ad874aec6dbb9e9e06005175f622a5d91"></a>

### `LIGHTWEIGHT_TRAIN_IDLE_Q95_LOGIT`


```cpp
constexpr float espectre::LIGHTWEIGHT_TRAIN_IDLE_Q95_LOGIT = -2.253902812716911f
```

   

<a id="namespaceespectre_1a8a8f6f5076e59d8c14e9b68b6b15d071"></a>

### `LIGHTWEIGHT_STARTUP_QUANTILE`


```cpp
constexpr float espectre::LIGHTWEIGHT_STARTUP_QUANTILE = 0.95f
```

   

<a id="namespaceespectre_1a46e2adfff54810a8e86d93dc6e0acf04"></a>

### `LIGHTWEIGHT_STARTUP_STRENGTH`


```cpp
constexpr float espectre::LIGHTWEIGHT_STARTUP_STRENGTH = 0.5f
```

   

<a id="namespaceespectre_1a453cecc04ac26e8ba1da62b5e55f36aa"></a>

### `LIGHTWEIGHT_STARTUP_SAMPLE_LIMIT`


```cpp
constexpr uint8_t espectre::LIGHTWEIGHT_STARTUP_SAMPLE_LIMIT = 64U
```

   

<a id="namespaceespectre_1a01b743a22c6a69557f80126341092991"></a>

### `LIGHTWEIGHT_SETTLE_BLOCKS`


```cpp
constexpr uint8_t espectre::LIGHTWEIGHT_SETTLE_BLOCKS = 12U
```

   

<a id="namespaceespectre_1ad4819b7e3ae66e4891815046b4675f7d"></a>

### `LIGHTWEIGHT_SETTLE_BLOCK_EVALUATIONS`


```cpp
constexpr uint8_t espectre::LIGHTWEIGHT_SETTLE_BLOCK_EVALUATIONS = 20U
```

   

<a id="namespaceespectre_1a54ab674f4c505a089ca14218b46b1fa1"></a>

### `LIGHTWEIGHT_SETTLE_MARGIN_LOGITS`


```cpp
constexpr float espectre::LIGHTWEIGHT_SETTLE_MARGIN_LOGITS = 2.7f
```

   

<a id="namespaceespectre_1a66fe1d687dfe9106731a7ed5e8136092"></a>

### `HT20_CLASSIC_ONLY_NULL_BINS`


```cpp
constexpr uint8_t espectre::HT20_CLASSIC_ONLY_NULL_BINS[][] = {29, 30, 31, 33, 34, 35}
```

   

<a id="namespaceespectre_1a460991f7f0cd4871fd1f338fc166b81c"></a>

### `HT20_CENTERED_ONLY_NULL_BINS`


```cpp
constexpr uint8_t espectre::HT20_CENTERED_ONLY_NULL_BINS[][] = {1, 2, 3, 61, 62, 63}
```

   

<a id="namespaceespectre_1a87ab0d558b48a21c390b13b6c153c68d"></a>

### `HT20_LLTF_MISSING_BINS`


```cpp
constexpr uint8_t espectre::HT20_LLTF_MISSING_BINS[][] = {4, 5, 59, 60}
```

   

<a id="namespaceespectre_1ad8f2e24e1681c31efcee0dc5e508af26"></a>

### `TEMPORAL_CSI_MICROSECONDS_PER_SECOND`


```cpp
constexpr uint32_t espectre::TEMPORAL_CSI_MICROSECONDS_PER_SECOND = 1000000U
```

   

<a id="namespaceespectre_1a2af3fbdcae0da1f75af14e8a39ab629c"></a>

### `TEMPORAL_CSI_MINIMUM_COVERAGE_NUMERATOR`


```cpp
constexpr uint8_t espectre::TEMPORAL_CSI_MINIMUM_COVERAGE_NUMERATOR = 7U
```

   

<a id="namespaceespectre_1aff60a06668015197e15387349e04bb3d"></a>

### `TEMPORAL_CSI_MINIMUM_COVERAGE_DENOMINATOR`


```cpp
constexpr uint8_t espectre::TEMPORAL_CSI_MINIMUM_COVERAGE_DENOMINATOR = 10U
```

   

<a id="namespaceespectre_1aa590854a8a59e96754371b7f35c4e48e"></a>

### `TEMPORAL_CSI_SLOT_HALF_DENOMINATOR`


```cpp
constexpr uint8_t espectre::TEMPORAL_CSI_SLOT_HALF_DENOMINATOR = 2U
```

   

<a id="namespaceespectre_1a8911611945c4d9384150e5a08552bda0"></a>

### `DETECTOR_WINDOW_SIZE_MS_MIN`


```cpp
constexpr uint32_t espectre::DETECTOR_WINDOW_SIZE_MS_MIN = 1000U
```

   

<a id="namespaceespectre_1a57fa4ae3e3020de3ce66fd00fd14b939"></a>

### `DETECTOR_WINDOW_SIZE_MS_MAX`


```cpp
constexpr uint32_t espectre::DETECTOR_WINDOW_SIZE_MS_MAX = 2000U
```

   

<a id="namespaceespectre_1a7f6cf82a5d4e26e53ee0f6b852dbabb2"></a>

### `DETECTOR_WINDOW_SIZE_MS_DEFAULT`


```cpp
constexpr uint32_t espectre::DETECTOR_WINDOW_SIZE_MS_DEFAULT = 1000U
```

   

<a id="namespaceespectre_1a292d263e8e374c65abb1c76af1121781"></a>

### `DETECTOR_DEFAULT_WINDOW_SIZE`


```cpp
constexpr uint16_t espectre::DETECTOR_DEFAULT_WINDOW_SIZE = 100
```

   

<a id="namespaceespectre_1af760f0ac7095300522fff6ea2edb6d7c"></a>

### `DETECTOR_MIN_WINDOW_SIZE`


```cpp
constexpr uint16_t espectre::DETECTOR_MIN_WINDOW_SIZE = 1
```

   

<a id="namespaceespectre_1ac7c47f062cc8d9adfd7881bd9fdbfdfb"></a>

### `DETECTOR_MAX_WINDOW_SIZE`


```cpp
constexpr uint16_t espectre::DETECTOR_MAX_WINDOW_SIZE = 1000
```

   

<a id="namespaceespectre_1aabc8a97ebb800fc8c97d279664c586eb"></a>

### `CALIBRATION_NUM_WINDOWS`


```cpp
constexpr uint16_t espectre::CALIBRATION_NUM_WINDOWS = 10
```

   

<a id="namespaceespectre_1aae96d7ab4eb211aac2c5f72d9b3a480c"></a>

### `CALIBRATION_DEFAULT_BUFFER_SIZE`


```cpp
constexpr uint16_t espectre::CALIBRATION_DEFAULT_BUFFER_SIZE                                                =
DETECTOR_DEFAULT_WINDOW_SIZE * CALIBRATION_NUM_WINDOWS
```

   

<a id="namespaceespectre_1ade89f4e051867c201a53266ca487bc00"></a>

### `EVALUATION_INTERVAL_US`


```cpp
constexpr uint32_t espectre::EVALUATION_INTERVAL_US = 250000U
```

   

<a id="namespaceespectre_1a24a334c3fa5dbbc227cf527faf402913"></a>

### `L1_DELTA_LAG_US`


```cpp
constexpr uint32_t espectre::L1_DELTA_LAG_US = 100000U
```

   

<a id="namespaceespectre_1ae59e57079a7c71da7ba4b2c9a87868b3"></a>

### `TURB_AUTOCORR_LAG_US`


```cpp
constexpr uint32_t espectre::TURB_AUTOCORR_LAG_US = 10000U
```

   

<a id="namespaceespectre_1abd53db5fbc189b5864021cac6914fb5c"></a>

### `DETECTOR_L1_DELTA_LAG_DEFAULT`


```cpp
constexpr uint16_t espectre::DETECTOR_L1_DELTA_LAG_DEFAULT = 10U
```

   

<a id="namespaceespectre_1adb267e831a03088b59bb2b2924af6027"></a>

### `DETECTOR_AUTOCORR_LAG_DEFAULT`


```cpp
constexpr uint16_t espectre::DETECTOR_AUTOCORR_LAG_DEFAULT = 1U
```

   

<a id="namespaceespectre_1a7864a488a9f0bc50ab7048258047247b"></a>

### `L1_DELTA_LAG_MAX`


```cpp
constexpr uint16_t espectre::L1_DELTA_LAG_MAX = 32
```

   

<a id="namespaceespectre_1a5eb2d1d16fb41389c7e99d23fc36759d"></a>

### `MIN_PLAUSIBLE_PACKET_INTERVAL_US`


```cpp
constexpr uint32_t espectre::MIN_PLAUSIBLE_PACKET_INTERVAL_US = 200U
```

   

<a id="namespaceespectre_1a0f6d2f2883521b8e46158775db275941"></a>

### `WIFI_TX_RATE_SETTING`


```cpp
constexpr std::string_view espectre::WIFI_TX_RATE_SETTING = CONFIG_ESPECTRE_WIFI_TX_RATE_MBPS
```

   

<a id="namespaceespectre_1ae52b924109160e5cfb0375c182bd6c1e"></a>

### `WIFI_TX_RATE_MBPS`


```cpp
constexpr float espectre::WIFI_TX_RATE_MBPS                               =
WIFI_TX_RATE_SETTING == "0" ? 0.0f :
WIFI_TX_RATE_SETTING == "6" ? 6.0f :
WIFI_TX_RATE_SETTING == "6.5" ? 6.5f : -1.0f
```

   

<a id="namespaceespectre_1ab83556ace9460431907c89a7cd641d44"></a>

### `WIFI_OFDM_TX_RATE`


```cpp
constexpr wifi_phy_rate_t espectre::WIFI_OFDM_TX_RATE = WIFI_PHY_RATE_6M
```

   

<a id="namespaceespectre_1a77be06c23411f6aa21db984fc53c419d"></a>

### `WIFI_STATION_TX_RATE`


```cpp
constexpr wifi_phy_rate_t espectre::WIFI_STATION_TX_RATE                                            =
WIFI_TX_RATE_MBPS == 6.5f ? WIFI_PHY_RATE_MCS0_LGI : WIFI_OFDM_TX_RATE
```

   

<a id="namespaceespectre_1ab18ef5b016f2a45b3e57911383e7a528"></a>

### `WIFI_CHANNEL_AUTO`


```cpp
constexpr int espectre::WIFI_CHANNEL_AUTO = 0
```

   

<a id="namespaceespectre_1ac6072079a5ee71395587ea95286469a8"></a>

### `WIFI_CHANNEL_2G_MAX`


```cpp
constexpr int espectre::WIFI_CHANNEL_2G_MAX = 14
```

   

<a id="namespaceespectre_1a859a9a7b26d35879fde75cdda7a32f85"></a>

### `kEspectreAsciiLogoLines`


```cpp
constexpr const char* espectre::kEspectreAsciiLogoLines[][]                                                     = {
    "  _____ ____  ____           __            ",
    " | ____/ ___||  _ \\ ___  ___| |_ _ __ ___ ",
    " |  _| \\___ \\| |_) / _ \\/ __| __| '__/ _ \\",
    " | |___ ___) |  __/  __/ (__| |_| | |  __/",
    " |_____|____/|_|   \\___|\\___|\\__|_|  \\___|",
}
```

   

<a id="namespaceespectre_1abc7070382b2620aad729f294d9f00e8d"></a>

### `ESPECTRE_PEER_DISCOVERY_TIMEOUT_MS`


```cpp
constexpr uint32_t espectre::ESPECTRE_PEER_DISCOVERY_TIMEOUT_MS = 3000U
```

   

<a id="namespaceespectre_1a1eb28ce7d48bbb1551343b78c62eb44a"></a>

### `ESPECTRE_PEER_DISCOVERY_MAX_DEVICES`


```cpp
constexpr size_t espectre::ESPECTRE_PEER_DISCOVERY_MAX_DEVICES = 8U
```

   

<a id="namespaceespectre_1a763c9fa6ba6bfe96f1f5d73d2f1eb1ce"></a>

### `ESPECTRE_PEER_DISCOVERY_MAX_ADDRESSES`


```cpp
constexpr size_t espectre::ESPECTRE_PEER_DISCOVERY_MAX_ADDRESSES = 2U
```

   

<a id="namespaceespectre_1a0ab265cc384a2f5d3c4b58f335984291"></a>

### `ESPECTRE_PEER_DISCOVERY_MAX_RESULT_SIZE`


```cpp
constexpr size_t espectre::ESPECTRE_PEER_DISCOVERY_MAX_RESULT_SIZE = 3584U
```

   


<a id="namespaceespectre_1a35ddf262655083501dcdf68b4d934ac0"></a>

### `espectre_sdk_version`


```cpp
constexpr const char * espectre::espectre_sdk_version()
```

 

The SDK version as a string, usable where a macro is not.

  

**Returns:** [`ESPECTRE_SDK_VERSION_STRING`](#espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74), or `"0.0.0"` when unknown. Never null; valid for the process lifetime.

  

<a id="namespaceespectre_1a739067c18cf8673bbc45564cd2a29f2b"></a>

### `runtime_operation_state_name`


```cpp
const char * espectre::runtime_operation_state_name(RuntimeOperationState state)
```

   

<a id="namespaceespectre_1adf6bece0a78ea38870c47f1f721ac096"></a>

### `csi_capture_profile_name`


```cpp
constexpr const char * espectre::csi_capture_profile_name(CsiCaptureProfile profile)
```

   

<a id="namespaceespectre_1a2d1b08a1daef9612d8f797d055f1d84f"></a>

### `csi_capture_profile_uses_lltf`


```cpp
constexpr bool espectre::csi_capture_profile_uses_lltf(CsiCaptureProfile profile)
```

   

<a id="namespaceespectre_1ab673d1c40a3ffe2f300776a1501b1131"></a>

### `resolve_csi_capture_profile`


```cpp
constexpr CsiCaptureProfile espectre::resolve_csi_capture_profile(bool prefers_lltf20, bool supports_vht20, uint8_t wifi_channel, CsiCapturePolicy requested=CsiCapturePolicy::AUTO)
```

 

Resolve the configured capture policy from target capabilities and link channel.

   

<a id="namespaceespectre_1afe16dc0f8dcdb90f8c11b66b03233a35"></a>

### `runtime_threshold_max`


```cpp
constexpr float espectre::runtime_threshold_max(DetectionAlgorithm algorithm)
```

   

<a id="namespaceespectre_1ac2918b7136144625515b36b675d28ee5"></a>

### `runtime_detection_algorithm_valid`


```cpp
constexpr bool espectre::runtime_detection_algorithm_valid(DetectionAlgorithm algorithm)
```

   

<a id="namespaceespectre_1ac03ffc8152503ebb7c6bcc497a321ae0"></a>

### `runtime_profile_valid`


```cpp
constexpr bool espectre::runtime_profile_valid(RuntimeProfile profile)
```

   

<a id="namespaceespectre_1a85d8ed0f40066f023fa0788465641f8f"></a>

### `runtime_traffic_mode_valid`


```cpp
constexpr bool espectre::runtime_traffic_mode_valid(RuntimeTrafficMode mode)
```

   

<a id="namespaceespectre_1ad99eba7f2b5a38c9818a6203463e5767"></a>

### `runtime_csi_traffic_mode_valid`


```cpp
constexpr bool espectre::runtime_csi_traffic_mode_valid(CsiTrafficMode mode)
```

   

<a id="namespaceespectre_1a42a408fb181170f0dc6c93041c6faeaf"></a>

### `runtime_csi_traffic_mode_valid_for_profile`


```cpp
constexpr bool espectre::runtime_csi_traffic_mode_valid_for_profile(RuntimeProfile profile, CsiTrafficMode mode)
```

   

<a id="namespaceespectre_1a7ebccf5d9764673ec697cac7c059b6f9"></a>

### `runtime_default_threshold`


```cpp
constexpr float espectre::runtime_default_threshold(DetectionAlgorithm algorithm)
```

   

<a id="namespaceespectre_1ae40d935f9a093b8daca17290196df3fa"></a>

### `validate_runtime_threshold`


```cpp
bool espectre::validate_runtime_threshold(float threshold)
```

   

<a id="namespaceespectre_1a662ded5428c534fcee07d8886852da0a"></a>

### `validate_runtime_threshold_for_algorithm`


```cpp
bool espectre::validate_runtime_threshold_for_algorithm(float threshold, DetectionAlgorithm algorithm)
```

   

<a id="namespaceespectre_1a89e30bf889f6ecffe4b628b5b6555243"></a>

### `validate_runtime_float`


```cpp
bool espectre::validate_runtime_float(float value, float min_value, float max_value)
```

   

<a id="namespaceespectre_1a60505f14742f122e69f348acae5994be"></a>

### `validate_runtime_uint32`


```cpp
bool espectre::validate_runtime_uint32(uint32_t value, uint32_t min_value, uint32_t max_value)
```

   

<a id="namespaceespectre_1aa4961454dfc0b34191907f73e9cdefaa"></a>

### `validate_runtime_uint8`


```cpp
bool espectre::validate_runtime_uint8(uint8_t value, uint8_t min_value, uint8_t max_value)
```

   

<a id="namespaceespectre_1ac488c89e66dd60728b32b7254385904e"></a>

### `runtime_traffic_mode_supported`


```cpp
bool espectre::runtime_traffic_mode_supported(RuntimeTrafficMode mode)
```

 

Whether this build target supports the internal traffic source; host builds accept every valid mode.

   

<a id="namespaceespectre_1affbe2d9c493450276e7cca8b95ff5a64"></a>

### `runtime_capture_profile_supports_traffic`


```cpp
bool espectre::runtime_capture_profile_supports_traffic(CsiCapturePolicy profile, RuntimeTrafficMode mode)
```

 

Whether a configured CSI profile can be combined with the internal source.

   

<a id="namespaceespectre_1a3204487b096871eb46f055d2a8088907"></a>

### `validate_runtime_config`


```cpp
RuntimeConfigError espectre::validate_runtime_config(const RuntimeConfig &config)
```

 

Validate the complete configuration before creating runtime state.

   

<a id="namespaceespectre_1a464f8d16630630601b5136ed82097b34"></a>

### `runtime_config_error_message`


```cpp
const char * espectre::runtime_config_error_message(RuntimeConfigError error)
```

 

Stable diagnostic label for a configuration error.

  

Never returns `nullptr`.

  

<a id="namespaceespectre_1a87461d595b73c9764e020c3ecd7eea14"></a>

### `runtime_traffic_target_addr`


```cpp
uint32_t espectre::runtime_traffic_target_addr(const RuntimeConfig &config, uint32_t gateway_addr)
```

 

Resolve the internal traffic destination in network byte order; empty uses the gateway, and invalid IPv4 returns zero.

   

<a id="namespaceespectre_1a9725ce3833039319e55002a4dd2f51f9"></a>

### `runtime_profile_name`


```cpp
const char * espectre::runtime_profile_name(RuntimeProfile profile)
```

   

<a id="namespaceespectre_1a988bb4b92b7b0de94be5d39ea3083d2f"></a>

### `wifi_band_policy_name`


```cpp
const char * espectre::wifi_band_policy_name(WifiBandPolicy policy)
```

   

<a id="namespaceespectre_1a0223efacde0d99454b7fa5a4635d739b"></a>

### `traffic_mode_name`


```cpp
const char * espectre::traffic_mode_name(RuntimeTrafficMode mode)
```

   

<a id="namespaceespectre_1adb6a5eee226c7f0924be378f705a37e7"></a>

### `csi_traffic_mode_name`


```cpp
const char * espectre::csi_traffic_mode_name(CsiTrafficMode mode)
```

   

<a id="namespaceespectre_1ad743fa11bd056d3da272e85611bc4cf0"></a>

### `csi_traffic_mode_is_sensing_control`


```cpp
bool espectre::csi_traffic_mode_is_sensing_control(CsiTrafficMode mode)
```

   

<a id="namespaceespectre_1aeddc7c77a658e90373a22ac483816343"></a>

### `normalize_sensing_csi_traffic_mode`


```cpp
CsiTrafficMode espectre::normalize_sensing_csi_traffic_mode(CsiTrafficMode mode)
```

   

<a id="namespaceespectre_1a00b12f22b91595a0e1c0fa56be36753d"></a>

### `detection_algorithm_name`


```cpp
const char * espectre::detection_algorithm_name(DetectionAlgorithm algorithm)
```

   

<a id="namespaceespectre_1aaea114f80858324c0deee3c6be0ef930"></a>

### `subcarrier_source_name`


```cpp
const char * espectre::subcarrier_source_name(RuntimeSubcarrierSource source)
```

   

<a id="namespaceespectre_1af9f8ba3414ad71912c40644b68d4070d"></a>

### `parse_traffic_mode`


```cpp
RuntimeTrafficMode espectre::parse_traffic_mode(const char *mode)
```

   

<a id="namespaceespectre_1a3bc1eb230ccf5718347382802fe3adf2"></a>

### `parse_csi_traffic_mode`


```cpp
CsiTrafficMode espectre::parse_csi_traffic_mode(const char *mode)
```

   

<a id="namespaceespectre_1a58cce43945e826bdfe8db0e85cd5732c"></a>

### `parse_detection_algorithm`


```cpp
DetectionAlgorithm espectre::parse_detection_algorithm(const char *algorithm)
```

   

<a id="namespaceespectre_1a21438506ac935cbc46862e5166c3d1eb"></a>

### `parse_wifi_band_policy`


```cpp
WifiBandPolicy espectre::parse_wifi_band_policy(const char *policy)
```

   

<a id="namespaceespectre_1abd3ea9004c3b96e776f0def128c64696"></a>

### `make_runtime_sensing_config`


```cpp
RuntimeConfig espectre::make_runtime_sensing_config()
```

   

<a id="namespaceespectre_1aec161d888273753b9117d92eb3273246"></a>

### `append_runtime_csi_quality_diagnostics_json`


```cpp
void espectre::append_runtime_csi_quality_diagnostics_json(std::string *out, const RuntimeDiagnosticsSnapshot &diagnostics)
```

 

Append capture-quality counters to an already opened JSON object.

   

<a id="namespaceespectre_1a43f43b5fa48477941d70036166ca22c1"></a>

### `append_runtime_performance_diagnostics_json`


```cpp
void espectre::append_runtime_performance_diagnostics_json(std::string *out, const RuntimeDiagnosticsSnapshot &diagnostics, bool include_current_memory=true)
```

 

Append shared platform and performance fields to an existing JSON object.

  

The object must already contain at least one field. Metrics from an incomplete aggregation window are emitted as `null`; unsupported detector timing is identified separately by `detection_timing_supported`.

  

<a id="namespaceespectre_1ac4f7c5525911cb19bac3f714d29ed3ae"></a>

### `validate_diagnostic_fields`


```cpp
bool espectre::validate_diagnostic_fields(const std::vector< std::string > &fields, unsigned profile=7U)
```

 

Validate diagnostic paths, groups, or an exclusive wildcard against the canonical registry.

   

<a id="namespaceespectre_1abdb85601916430789d63639f7708ff4a"></a>

### `diagnostic_response`


```cpp
std::string espectre::diagnostic_response(const std::vector< std::string > &fields, unsigned profile, const std::function< std::string(const char *)> &value)
```

 

Serialize the catalog without reading values, or only selected values from the supplied provider.

  

Profiles are Native=1, shared Direct bridge=2, and Micro=4. Empty selections return the catalog. The provider returns one JSON scalar. Unknown profile fields produce an empty response.

  

<a id="namespaceespectre_1ad8e4b0d6a83b94536fa09d8cc9aacc67"></a>

### `runtime_diagnostic_value`


```cpp
std::string espectre::runtime_diagnostic_value(const char *key, const RuntimeDiagnosticsSample *sample, const std::function< const RuntimeDiagnosticsSnapshot &()> &snapshot)
```

 

Read a shared scalar from a cached rate sample or a lazily acquired runtime snapshot.

   

<a id="namespaceespectre_1a76b766e8ac9d031f559be00ab17b315b"></a>

### `visit_runtime_diagnostics`


```cpp
void espectre::visit_runtime_diagnostics(const RuntimeConfig &config, const RuntimeSnapshot &snapshot, runtime_diagnostic_visitor_t visitor)
```

   

<a id="namespaceespectre_1a79c04e29909488dd8aae7ee4df04c124"></a>

### `validate_protocol_extension`


```cpp
bool espectre::validate_protocol_extension(const EspectreProtocolExtension &extension, std::string *error=nullptr)
```

 

Reject malformed descriptors and collisions with the SDK or another extension entry.

   

<a id="namespaceespectre_1a042b26831152547bc29a3a8cedd7e5d7"></a>

### `find_extension_route`


```cpp
const EspectreExtensionRoute * espectre::find_extension_route(const EspectreProtocolExtension *extension, const std::string &command)
```

 

Find a command in a valid extension; a null or invalid extension has no routes.

   

<a id="namespaceespectre_1a1f22c8af7f655d2ab62a805f5827bcec"></a>

### `espectre_api_routes`


```cpp
const EspectreApiRoute * espectre::espectre_api_routes(size_t *count)
```

 

Return the immutable v1 resource registry and its entry count.

   

<a id="namespaceespectre_1ad369de74fc2722fa68d76a20e9277e43"></a>

### `espectre_api_events`


```cpp
const EspectreApiEventDescriptor * espectre::espectre_api_events(size_t *count)
```

   

<a id="namespaceespectre_1a64b54752d746f722b1176a3fe995caef"></a>

### `append_json_string`


```cpp
void espectre::append_json_string(std::string *out, const char *value)
```

   

<a id="namespaceespectre_1a4c1693617d0914f60a81ced263a8fb72"></a>

### `append_json_pair`


```cpp
void espectre::append_json_pair(std::string *out, const char *key, const char *value, bool first=false)
```

   

<a id="namespaceespectre_1a3e05f93260fcedb1a0f010c52825ac67"></a>

### `has_json_key`


```cpp
bool espectre::has_json_key(const std::string &payload, const char *key)
```

   

<a id="namespaceespectre_1ada7befc8e455d080569e41b4072dffa6"></a>

### `extract_json_string`


```cpp
std::string espectre::extract_json_string(const std::string &payload, const char *key)
```

   

<a id="namespaceespectre_1ac22e051693ae366770a862f8ae6511de"></a>

### `extract_json_number_token`


```cpp
std::string espectre::extract_json_number_token(const std::string &payload, const char *key)
```

   

<a id="namespaceespectre_1ad94497c9202bbf4d01870ca2e7ce5dd1"></a>

### `decode_urlencoded_component`


```cpp
bool espectre::decode_urlencoded_component(const std::string &encoded, std::string *decoded, std::string *error=nullptr)
```

   

<a id="namespaceespectre_1ae9a669e530c21661ba4bf329fc86927d"></a>

### `encode_urlencoded_component`


```cpp
std::string espectre::encode_urlencoded_component(const std::string &value)
```

   

<a id="namespaceespectre_1a6089f509e536788cce4984fc7569bf9a"></a>

### `parse_urlencoded_key_value_pairs`


```cpp
bool espectre::parse_urlencoded_key_value_pairs(const std::string &payload, std::vector< std::pair< std::string, std::string > > *pairs, std::string *error=nullptr)
```

   

<a id="namespaceespectre_1a20e153bb946d91e4aae1899f1c26586b"></a>

### `parse_json_object_fields`


```cpp
bool espectre::parse_json_object_fields(const std::string &payload, std::vector< JsonObjectField > *fields, std::string *error=nullptr)
```

 

Parse and validate one complete JSON object, rejecting duplicate field names.

   

<a id="namespaceespectre_1ab8ee058514ade62ed06d26edd5ad5e72"></a>

### `parse_json_array_objects`


```cpp
bool espectre::parse_json_array_objects(const std::string &payload, std::vector< std::vector< JsonObjectField > > *objects, std::string *error=nullptr)
```

 

Parse a complete array of objects, rejecting invalid or non-object entries.

   

<a id="namespaceespectre_1ac9e20ff827dae90b16db7b332fa4dc19"></a>

### `parse_json_array_strings`


```cpp
bool espectre::parse_json_array_strings(const std::string &payload, std::vector< std::string > *strings, std::string *error=nullptr)
```

 

Parse a complete array containing only JSON strings.

   

<a id="namespaceespectre_1ae7d7210fe0bec5db1ba8ad2face750b2"></a>

### `find_json_object_field`


```cpp
const JsonObjectField * espectre::find_json_object_field(const std::vector< JsonObjectField > &fields, const char *name)
```

   

<a id="namespaceespectre_1a138e724fbe594802da86d2961939cd7f"></a>

### `parse_direct_http_request`


```cpp
bool espectre::parse_direct_http_request(const std::string &http_method, const std::string &path, const std::string &payload, DirectRequest *request, std::string *error=nullptr, const EspectreProtocolExtension *extension=nullptr)
```

   

<a id="namespaceespectre_1abcacfcd112472bfc62c59a502f647ceb"></a>

### `direct_http_request_to_command`


```cpp
bool espectre::direct_http_request_to_command(const DirectRequest &request, EspectreCommand *command, std::string *error=nullptr, const EspectreProtocolExtension *extension=nullptr)
```

   

<a id="namespaceespectre_1a5509432cbeaff50ecf7e2b7d5ace8bd9"></a>

### `espectre_transport_mapping_payload`


```cpp
std::string espectre::espectre_transport_mapping_payload()
```

 

Executable Direct/MQTT mapping owned and tested by C++.

   

<a id="namespaceespectre_1ac57dce35f8b2fdb1cdfe072f3f4feb14"></a>

### `espectre_protocol_catalog_payload`


```cpp
std::string espectre::espectre_protocol_catalog_payload(const EspectreProtocolExtension *extension=nullptr)
```

 

Combined message-model and transport-mapping catalog for protocol inspection.

   

<a id="namespaceespectre_1a34031a60d78bbb6306047b3540b4f905"></a>

### `derive_runtime_device_id`


```cpp
uint64_t espectre::derive_runtime_device_id()
```

 

Return the cached 64-bit SHA-256 pseudonym derived from the station MAC.

   

<a id="namespaceespectre_1a0f5171c004f18f155e1cd453c8eb4801"></a>

### `derive_runtime_device_id_string`


```cpp
std::string espectre::derive_runtime_device_id_string()
```

 

Return the cached canonical text for [`derive_runtime_device_id()`](#namespaceespectre_1a34031a60d78bbb6306047b3540b4f905).

   

<a id="namespaceespectre_1ab070877204ffb133b519d0b163420df6"></a>

### `make_runtime_sensing_config_from_kconfig`


```cpp
RuntimeConfig espectre::make_runtime_sensing_config_from_kconfig()
```

 

Build a [`RuntimeConfig`](#structespectre_1_1_runtime_config) from the `ESPECTRE_*` menuconfig options.

  

This is the ergonomic path on ESP-IDF: expose the sensing settings in menuconfig, call this at boot, and override only the fields your product computes at runtime.

 

```cpp
espectre::RuntimeConfig config = espectre::make_runtime_sensing_config_from_kconfig();
config.device_id = my_device_id();
controller.set_config(config);
```

 

Every value is range-checked against the schema in [`runtime_sensing_schema.h`](#runtime__sensing__schema_8h). An out-of-range or unparseable option falls back to the documented default and logs a warning rather than failing the boot, so a bad `sdkconfig` degrades instead of bricking the device.

 

Options absent from the build, for instance when the SDK Kconfig is not sourced, compile to their defaults. Fields with no Kconfig option, such as `device_id` and the stream settings, keep their [`RuntimeConfig`](#structespectre_1_1_runtime_config) defaults.

 

**Returns:** A validated configuration, ready for [`RuntimeFrontendController::set_config()`](#classespectre_1_1_runtime_frontend_controller_1a6bc5d2dea03c406e822c0fc917e54840).

  

<a id="namespaceespectre_1a4ce213aabcd22d32aa6f62e83a2bda1e"></a>

### `set_log_sink`


```cpp
bool espectre::set_log_sink(const LogSink &sink)
```

 

Register a complete frontend logging sink.

  

Registration must happen before runtime setup, and replacement is supported only while no ESPectre runtime is active. An invalid sink leaves the current registration unchanged.

 

**Parameters**

- `sink`: Callback value copied by ESPectre.

 

**Returns:** `true` when both required callbacks were registered.

  

<a id="namespaceespectre_1a61ab03223d965fdc086b55a8527ed204"></a>

### `clear_log_sink`


```cpp
void espectre::clear_log_sink()
```

 

Clear the current sink while no ESPectre runtime is active.

   

<a id="namespaceespectre_1aceb53f160132829964a6b4d69347ed4e"></a>

### `log_enabled`


```cpp
bool espectre::log_enabled(LogLevel level, const char *tag)
```

 

Return whether the current sink accepts one level and tag.

  

**Parameters**

- `level`: Message severity.
- `tag`: Stable logger tag.

 

**Returns:** `false` when no complete sink is registered or the sink filters the message.

  

<a id="namespaceespectre_1a09a51380aebbfbfacbb14b51c7604653"></a>

### `make_default_subcarriers`


```cpp
constexpr SelectedSubcarriers espectre::make_default_subcarriers()
```

   

<a id="namespaceespectre_1a6bd20096271ae7a56b205e06ac9c7e86"></a>

### `ht20_bins_with_energy`


```cpp
uint8_t espectre::ht20_bins_with_energy(const int8_t *csi_data, const uint8_t *bins, uint8_t count, bool first_word_invalid=false)
```

   

<a id="namespaceespectre_1a7d1d5b5cec71e45a58dfc64c0ba441cd"></a>

### `detect_ht20_bin_layout`


```cpp
Ht20BinLayout espectre::detect_ht20_bin_layout(const int8_t *csi_data, size_t csi_len, bool first_word_invalid=false)
```

 

Identify which HT20 bin ordering a 64-subcarrier payload uses.

  

Requires positive evidence in both directions: one guard set must be entirely null and the other entirely populated. Absence of energy alone is not enough, because a sparse or degenerate payload is null under both conventions.

 

**Parameters**

- `csi_data`: Raw CSI payload (interleaved I/Q pairs)
- `csi_len`: Payload length in bytes (must be HT20\_CSI\_LEN)
- `first_word_invalid`: Ignore the two hardware-invalid source pairs

 

**Returns:** The detected layout, or UNKNOWN when the evidence is inconclusive

  

<a id="namespaceespectre_1ad95f5d8710d3ea0b07337e581593c63e"></a>

### `zero_ht20_lltf_missing_bins`


```cpp
bool espectre::zero_ht20_lltf_missing_bins(int8_t *csi_data, size_t csi_len)
```

 

Mark LLTF's unavailable edge tones as missing in a normalized raw view.

  

**Parameters**

- `csi_data`: Centered, interleaved I/Q HT20 payload to update in place.
- `csi_len`: Payload length in bytes; must equal HT20\_CSI\_LEN.

 

**Returns:** true when the payload was updated, or false for invalid input.

  

<a id="namespaceespectre_1a56a1f68a4399f8754598fe6aa6c86a09"></a>

### `prepare_ht20_detector_input`


```cpp
bool espectre::prepare_ht20_detector_input(int8_t *csi_data, size_t csi_len, bool lltf, bool first_word_invalid=false, Ht20BinLayout source_layout=Ht20BinLayout::UNKNOWN)
```

 

Prepare a private centered detector buffer from normalized raw CSI.

  

Fill LLTF edge tones from -26/+26 and hardware-invalid classic +1 from +2. Source metadata, never a zero value, selects the latter. DC and guards stay unchanged. Call only on a private detector buffer, after raw delivery splits.

 

**Parameters**

- `csi_data`: Private centered, interleaved I/Q HT20 buffer to update.
- `csi_len`: Payload length in bytes; must equal HT20\_CSI\_LEN.
- `lltf`: Whether the capture profile lacks the LLTF edge tones.
- `first_word_invalid`: Whether the first four source bytes were invalid.
- `source_layout`: Original source ordering, before centered normalization.

 

**Returns:** true for a prepared buffer, or false for invalid input or unknown ordering of a flagged source; invalid input is not modified.

  

<a id="namespaceespectre_1ab70480c9cd9d9a706a1777486c4d073d"></a>

### `impute_ht20_lltf_detector_bins`


```cpp
bool espectre::impute_ht20_lltf_detector_bins(int8_t *csi_data, size_t csi_len)
```

 

Prepare the legacy LLTF-only detector view in a private buffer.

   

<a id="namespaceespectre_1a8e38da349464d03ae50a403cab4f977a"></a>

### `rotate_ht20_classic_to_centered`


```cpp
void espectre::rotate_ht20_classic_to_centered(const int8_t *csi_data, int8_t *out)
```

 

Rotate a classic-order HT20 payload into the centered convention.

  

Rotating by half the FFT size is its own inverse, so one swap of the payload halves maps `0~31, -32~-1` onto `-32~+31`.

 

**Parameters**

- `csi_data`: Source payload of HT20\_CSI\_LEN bytes
- `out`: Destination buffer of HT20\_CSI\_LEN bytes (must not alias the source)

  

<a id="namespaceespectre_1a20a50c9af4bbb66528f0c0491e92b3e8"></a>

### `calculate_spatial_turbulence`


```cpp
float espectre::calculate_spatial_turbulence(const float *magnitudes, const uint8_t *subcarriers, uint8_t num_subcarriers, uint16_t max_subcarrier=64)
```

 

Calculate spatial turbulence from pre-calculated magnitudes.

  

Spatial turbulence is the standard deviation of magnitudes across selected subcarriers. It measures the spatial variability of the Wi-Fi channel - higher values indicate motion/disturbance.

 

**Parameters**

- `magnitudes`: Array of magnitude values (one per subcarrier)
- `subcarriers`: Array of selected subcarrier indices
- `num_subcarriers`: Number of selected subcarriers (max 12)
- `max_subcarrier`: Maximum valid subcarrier index (default: 64 for HT20)

 

**Returns:** Turbulence value

  

<a id="namespaceespectre_1ae28970c57767d93ae75b3410225d51b1"></a>

### `extract_subcarrier_amplitudes`


```cpp
uint8_t espectre::extract_subcarrier_amplitudes(const int8_t *csi_data, size_t csi_len, const uint8_t *subcarriers, uint8_t num_subcarriers, float *out, uint8_t out_capacity)
```

 

Extract subcarrier amplitudes from raw CSI data (I/Q pairs).

  

Mirrors the Python `SegmentationContext._fill_amplitude_buffer` helper.

 

**Parameters**

- `csi_data`: Raw CSI data (interleaved I/Q pairs, Espressif format)
- `csi_len`: Length of CSI data in bytes
- `subcarriers`: Array of selected subcarrier indices
- `num_subcarriers`: Number of selected subcarriers
- `out`: Output amplitude buffer
- `out_capacity`: Capacity of the output buffer

 

**Returns:** Number of amplitudes written

  

<a id="namespaceespectre_1ac837a8b05d79f7e5e2b3978ab2791fb8"></a>

### `extract_packet_subcarrier_amplitudes`


```cpp
uint8_t espectre::extract_packet_subcarrier_amplitudes(const int8_t *csi_data, size_t csi_len, float *out, uint8_t out_capacity)
```

 

Extract one packet-wide amplitude frame for reuse by multiple feature paths.

   

<a id="namespaceespectre_1a5a120acf2ff3297fe7d5658e12e79a25"></a>

### `fill_packet_subcarrier_energies`


```cpp
uint8_t espectre::fill_packet_subcarrier_energies(const int8_t *csi_data, size_t csi_len, float *out, uint8_t out_capacity)
```

 

Fill one packet-wide squared-magnitude frame for energy-domain consumers.

   

<a id="namespaceespectre_1a9d29e561f008ffa26b8d57f46f6e1ca5"></a>

### `energies_to_amplitudes_in_place`


```cpp
void espectre::energies_to_amplitudes_in_place(float *values, uint8_t count)
```

   

<a id="namespaceespectre_1a7ee2f120717498da48852634a0db88ca"></a>

### `select_subcarrier_amplitudes`


```cpp
uint8_t espectre::select_subcarrier_amplitudes(const float *packet_amplitudes, uint8_t packet_count, const uint8_t *subcarriers, uint8_t num_subcarriers, float *out, uint8_t out_capacity)
```

 

Select the configured tones from a packet-wide amplitude frame.

   

<a id="namespaceespectre_1a15c3caa66a486b64ea5b4baa16f6c9fc"></a>

### `select_adjacent_aggregated_subcarrier_amplitudes`


```cpp
uint8_t espectre::select_adjacent_aggregated_subcarrier_amplitudes(const float *packet_amplitudes, uint8_t packet_count, const uint8_t *subcarriers, uint8_t num_subcarriers, uint8_t width, float *out, uint8_t out_capacity)
```

 

Select adjacent-bin mean amplitudes from a packet-wide amplitude frame.

   

<a id="namespaceespectre_1ab089846cad43726fc4d5ee80271586e3"></a>

### `extract_adjacent_aggregated_subcarrier_amplitudes`


```cpp
uint8_t espectre::extract_adjacent_aggregated_subcarrier_amplitudes(const int8_t *csi_data, size_t csi_len, const uint8_t *subcarriers, uint8_t num_subcarriers, uint8_t width, float *out, uint8_t out_capacity)
```

 

Extract one mean magnitude per selected tone from adjacent live HT20 bins.

  

Windows are clamped to bins 4..60 and skip the DC null at bin 32. This is the production counterpart of `SegmentationContext._fill_adjacent_aggregated_amplitude_buffer`.

  

<a id="namespaceespectre_1a56c215b39ccf2e01b773e922a484459b"></a>

### `calculate_spatial_turbulence_from_amplitudes`


```cpp
float espectre::calculate_spatial_turbulence_from_amplitudes(const float *amplitudes, uint8_t count)
```

   

<a id="namespaceespectre_1a2dc522f2419538854cf164ca24220b66"></a>

### `calculate_spatial_turbulence_from_csi`


```cpp
float espectre::calculate_spatial_turbulence_from_csi(const int8_t *csi_data, size_t csi_len, const uint8_t *subcarriers, uint8_t num_subcarriers)
```

 

Calculate spatial turbulence directly from raw CSI data (I/Q pairs).

  

This is a convenience wrapper that calculates magnitudes internally before computing spatial turbulence.

 

HT20 only: 64 subcarriers, 128 bytes CSI data.

 

**Parameters**

- `csi_data`: Raw CSI data (interleaved I/Q pairs)
- `csi_len`: Length of CSI data in bytes (expected: 128 for HT20)
- `subcarriers`: Array of selected subcarrier indices
- `num_subcarriers`: Number of selected subcarriers (max 12)

 

**Returns:** Turbulence value

  

<a id="namespaceespectre_1aaec036cc9ad204a6e3fc1abd72d00ef9"></a>

### `temporal_window_slots`


```cpp
uint32_t espectre::temporal_window_slots(uint32_t target_pps, uint32_t window_size_ms)
```

 

Return the fixed-grid slot count for a target rate and window duration.

   

<a id="namespaceespectre_1a06e0cbe94d9c977e8c5f7d7976890d0d"></a>

### `temporal_minimum_valid_slots`


```cpp
uint32_t espectre::temporal_minimum_valid_slots(uint32_t window_slots)
```

 

Return the minimum occupied slots required for a ready window.

   

<a id="namespaceespectre_1a8a21858a93018db73d09ee475c20e11c"></a>

### `temporal_minimum_sample_spacing_us`


```cpp
uint32_t espectre::temporal_minimum_sample_spacing_us(uint32_t target_pps)
```

 

Return the minimum spacing between selected candidates at a target rate.

   

<a id="namespaceespectre_1a2cf603b44b19bbfa3bb19e238387e886"></a>

### `load_stored_wifi_config`


```cpp
esp_err_t espectre::load_stored_wifi_config(StoredWifiConfig *config)
```

   

<a id="namespaceespectre_1aedba313a714d86f0c2f5e4c27e930c26"></a>

### `save_stored_wifi_config`


```cpp
esp_err_t espectre::save_stored_wifi_config(const StoredWifiConfig &config)
```

   

<a id="namespaceespectre_1a748cc12e82891ff8357c5400ddeba8be"></a>

### `clear_stored_wifi_config`


```cpp
esp_err_t espectre::clear_stored_wifi_config()
```

   

<a id="namespaceespectre_1a0b38592b6457d7241bf7d27ed727e206"></a>

### `load_pending_wifi_config`


```cpp
esp_err_t espectre::load_pending_wifi_config(StoredWifiConfig *config, bool *has_pending)
```

   

<a id="namespaceespectre_1aad6feb37ea2ad9bf489303f43fe1b356"></a>

### `save_pending_wifi_config`


```cpp
esp_err_t espectre::save_pending_wifi_config(const StoredWifiConfig &config)
```

   

<a id="namespaceespectre_1a8096ad0bac3ccebebe9f58089d27a0fc"></a>

### `clear_pending_wifi_config`


```cpp
esp_err_t espectre::clear_pending_wifi_config()
```

   

<a id="namespaceespectre_1aefa05fb8f5d8a1be93d9dd3a6d0fb39e"></a>

### `load_stored_device_config`


```cpp
esp_err_t espectre::load_stored_device_config(EspectreDeviceConfig *config, bool *has_saved_config)
```

   

<a id="namespaceespectre_1a895dff951a4439b9cc6f9469057602c7"></a>

### `save_stored_device_config`


```cpp
esp_err_t espectre::save_stored_device_config(const EspectreDeviceConfig &config)
```

   

<a id="namespaceespectre_1a283d26d4b901e79e0d50bb31defa0af7"></a>

### `clear_stored_device_config`


```cpp
esp_err_t espectre::clear_stored_device_config()
```

   

<a id="namespaceespectre_1ad4c7901011b5435695529f5f5a01e8bf"></a>

### `read_direct_wifi_snapshot`


```cpp
DirectWifiSnapshot espectre::read_direct_wifi_snapshot()
```

 

Read the current ESP-IDF station configuration and association without credentials.

   

<a id="namespaceespectre_1a911b097ab2cd0645acb686a8d64040b3"></a>

### `read_direct_wifi_connected`


```cpp
bool espectre::read_direct_wifi_connected()
```

 

Read cached IPv4 link readiness without querying the Wi-Fi driver.

   

<a id="namespaceespectre_1a2dab48606d782213e70dae8808b0fdd9"></a>

### `load_frontend_device_config`


```cpp
EspectreDeviceConfig espectre::load_frontend_device_config(const FrontendDeviceConfigDefaults &defaults, const char *log_tag, const char *stored_config_message, const char *load_error_prefix)
```

   

<a id="namespaceespectre_1a9c0cb264d4cfce2b1652a1da5e178fb3"></a>

### `setup_frontend_wifi_station`


```cpp
esp_err_t espectre::setup_frontend_wifi_station(WifiProvisioningService *provisioning, StandaloneWifiService *wifi_manager, const FrontendWifiStationOptions &options, const char *log_tag, const char *stored_config_message)
```

   

<a id="namespaceespectre_1ae48174400d9601d7260ae60e07591908"></a>

### `frontend_ha_mqtt_enabled`


```cpp
bool espectre::frontend_ha_mqtt_enabled()
```

   

<a id="namespaceespectre_1ad0ab3784ab4c2449af25b7fb4f8a80b6"></a>

### `build_frontend_ha_mqtt_settings`


```cpp
FrontendHaMqttSettings espectre::build_frontend_ha_mqtt_settings(const EspectreDeviceConfig &config, const EspectreDeviceInfo &info, const char *frontend_name)
```

   

<a id="namespaceespectre_1a5114c22b690a7c5684ade9d26b0294f4"></a>

### `build_frontend_ha_discovery_message`


```cpp
bool espectre::build_frontend_ha_discovery_message(const FrontendHaMqttSettings &settings, const EspectreDeviceInfo &info, bool supports_detector, bool supports_motion_hits, bool supports_traffic_control, size_t index, FrontendHaDiscoveryMessage *message)
```

 

Build one discovery message in publication order; false marks the end.

   

<a id="namespaceespectre_1ac317e956257fb2f5f6171e5fe42affd6"></a>

### `build_frontend_ha_discovery_messages`


```cpp
std::vector< FrontendHaDiscoveryMessage > espectre::build_frontend_ha_discovery_messages(const FrontendHaMqttSettings &settings, const EspectreDeviceInfo &info, bool supports_detector, bool supports_motion_hits, bool supports_traffic_control)
```

   

<a id="namespaceespectre_1a859fb9c76658edbda893921726ab1f0b"></a>

### `setup_frontend_mqtt_transport`


```cpp
bool espectre::setup_frontend_mqtt_transport(IMqttTransport *transport, const EspectreDeviceConfig &config, IMqttTransport::CommandCallback command_callback, FrontendMqttConnectedCallback connected_callback, const char *log_tag)
```

   

<a id="namespaceespectre_1a5698df454955c92dd61cef93bbe3437f"></a>

### `publish_frontend_mqtt_message`


```cpp
bool espectre::publish_frontend_mqtt_message(IMqttTransport *transport, const EspectreDeviceConfig &config, const char *suffix, const std::string &payload, bool retain)
```

   

<a id="namespaceespectre_1a07966aaab03a7ae12577400864e36b30"></a>

### `publish_frontend_mqtt_status`


```cpp
bool espectre::publish_frontend_mqtt_status(IMqttTransport *transport, const EspectreDeviceConfig &config, bool online, uint32_t timestamp_ms)
```

   

<a id="namespaceespectre_1a09e7fae5dc31f12962e6537107073fad"></a>

### `publish_frontend_mqtt_command_result`


```cpp
bool espectre::publish_frontend_mqtt_command_result(IMqttTransport *transport, const EspectreDeviceConfig &config, const FrontendCommandResult &result)
```

   

<a id="namespaceespectre_1aa9d1ab4fa6250571247a25c88d68acf7"></a>

### `nvs_init_with_erase_fallback`


```cpp
esp_err_t espectre::nvs_init_with_erase_fallback()
```

   

<a id="namespaceespectre_1a2a3712a02c829f91e0da24cf3eec56a6"></a>

### `apply_wifi_bssid_pin`


```cpp
bool espectre::apply_wifi_bssid_pin(const std::string &bssid, std::string *message, bool *station_transition_started=nullptr)
```

 

Apply or clear the ESP-IDF station BSSID pin through a Wi-Fi state-machine restart.

   

<a id="namespaceespectre_1a006540692cbd27adf81e85262e1ade02"></a>

### `apply_raw_tx_rate`


```cpp
esp_err_t espectre::apply_raw_tx_rate(const wifi_ap_record_t &ap)
```

 

Configure raw-frame OFDM transmission for the associated AP's band.

   

<a id="namespaceespectre_1a9864a7885166c767516635cd059a8ef6"></a>

### `apply_station_tx_rate`


```cpp
esp_err_t espectre::apply_station_tx_rate()
```

 

Apply station policy; Auto and TX A-MPDU builds leave driver rate selection unchanged.

   

<a id="namespaceespectre_1a3d748e9f1b0d5dbe5388efb97e13569d"></a>

### `to_csi_traffic_config`


```cpp
CsiTrafficServiceConfig espectre::to_csi_traffic_config(const RuntimeConfig &config)
```

 

Project runtime configuration onto transport-independent CSI traffic policy.

   

<a id="namespaceespectre_1af3215fab6f83ede00987d248b8399c94"></a>

### `wifi_band_policy_is_supported`


```cpp
constexpr bool espectre::wifi_band_policy_is_supported(WifiBandPolicy policy)
```

 

Return whether this build can honor the requested band policy.

   

<a id="namespaceespectre_1a964290548f98cd616789767c4f34b690"></a>

### `wifi_channel_matches_band_policy`


```cpp
constexpr bool espectre::wifi_channel_matches_band_policy(int channel, WifiBandPolicy policy)
```

 

Return whether a channel hint is compatible with the requested band.

   

<a id="namespaceespectre_1ae7131ef838a5d0f599a6e4dbcda5830c"></a>

### `wifi_channel_is_supported`


```cpp
constexpr bool espectre::wifi_channel_is_supported(int channel)
```

 

Report whether an optional channel hint is usable on this build.

  

2.4 GHz channels are contiguous; the 5 GHz channel numbers are the 20 MHz centers of the UNII bands, which are spaced four channels apart from 36 and from 149. Passing a 5 GHz channel a 2.4 GHz-only radio cannot tune would fail silently at association time, so those numbers are rejected there.

 

**Parameters**

- `channel`: Channel number, or WIFI\_CHANNEL\_AUTO for no hint

 

**Returns:** true when the channel can be configured on this build

  

<a id="namespaceespectre_1a106a2c32bc0d816e1221218b7b0c0d94"></a>

### `wifi_channel_supported_description`


```cpp
const char * espectre::wifi_channel_supported_description()
```

 

Describe the accepted channel hint values for operator-facing errors.

  

**Returns:** A short human-readable range description

  

<a id="namespaceespectre_1ac6f0a44c679e44a001705073485c13f4"></a>

### `wifi_channel_supported_description`


```cpp
const char * espectre::wifi_channel_supported_description(WifiBandPolicy policy)
```

   

<a id="namespaceespectre_1a46e196c7dcc084bdc7b9db150635bfd0"></a>

### `wifi_bssid_pin_apply_state_name`


```cpp
const char * espectre::wifi_bssid_pin_apply_state_name(WifiBssidPinApplyState state)
```

   

<a id="namespaceespectre_1a6df158d98f79adc5e2759b133ecf52e8"></a>

### `wifi_provisioning_apply_state_name`


```cpp
const char * espectre::wifi_provisioning_apply_state_name(WifiProvisioningApplyState state)
```

   

<a id="namespaceespectre_1a401a56fc8d13271aa575ac137e41dd93"></a>

### `log_espectre_banner`


```cpp
template <typename Logger>
void espectre::log_espectre_banner(Logger &&log_line)
```

   

<a id="namespaceespectre_1ad29105f65f58304d2b72dfec2a198393"></a>

### `frontend_command_parse_error_code`


```cpp
const char * espectre::frontend_command_parse_error_code(const std::string &error)
```

 

Map a canonical command parse failure to its stable result code.

   

<a id="namespaceespectre_1af1ba3349774c2074ec11664168dc616f"></a>

### `operator|`


```cpp
FrontendCommandChange espectre::operator|(FrontendCommandChange lhs, FrontendCommandChange rhs)
```

   

<a id="namespaceespectre_1a1ffdc75b86ce51dcf7243ef983336049"></a>

### `handle_device_config_command`


```cpp
DeviceConfigCommandResult espectre::handle_device_config_command(const std::string &command, const EspectreDeviceConfig &current_config, DeviceConfigClearHandler clear_handler, DeviceConfigUpdateHandler update_handler)
```

   

<a id="namespaceespectre_1abf3a6449bc675492ac72bdb143df9948"></a>

### `frontend_command_allowed_during_raw_collection`


```cpp
bool espectre::frontend_command_allowed_during_raw_collection(const std::string &command, const EspectreProtocolExtension *extension=nullptr)
```

   

<a id="namespaceespectre_1a4bebef550879193c62fbeba6f47cee5a"></a>

### `validate_peer_discovery_candidates`


```cpp
PeerDiscoverySnapshot espectre::validate_peer_discovery_candidates(const std::vector< PeerDiscoveryCandidate > &candidates, uint32_t station_address, uint32_t station_netmask, uint32_t elapsed_ms, bool timed_out)
```

 

Validate, deduplicate, sort, and serialize one bounded discovery result.

   

<a id="namespaceespectre_1a70a8d3f60a08466d66856679d67ad911"></a>

### `peer_discovery_snapshot_json`


```cpp
std::string espectre::peer_discovery_snapshot_json(const PeerDiscoverySnapshot &snapshot)
```

   

<a id="namespaceespectre_1a371a57d18d999de733c9e7cfa628c6c0"></a>

### `monotonic_now_us`


```cpp
uint64_t espectre::monotonic_now_us()
```

   

<a id="namespaceespectre_1a74347339c609120224a1110d79205927"></a>

### `monotonic_now_ms`


```cpp
uint32_t espectre::monotonic_now_ms()
```

   


<a id="namespaceespectre_1_1detail"></a>

## espectre::detail

  [`espectre::detail::PendingEventLock`](#classespectre_1_1detail_1_1_pending_event_lock)



<a id="namespaceespectre_1_1detail_1a4328f2b1fc284e8db1bcf5c82b823899"></a>

### `required_amplitude_bins`


```cpp
constexpr std::array< bool, HT20_NUM_SUBCARRIERS > espectre::detail::required_amplitude_bins(const uint8_t *subcarriers, uint8_t count, uint8_t width)
```

   

<a id="namespaceespectre_1_1detail_1ac20c5153000523ffb25a8b9459d6f546"></a>

### `required_energies_to_amplitudes`


```cpp
template <uint8_t Width>
void espectre::detail::required_energies_to_amplitudes(float *values, uint8_t count, const uint8_t *subcarriers, uint8_t subcarrier_count, bool aggregated)
```

   


<a id="namespaceespectre_1_1task__scheduling"></a>

## espectre::task\_scheduling

  

<a id="namespaceespectre_1_1task__scheduling_1aa4d1b82dcd846f10a6788c92d721c631"></a>

### `kDirectHttpdPriority`


```cpp
constexpr uint32_t espectre::task_scheduling::kDirectHttpdPriority                                            =
CONFIG_ESPECTRE_DIRECT_HTTPD_TASK_PRIORITY
```

   

<a id="namespaceespectre_1_1task__scheduling_1a7ab02a1007eac7ec5986596a9da76ef6"></a>

### `kDirectWorkerPriority`


```cpp
constexpr uint32_t espectre::task_scheduling::kDirectWorkerPriority                                             =
CONFIG_ESPECTRE_DIRECT_WORKER_TASK_PRIORITY
```

   

<a id="namespaceespectre_1_1task__scheduling_1a9161d912c84e540b1a25df4ec85fcdd5"></a>

### `kRawWorkerPriority`


```cpp
constexpr uint32_t espectre::task_scheduling::kRawWorkerPriority                                          =
CONFIG_ESPECTRE_RAW_WORKER_TASK_PRIORITY
```

   

<a id="namespaceespectre_1_1task__scheduling_1aeb066e2810db7b56cf4a6b62d7296998"></a>

### `kTrafficPriority`


```cpp
constexpr uint32_t espectre::task_scheduling::kTrafficPriority = CONFIG_ESPECTRE_TRAFFIC_TASK_PRIORITY
```

   

<a id="namespaceespectre_1_1task__scheduling_1af6a58fae684eb2597f88823b34ca8f5d"></a>

### `kNativeLoopPriority`


```cpp
constexpr uint32_t espectre::task_scheduling::kNativeLoopPriority                                           =
CONFIG_ESPECTRE_NATIVE_LOOP_TASK_PRIORITY
```

   


<a id="classespectre_1_1_base_detector"></a>

## espectre::BaseDetector



```cpp
#include <core/base_detector.h>
```



```cpp
class espectre::BaseDetector
```

 

Abstract base class for motion detection algorithms.

  

Provides shared functionality:

- Turbulence buffer management (circular buffer)

- Hampel and low-pass filtering

- CSI processing and spatial turbulence calculation

 

Subclasses must implement:

- [update\_state()](#classespectre_1_1_base_detector_1a261ca504b8a5fb2e915c6354f3e9ddf6): detection algorithm logic

- [get\_motion\_metric()](#classespectre_1_1_base_detector_1ab7ea59db54d734cc87815e0a7aebd972): primary detection metric

- [get\_threshold()](#classespectre_1_1_base_detector_1ab1b2a5a33a086a50783cc158f56a6b8c) / [set\_threshold()](#classespectre_1_1_base_detector_1a9614847f36f3a391ff2df8e0f77fc1da): threshold management

- [get\_name()](#classespectre_1_1_base_detector_1af1a3b2c9adb5ad7b550acfd7230a1503): detector name for logging

 

<a id="classespectre_1_1_base_detector_1a704e1cd629bbfa076f09ff78f8589449"></a>

### `turbulence_buffer_`


```cpp
float* espectre::BaseDetector::turbulence_buffer_
```

   

<a id="classespectre_1_1_base_detector_1a803bf375787e80593d21eae6c86cdca1"></a>

### `ordered_turbulence_`


```cpp
float* espectre::BaseDetector::ordered_turbulence_
```

   

<a id="classespectre_1_1_base_detector_1a111ed542d50cc07a7d19b7d4c723d605"></a>

### `buffer_index_`


```cpp
uint16_t espectre::BaseDetector::buffer_index_
```

   

<a id="classespectre_1_1_base_detector_1a5dfe97b27a2071b41ba5522df54d1d74"></a>

### `buffer_count_`


```cpp
uint16_t espectre::BaseDetector::buffer_count_
```

   

<a id="classespectre_1_1_base_detector_1ab6a65687542789b85ea50d08f8889411"></a>

### `valid_buffer_count_`


```cpp
uint16_t espectre::BaseDetector::valid_buffer_count_
```

   

<a id="classespectre_1_1_base_detector_1a6390a37f6eab391953b2902ccad28e19"></a>

### `minimum_valid_samples_`


```cpp
uint16_t espectre::BaseDetector::minimum_valid_samples_
```

   

<a id="classespectre_1_1_base_detector_1a531deb4e201dd7315f89a77144c0cb66"></a>

### `window_size_`


```cpp
uint16_t espectre::BaseDetector::window_size_
```

   

<a id="classespectre_1_1_base_detector_1a7c807d680f10bfd7c6956812b7413749"></a>

### `state_`


```cpp
MotionState espectre::BaseDetector::state_
```

   

<a id="classespectre_1_1_base_detector_1ac744d80062fb6c9fcf64d122e2865362"></a>

### `current_metric_`


```cpp
float espectre::BaseDetector::current_metric_
```

   

<a id="classespectre_1_1_base_detector_1a39ecf887d2f955fe53c2efdede92915b"></a>

### `total_packets_`


```cpp
uint32_t espectre::BaseDetector::total_packets_
```

   

<a id="classespectre_1_1_base_detector_1a3b899045c8ad6a5d932af413615b6274"></a>

### `packet_index_`


```cpp
uint32_t espectre::BaseDetector::packet_index_
```

   

<a id="classespectre_1_1_base_detector_1a71cfdb211ee4311aee2347e61b00d941"></a>

### `packet_timestamp_us_`


```cpp
uint64_t espectre::BaseDetector::packet_timestamp_us_
```

   

<a id="classespectre_1_1_base_detector_1ac627c02075ead3e632d29811dc4e3c20"></a>

### `has_packet_timestamp_`


```cpp
bool espectre::BaseDetector::has_packet_timestamp_
```

   

<a id="classespectre_1_1_base_detector_1ad8976c91d321a26c1a35ff75eb5bbeb6"></a>

### `hampel_state_`


```cpp
hampel_filter_state_t espectre::BaseDetector::hampel_state_
```

   

<a id="classespectre_1_1_base_detector_1a82b7aac2d9a18c7403a64556b64f23c6"></a>

### `lowpass_state_`


```cpp
lowpass_filter_state_t espectre::BaseDetector::lowpass_state_
```

   


<a id="classespectre_1_1_base_detector_1ac70f1692bdd644c0589f426d8267b681"></a>

### `BaseDetector`


```cpp
explicit espectre::BaseDetector::BaseDetector(uint16_t window_size=DETECTOR_DEFAULT_WINDOW_SIZE)
```

 

Constructor.

  

**Parameters**

- `window_size`: Buffer window size in the inclusive range defined by DETECTOR\_MIN\_WINDOW\_SIZE and DETECTOR\_MAX\_WINDOW\_SIZE

  

<a id="classespectre_1_1_base_detector_1a2062504291217a724134d103d8a73d59"></a>

### `~BaseDetector`


```cpp
virtual espectre::BaseDetector::~BaseDetector()
```

   

<a id="classespectre_1_1_base_detector_1a5d2806fada882285a9b8fa8848179238"></a>

### `BaseDetector`


```cpp
espectre::BaseDetector::BaseDetector(BaseDetector &&other) noexcept
```

   

<a id="classespectre_1_1_base_detector_1a565d9425c07877ff82b9950feb65a429"></a>

### `operator=`


```cpp
BaseDetector & espectre::BaseDetector::operator=(BaseDetector &&other) noexcept
```

   

<a id="classespectre_1_1_base_detector_1a2602479812119dada1826c3d996520de"></a>

### `BaseDetector`


```cpp
espectre::BaseDetector::BaseDetector(const BaseDetector &)=delete
```

   

<a id="classespectre_1_1_base_detector_1a25933318888d59fa2cfa90ac594fb0c8"></a>

### `operator=`


```cpp
BaseDetector & espectre::BaseDetector::operator=(const BaseDetector &)=delete
```

   

<a id="classespectre_1_1_base_detector_1a121de67ca4480d53819bd6fb45bc7253"></a>

### `process_packet`


```cpp
virtual void espectre::BaseDetector::process_packet(const int8_t *csi_data, size_t csi_len, const uint8_t *selected_subcarriers=nullptr, uint8_t num_subcarriers=0, int8_t rssi_dbm=INT8_MIN)
```

 

Process one normalized, temporally admitted CSI packet.

  

Calculates spatial turbulence from CSI data, applies filtering, and stores in circular buffer.

 

**Parameters**

- `csi_data`: Normalized CSI data (I/Q interleaved)
- `csi_len`: Length of CSI data
- `selected_subcarriers`: Array of subcarrier indices
- `num_subcarriers`: Number of selected subcarriers
- `rssi_dbm`: Link RSSI for this packet, or INT8\_MIN when unknown

  

<a id="classespectre_1_1_base_detector_1ad432493bba41a1951f7d2ee2e7666a4d"></a>

### `set_packet_timestamp_us`


```cpp
void espectre::BaseDetector::set_packet_timestamp_us(uint64_t timestamp_us)
```

 

Supply the monotonic arrival timestamp consumed by time-binned features.

   

<a id="classespectre_1_1_base_detector_1afeafa0d2e142db2f73eff87230164288"></a>

### `reset`


```cpp
virtual void espectre::BaseDetector::reset()
```

 

Reset detector state.

  

Resets state machine but preserves buffer ("warm" restart).

  

<a id="classespectre_1_1_base_detector_1a8aa4a67f587b5e575346e3bf529f96f2"></a>

### `get_state`


```cpp
virtual MotionState espectre::BaseDetector::get_state() const
```

 

Get current motion state.

   

<a id="classespectre_1_1_base_detector_1a474ff45b6a2ef2cb061f86603e76d475"></a>

### `is_valid`


```cpp
virtual bool espectre::BaseDetector::is_valid() const
```

 

Return whether all base detector working storage was allocated.

   

<a id="classespectre_1_1_base_detector_1a909126a7761b02f5f58c19103cd91053"></a>

### `is_ready`


```cpp
virtual bool espectre::BaseDetector::is_ready() const
```

 

Check if detector is ready (buffer filled).

   

<a id="classespectre_1_1_base_detector_1a5e047ba665b25faf9e5088df58302f50"></a>

### `advance_missing_slots`


```cpp
virtual void espectre::BaseDetector::advance_missing_slots(uint32_t count)
```

 

Advance packet-indexed feature rings for absent temporal slots.

   

<a id="classespectre_1_1_base_detector_1a9732e34f845a2eb619ac9f42e1096353"></a>

### `set_minimum_valid_samples`


```cpp
void espectre::BaseDetector::set_minimum_valid_samples(uint16_t count)
```

 

Set the valid-slot occupancy floor used by [`is_ready()`](#classespectre_1_1_base_detector_1a909126a7761b02f5f58c19103cd91053).

   

<a id="classespectre_1_1_base_detector_1a4ca1de3311c1895fbaa1295e7c8ec9ec"></a>

### `get_total_packets`


```cpp
virtual uint32_t espectre::BaseDetector::get_total_packets() const
```

 

Get total packets processed.

   

<a id="classespectre_1_1_base_detector_1a261ca504b8a5fb2e915c6354f3e9ddf6"></a>

### `update_state`


```cpp
virtual void espectre::BaseDetector::update_state()=0
```

 

Update state machine (call at the detector evaluation interval).

  

Subclasses implement their detection algorithm here.

  

<a id="classespectre_1_1_base_detector_1ab7ea59db54d734cc87815e0a7aebd972"></a>

### `get_motion_metric`


```cpp
float espectre::BaseDetector::get_motion_metric() const
```

 

Get current motion metric value.

  

Not virtual: every detector reported the same member through an identical accessor, and the two copies drifted on when they cleared it. Subclasses assign [`current_metric_`](#classespectre_1_1_base_detector_1ac744d80062fb6c9fcf64d122e2865362) at the end of their [`update_state()`](#classespectre_1_1_base_detector_1a261ca504b8a5fb2e915c6354f3e9ddf6) instead.

 

**Returns:** Primary metric (classic motion metric, ML probability, etc.)

  

<a id="classespectre_1_1_base_detector_1a9614847f36f3a391ff2df8e0f77fc1da"></a>

### `set_threshold`


```cpp
virtual bool espectre::BaseDetector::set_threshold(float threshold)=0
```

 

Set detection threshold.

  

**Parameters**

- `threshold`: New threshold value

 

**Returns:** true if value was accepted

  

<a id="classespectre_1_1_base_detector_1a6badc6950f8328f4bd77ff50ea47fee4"></a>

### `set_adaptive_threshold`


```cpp
virtual bool espectre::BaseDetector::set_adaptive_threshold(float threshold)
```

 

Apply a detector-specific startup-calibrated threshold.

   

<a id="classespectre_1_1_base_detector_1ab1b2a5a33a086a50783cc158f56a6b8c"></a>

### `get_threshold`


```cpp
virtual float espectre::BaseDetector::get_threshold() const =0
```

 

Get current threshold.

   

<a id="classespectre_1_1_base_detector_1af1a3b2c9adb5ad7b550acfd7230a1503"></a>

### `get_name`


```cpp
virtual const char * espectre::BaseDetector::get_name() const =0
```

 

Get detector name for logging.

   

<a id="classespectre_1_1_base_detector_1ab3ff821066a78493f9f91dda37001310"></a>

### `get_startup_threshold_factor`


```cpp
virtual float espectre::BaseDetector::get_startup_threshold_factor() const
```

 

Get the detector-specific automatic startup multiplier.

  

threshold = threshold\_metric x factor. Matches the Python runtime's detector STARTUP\_THRESHOLD\_FACTOR convention, where `threshold_metric` comes from the shared startup calibrator.

  

<a id="classespectre_1_1_base_detector_1ad476a9ddaeda232d21c7b85b8323f482"></a>

### `startup_gate_enabled`


```cpp
virtual bool espectre::BaseDetector::startup_gate_enabled() const
```

 

Whether startup calibration uses the consistency gate (threshold.h).

  

Enabled only for detectors with a tight quiet floor (l1\_delta). Matches the Python runtime's detector STARTUP\_GATE convention.

  

<a id="classespectre_1_1_base_detector_1a23b1db60d0ab0f31516e345f571fa01c"></a>

### `on_startup_calibration_begin`


```cpp
virtual void espectre::BaseDetector::on_startup_calibration_begin()
```

 

Hook called immediately before startup calibration begins.

   

<a id="classespectre_1_1_base_detector_1af003e89702b0e5bd97028e0b5ce4591b"></a>

### `on_startup_calibration_complete`


```cpp
virtual void espectre::BaseDetector::on_startup_calibration_complete()
```

 

Hook called when startup calibration completes successfully.

  

Detectors can freeze session-specific state here before the runtime performs its warm clear between calibration and steady-state detection.

  

<a id="classespectre_1_1_base_detector_1a62329885a69c9b2bdadfb0635f171d61"></a>

### `configure_lowpass`


```cpp
virtual void espectre::BaseDetector::configure_lowpass(bool enabled, float cutoff_hz=LOWPASS_CUTOFF_DEFAULT)
```

 

Configure low-pass filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `cutoff_hz`: Cutoff frequency (5.0-20.0 Hz)

  

<a id="classespectre_1_1_base_detector_1aa1401e5000e0a766275dfa0e37e10fb4"></a>

### `configure_hampel`


```cpp
virtual void espectre::BaseDetector::configure_hampel(bool enabled, uint8_t window_size=HAMPEL_TURBULENCE_WINDOW_DEFAULT, float threshold=HAMPEL_TURBULENCE_THRESHOLD_DEFAULT)
```

 

Configure Hampel filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `window_size`: Window size (3-11)
- `threshold`: MAD multiplier threshold

  

<a id="classespectre_1_1_base_detector_1a80285cefc4541552ee897557e8339da2"></a>

### `clear_buffer`


```cpp
virtual void espectre::BaseDetector::clear_buffer()
```

 

Clear turbulence buffer (cold restart).

  

Virtual so detectors with additional state (e.g. L1-Delta profile rings) can extend the cold clear.

  

<a id="classespectre_1_1_base_detector_1aaf32952ebf0ad274b164f9595d6ae491"></a>

### `get_turbulence_buffer`


```cpp
const float * espectre::BaseDetector::get_turbulence_buffer() const
```

 

Get turbulence buffer pointer.

   

<a id="classespectre_1_1_base_detector_1a01a376fa621d31e9e122686aa1f58c1e"></a>

### `get_buffer_count`


```cpp
uint16_t espectre::BaseDetector::get_buffer_count() const
```

 

Get number of valid samples in buffer.

   

<a id="classespectre_1_1_base_detector_1a836410ad2d0b965fe812c249b1756a7a"></a>

### `get_valid_buffer_count`


```cpp
uint16_t espectre::BaseDetector::get_valid_buffer_count() const
```

   

<a id="classespectre_1_1_base_detector_1a76ad118e4803e800bac0df5870dbfbd4"></a>

### `get_window_size`


```cpp
uint16_t espectre::BaseDetector::get_window_size() const
```

 

Get configured window size.

   

<a id="classespectre_1_1_base_detector_1ad9b1e80293dbaf06f2ef18d56401ccef"></a>

### `get_last_turbulence`


```cpp
float espectre::BaseDetector::get_last_turbulence() const
```

 

Get last turbulence value.

   

<a id="classespectre_1_1_base_detector_1aa7baf15ce9ba07d078f09a8566f4e326"></a>

### `is_lowpass_enabled`


```cpp
bool espectre::BaseDetector::is_lowpass_enabled() const
```

 

Check if low-pass filter is enabled.

   

<a id="classespectre_1_1_base_detector_1ab9793996d7abbf858af925cd2f2fb725"></a>

### `is_hampel_enabled`


```cpp
bool espectre::BaseDetector::is_hampel_enabled() const
```

 

Check if Hampel filter is enabled.

   


<a id="classespectre_1_1_base_detector_1ad4b8b59d9e7d07dc689450a5c28a5f75"></a>

### `clear_evaluation_state_`


```cpp
void espectre::BaseDetector::clear_evaluation_state_()
```

 

Drop the last evaluation result.

  

Anything that invalidates the window must also invalidate what was derived from it, or the next publish ships a metric computed from samples the detector no longer holds. Owned here so a detector cannot clear one half and forget the other.

  

<a id="classespectre_1_1_base_detector_1ad05573f50021c0404ed629f1500f304e"></a>

### `process_amplitudes`


```cpp
void espectre::BaseDetector::process_amplitudes(const float *amplitudes, uint8_t count)
```

   

<a id="classespectre_1_1_base_detector_1a8ad0a3fdd14591477ebd01681e0ce84b"></a>

### `packet_timestamp_us_or`


```cpp
uint64_t espectre::BaseDetector::packet_timestamp_us_or(uint64_t fallback) const
```

   

<a id="classespectre_1_1_base_detector_1a93b91a3da1f77896a922e0a50efc9d77"></a>

### `add_turbulence_to_buffer`


```cpp
void espectre::BaseDetector::add_turbulence_to_buffer(float turbulence)
```

 

Add turbulence value to buffer (with filtering).

   

<a id="classespectre_1_1_base_detector_1a2d514487a053702a159e0d3435007450"></a>

### `ordered_turbulence`


```cpp
const float * espectre::BaseDetector::ordered_turbulence(uint16_t &count) const
```

 

View the turbulence ring in chronological order.

  

Returns the ring itself while it is still filling (already in order), and the base-owned reorder buffer once it wraps. Returns nullptr when there is nothing to read or the reorder buffer could not be allocated.

 

**Parameters**

- `count`: Receives the number of valid samples

  


<a id="classespectre_1_1_base_detector_1a1697649add47e9e80ebd4e29a50a795a"></a>

### `alloc_zeroed_floats`


```cpp
static float * espectre::BaseDetector::alloc_zeroed_floats(uint16_t count)
```

 

Allocate a zeroed float buffer on the heap.

  

Shared by the detectors so no feature helper puts a window-sized array on the CSI callback stack.

 

**Returns:** nullptr when count is 0 or the allocation fails

  


<a id="classespectre_1_1_csi_traffic_service"></a>

## espectre::CsiTrafficService



```cpp
#include <runtime/csi_traffic_service.h>
```



```cpp
class espectre::CsiTrafficService
```

  

<a id="classespectre_1_1_csi_traffic_service_1ac9e4fa69ec1c128db3a3be5a80d13499"></a>

### `CsiTrafficService`


```cpp
espectre::CsiTrafficService::CsiTrafficService(ICsiTrafficGenerator &traffic_generator, ICsiTrafficIngress &traffic_ingress)
```

   

<a id="classespectre_1_1_csi_traffic_service_1a2463a9630c708756b78379f60e4304d5"></a>

### `init`


```cpp
void espectre::CsiTrafficService::init(const CsiTrafficServiceConfig &config)
```

   

<a id="classespectre_1_1_csi_traffic_service_1a055f139cc1504b5a9ea8d095b4c030da"></a>

### `start`


```cpp
bool espectre::CsiTrafficService::start(uint32_t target_addr=0U)
```

   

<a id="classespectre_1_1_csi_traffic_service_1ac059347bfc8b0aea38d2501c18cc87f3"></a>

### `stop`


```cpp
void espectre::CsiTrafficService::stop()
```

   

<a id="classespectre_1_1_csi_traffic_service_1a5460f876c4d4c3d67cb964f87bfc49fe"></a>

### `loop`


```cpp
void espectre::CsiTrafficService::loop()
```

   

<a id="classespectre_1_1_csi_traffic_service_1acc1994d066d676521b378a7afea9928a"></a>

### `set_packet_callback`


```cpp
void espectre::CsiTrafficService::set_packet_callback(csi_traffic_packet_callback_t callback, void *context=nullptr)
```

   

<a id="classespectre_1_1_csi_traffic_service_1a9d1a8fb3968bd5e33d9c337d318670b4"></a>

### `is_running`


```cpp
bool espectre::CsiTrafficService::is_running() const
```

   

<a id="classespectre_1_1_csi_traffic_service_1adeaf0bf26e4ca70025b4039c5ea6b00b"></a>

### `get_last_sender`


```cpp
bool espectre::CsiTrafficService::get_last_sender(UdpDatagramPeer *out_peer) const
```

   

<a id="classespectre_1_1_csi_traffic_service_1ae9898ad9c4e5fc4ce168ac6fc27b851e"></a>

### `get_packets_received`


```cpp
uint64_t espectre::CsiTrafficService::get_packets_received() const
```

   

<a id="classespectre_1_1_csi_traffic_service_1a7757a198becbcde331fd15f9d164bb41"></a>

### `get_traffic_packets_total`


```cpp
uint64_t espectre::CsiTrafficService::get_traffic_packets_total() const
```

   

<a id="classespectre_1_1_csi_traffic_service_1a66bc64c398ab10a4921ccc6a4f0403de"></a>

### `internal_icmp_identifier`


```cpp
uint16_t espectre::CsiTrafficService::internal_icmp_identifier() const
```

   

<a id="classespectre_1_1_csi_traffic_service_1ab3a15734bfc83aa424fc922a5f276c31"></a>

### `mode`


```cpp
CsiTrafficMode espectre::CsiTrafficService::mode() const
```

   


<a id="structespectre_1_1_csi_traffic_service_config"></a>

## espectre::CsiTrafficServiceConfig



```cpp
#include <runtime/csi_traffic_service.h>
```



```cpp
struct espectre::CsiTrafficServiceConfig
```

  

<a id="structespectre_1_1_csi_traffic_service_config_1a0bab96b8c061971a5ea7a7a2ba417a96"></a>

### `mode`


```cpp
CsiTrafficMode espectre::CsiTrafficServiceConfig::mode {CsiTrafficMode::INTERNAL}
```

   

<a id="structespectre_1_1_csi_traffic_service_config_1a50268f115b693da1cb0fa47cab4f6a40"></a>

### `rate_pps`


```cpp
uint32_t espectre::CsiTrafficServiceConfig::rate_pps {100U}
```

   

<a id="structespectre_1_1_csi_traffic_service_config_1a3f78eddffc2fad80c70e5e17af936f00"></a>

### `traffic_mode`


```cpp
RuntimeTrafficMode espectre::CsiTrafficServiceConfig::traffic_mode {RuntimeTrafficMode::PING}
```

   

<a id="structespectre_1_1_csi_traffic_service_config_1af04a97ecbce02d1d10d0c4e31d337a42"></a>

### `udp_port`


```cpp
uint16_t espectre::CsiTrafficServiceConfig::udp_port {5555U}
```

   

<a id="structespectre_1_1_csi_traffic_service_config_1ae0ba87c83740f931991bb4666afa6c1d"></a>

### `multicast_group`


```cpp
std::string espectre::CsiTrafficServiceConfig::multicast_group
```

   


<a id="structespectre_1_1_device_config_command_result"></a>

## espectre::DeviceConfigCommandResult



```cpp
#include <runtime/frontend_command_engine.h>
```



```cpp
struct espectre::DeviceConfigCommandResult
```

  

<a id="structespectre_1_1_device_config_command_result_1a0375d1bdad26998422ff7b2022a1f842"></a>

### `handled`


```cpp
bool espectre::DeviceConfigCommandResult::handled {false}
```

   

<a id="structespectre_1_1_device_config_command_result_1aabb69541c164cda7328fc8bb160eca10"></a>

### `accepted`


```cpp
bool espectre::DeviceConfigCommandResult::accepted {false}
```

   

<a id="structespectre_1_1_device_config_command_result_1af8407c3b60ead9c12cef47b7681177f2"></a>

### `config_changed`


```cpp
bool espectre::DeviceConfigCommandResult::config_changed {false}
```

   

<a id="structespectre_1_1_device_config_command_result_1ac2e1db62790b22374bbdb33b701e45c2"></a>

### `config`


```cpp
EspectreDeviceConfig espectre::DeviceConfigCommandResult::config {}
```

   

<a id="structespectre_1_1_device_config_command_result_1a2196459723aac59d20afc0eddbecda2c"></a>

### `message`


```cpp
std::string espectre::DeviceConfigCommandResult::message
```

   


<a id="structespectre_1_1_direct_http_service_config"></a>

## espectre::DirectHttpServiceConfig



```cpp
#include <runtime/direct_http_service.h>
```



```cpp
struct espectre::DirectHttpServiceConfig
```

  

<a id="structespectre_1_1_direct_http_service_config_1afdc25c605172c283f046b864fc75f536"></a>

### `allowed_origins`


```cpp
std::vector<std::string> espectre::DirectHttpServiceConfig::allowed_origins
```

   

<a id="structespectre_1_1_direct_http_service_config_1ad302cbbe428f3ebf2c46b235c23f420c"></a>

### `device_id`


```cpp
uint64_t espectre::DirectHttpServiceConfig::device_id {0U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1ac197b814e5841ac86aef20a349bc53c9"></a>

### `port`


```cpp
uint16_t espectre::DirectHttpServiceConfig::port {ESPECTRE_DIRECT_HTTP_PORT}
```

   

<a id="structespectre_1_1_direct_http_service_config_1ab2ba838a2fc400029f6f5a16c086f077"></a>

### `max_event_clients`


```cpp
size_t espectre::DirectHttpServiceConfig::max_event_clients {2U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1a06fc309448ba84ebbac7f1419bdf4f64"></a>

### `max_pending_requests`


```cpp
size_t espectre::DirectHttpServiceConfig::max_pending_requests {4U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1ad25d287f420112dfec65715119b10dcf"></a>

### `outbound_queue_depth`


```cpp
size_t espectre::DirectHttpServiceConfig::outbound_queue_depth {8U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1a5d5ddecc43f3c19e1534b1c593c80a07"></a>

### `max_requests_per_second`


```cpp
uint16_t espectre::DirectHttpServiceConfig::max_requests_per_second {20U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1abba7b1ff7aa346cd9c4574d1771afd4f"></a>

### `max_mutations_per_minute`


```cpp
uint16_t espectre::DirectHttpServiceConfig::max_mutations_per_minute {60U}
```

   

<a id="structespectre_1_1_direct_http_service_config_1af076038c08cbdbb6811eb2b09db08762"></a>

### `allow_missing_origin`


```cpp
bool espectre::DirectHttpServiceConfig::allow_missing_origin {false}
```

   

<a id="structespectre_1_1_direct_http_service_config_1ae2c8f96e540149e33adc4db28ac8a95b"></a>

### `allow_http_loopback_origins`


```cpp
bool espectre::DirectHttpServiceConfig::allow_http_loopback_origins {false}
```

   

<a id="structespectre_1_1_direct_http_service_config_1a1a1ee541cab1a782eed9074764ae269b"></a>

### `protocol_extension`


```cpp
const EspectreProtocolExtension* espectre::DirectHttpServiceConfig::protocol_extension {nullptr}
```

 

Optional frontend routes.

  

The immutable catalog must outlive this service.

  


<a id="structespectre_1_1_direct_http_service_config_1a937605cc8df763b5e028a051c3b47e4a"></a>

### `for_first_party_portals`


```cpp
static DirectHttpServiceConfig espectre::DirectHttpServiceConfig::for_first_party_portals()
```

 

Configuration for ESPectre's production and validation portals.

   


<a id="structespectre_1_1_direct_http_service_diagnostics"></a>

## espectre::DirectHttpServiceDiagnostics



```cpp
#include <runtime/direct_http_service.h>
```



```cpp
struct espectre::DirectHttpServiceDiagnostics
```

  

<a id="structespectre_1_1_direct_http_service_diagnostics_1a9c7f0142a8d93556baeef9fdf63849a3"></a>

### `event_client_limit`


```cpp
size_t espectre::DirectHttpServiceDiagnostics::event_client_limit {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1ac707ab3bad71aef5cbb19e79c636f910"></a>

### `queue_capacity`


```cpp
size_t espectre::DirectHttpServiceDiagnostics::queue_capacity {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a8563f7956f0a9d8ffa358cf031b090d5"></a>

### `accepted_connections`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::accepted_connections {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a46d844448509e03ed47183648d9d0eec"></a>

### `rejected_connections`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::rejected_connections {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a1130f2f2217163e5f7c69d96eeaaa46c"></a>

### `malformed_requests`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::malformed_requests {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a3759c6627ef3e77a8070c56b37a938bd"></a>

### `oversized_requests`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::oversized_requests {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1afbda12528b3158bfe8b73e1729b18f74"></a>

### `rate_limited_requests`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::rate_limited_requests {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a5fedcd05e4e07aba75115a19fd2a0b7c"></a>

### `dropped_motion_events`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::dropped_motion_events {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1a642fe94b20a7c7e54f41fd513b9159d7"></a>

### `send_failures`


```cpp
uint32_t espectre::DirectHttpServiceDiagnostics::send_failures {0U}
```

   

<a id="structespectre_1_1_direct_http_service_diagnostics_1aec94025f197cf1408f7a52556db86fa7"></a>

### `queued_messages`


```cpp
size_t espectre::DirectHttpServiceDiagnostics::queued_messages {0U}
```

   


<a id="structespectre_1_1_direct_request"></a>

## espectre::DirectRequest



```cpp
#include <runtime/direct_http_protocol.h>
```



```cpp
struct espectre::DirectRequest
```

  

<a id="structespectre_1_1_direct_request_1adf922ed00c7a0f4e1f3639003ada642b"></a>

### `command_id`


```cpp
std::string espectre::DirectRequest::command_id
```

   

<a id="structespectre_1_1_direct_request_1ad00a242692f23702edc510466a3ddd18"></a>

### `command`


```cpp
std::string espectre::DirectRequest::command
```

   

<a id="structespectre_1_1_direct_request_1af1b326b84679b121e4495d128ce2f769"></a>

### `params`


```cpp
std::string espectre::DirectRequest::params {"{}"}
```

 

Syntactically valid JSON object containing command parameters.

   

<a id="structespectre_1_1_direct_request_1ad8acda6c3a8dd15be0dc5c1de5abd580"></a>

### `path`


```cpp
std::string espectre::DirectRequest::path
```

 

Request path, retained for resource-aware response handling.

   

<a id="structespectre_1_1_direct_request_1af80d15f9b41df7b5fb69e9cc2d8cde3e"></a>

### `http_method`


```cpp
std::string espectre::DirectRequest::http_method
```

 

HTTP method selected by the transport route.

   

<a id="structespectre_1_1_direct_request_1ae8e60534fc082b6e015412d3d8512ec7"></a>

### `asynchronous`


```cpp
bool espectre::DirectRequest::asynchronous {false}
```

 

Whether the accepted operation completes asynchronously.

   


<a id="structespectre_1_1_direct_wifi_snapshot"></a>

## espectre::DirectWifiSnapshot



```cpp
#include <runtime/esp_idf/direct_wifi_snapshot_esp_idf.h>
```



```cpp
struct espectre::DirectWifiSnapshot
```

  

<a id="structespectre_1_1_direct_wifi_snapshot_1a35fad680fbddf95dfc3d949827f25531"></a>

### `configured`


```cpp
bool espectre::DirectWifiSnapshot::configured {false}
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1a77b5b090fbac01ef3c6b04098cb774fb"></a>

### `connected`


```cpp
bool espectre::DirectWifiSnapshot::connected {false}
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1a654870b989f58fde00d8322e0fd4c09e"></a>

### `ssid`


```cpp
std::string espectre::DirectWifiSnapshot::ssid
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1a71e273d8802c9243de20cacf56d6257a"></a>

### `bssid`


```cpp
std::string espectre::DirectWifiSnapshot::bssid
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1a22518d182419dba3ff69f9500ed5a0bb"></a>

### `band`


```cpp
std::string espectre::DirectWifiSnapshot::band
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1aab4926f5f413440ec92938acd524c94f"></a>

### `channel`


```cpp
uint8_t espectre::DirectWifiSnapshot::channel {0U}
```

   

<a id="structespectre_1_1_direct_wifi_snapshot_1af8aa80bf3f802d719965d1dd4acf8c2a"></a>

### `rssi_dbm`


```cpp
int16_t espectre::DirectWifiSnapshot::rssi_dbm {INT16_MIN}
```

   


<a id="classespectre_1_1_esp_idf_direct_http_service"></a>

## espectre::EspIdfDirectHttpService



```cpp
#include <runtime/esp_idf/direct_http_service_esp_idf.h>
```



```cpp
class espectre::EspIdfDirectHttpService : public espectre::IDirectHttpService
```

  [`espectre::IDirectHttpService`](#classespectre_1_1_i_direct_http_service)



<a id="classespectre_1_1_esp_idf_direct_http_service_1af089ad0dc1f04f6c6df779fd334f253a"></a>

### `EspIdfDirectHttpService`


```cpp
espectre::EspIdfDirectHttpService::EspIdfDirectHttpService()
```

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1ac347e2a473f454a0dd361a2d2993e10f"></a>

### `~EspIdfDirectHttpService`


```cpp
espectre::EspIdfDirectHttpService::~EspIdfDirectHttpService() override
```

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1a7b8d45f4be693a762e4abe82fc2a20bf"></a>

### `setup`


```cpp
bool espectre::EspIdfDirectHttpService::setup(const DirectHttpServiceConfig &config, RequestHandler request_handler, ClientCountCallback client_count_callback) override
```

 

Configure and start the endpoint.

  

Safe to call again after shutdown.

  

<a id="classespectre_1_1_esp_idf_direct_http_service_1ae225e3119210aad76296207a590e13b6"></a>

### `setup_deferred`


```cpp
bool espectre::EspIdfDirectHttpService::setup_deferred(const DirectHttpServiceConfig &config, DeferredRequestHandler request_handler, ClientCountCallback client_count_callback) override
```

 

Configure a handler that may complete a request later.

  

The default preserves source compatibility for external transports that implement only synchronous Direct requests. A successful deferred handler must eventually call [complete\_deferred\_response()](#classespectre_1_1_esp_idf_direct_http_service_1a47b68b279c034d769daa2a257ae56a4e) with the opaque token.

  

<a id="classespectre_1_1_esp_idf_direct_http_service_1a47b68b279c034d769daa2a257ae56a4e"></a>

### `complete_deferred_response`


```cpp
bool espectre::EspIdfDirectHttpService::complete_deferred_response(uint64_t request_token, std::string response) override
```

 

Queue a deferred response only if the originating connection is live.

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1abbe2a278b424a1165475d8ffca79b78a"></a>

### `loop`


```cpp
void espectre::EspIdfDirectHttpService::loop() override
```

 

Pump deferred receive, dispatch, send work, and application callbacks from the frontend task.

  

Request, client-count, and raw-stop callbacks are never delivered from HTTP server or streaming worker tasks.

  

<a id="classespectre_1_1_esp_idf_direct_http_service_1a69bb753b2d9164edb8e4103810dff6d0"></a>

### `shutdown`


```cpp
void espectre::EspIdfDirectHttpService::shutdown() override
```

 

Stop accepting clients, close sockets, and release queued messages.

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1ada58a458d98dd8e124db39f943c3a2e5"></a>

### `running`


```cpp
bool espectre::EspIdfDirectHttpService::running() const override
```

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1ab361c7437c09142a8ef9c1c155923c49"></a>

### `event_client_count`


```cpp
size_t espectre::EspIdfDirectHttpService::event_client_count() const override
```

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1a6b1b073f0208576039b7e738b4924764"></a>

### `publish_event`


```cpp
bool espectre::EspIdfDirectHttpService::publish_event(const std::string &event_name, const std::string &data_json, bool replaceable_telemetry) override
```

 

Queue a normalized event for every connected client.

  

Telemetry events may replace an older queued event with the same name. State transitions and command responses must never be replaced by telemetry. Returns false when no client can accept the event.

  

<a id="classespectre_1_1_esp_idf_direct_http_service_1a53a673575c7d1bcd9b5c36415bb90883"></a>

### `diagnostics`


```cpp
DirectHttpServiceDiagnostics espectre::EspIdfDirectHttpService::diagnostics() const override
```

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1ac4e80472b1ff46d590b53873837ad3f5"></a>

### `set_raw_session_requested_callback`


```cpp
void espectre::EspIdfDirectHttpService::set_raw_session_requested_callback(RawSessionRequestedCallback callback) override
```

 

Register the frontend-task callback that opens collection for GET /csi.

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1a109597c4e5df813e81eb915429705722"></a>

### `start_raw_session`


```cpp
bool espectre::EspIdfDirectHttpService::start_raw_session(const RawCsiSessionConfig &config, RawSessionStoppedCallback stopped_callback) override
```

 

Begin one owner-bound raw session on the service's binary endpoint.

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1ac5b0595da73f263666c1db28954a6a26"></a>

### `stop_raw_session`


```cpp
bool espectre::EspIdfDirectHttpService::stop_raw_session(RawCsiStopReason reason) override
```

 

Stop the active raw session and close its binary socket.

  

The stopped callback is delivered by [loop()](#classespectre_1_1_esp_idf_direct_http_service_1abbe2a278b424a1165475d8ffca79b78a), or synchronously while [shutdown()](#classespectre_1_1_esp_idf_direct_http_service_1a69bb753b2d9164edb8e4103810dff6d0) completes on the owning frontend task.

  

<a id="classespectre_1_1_esp_idf_direct_http_service_1a6526110c0aa5da0fb3811dbdd53e20a7"></a>

### `offer_raw_packet`


```cpp
bool espectre::EspIdfDirectHttpService::offer_raw_packet(const RawCsiPacketView &packet) override
```

 

Copy one callback-scoped sample into the transport's bounded raw slots.

   

<a id="classespectre_1_1_esp_idf_direct_http_service_1af5f94e87f550721eca27dbbe0fda720a"></a>

### `raw_diagnostics`


```cpp
RawCsiSessionDiagnostics espectre::EspIdfDirectHttpService::raw_diagnostics() const override
```

   


<a id="classespectre_1_1_esp_idf_mqtt_transport"></a>

## espectre::EspIdfMqttTransport



```cpp
#include <runtime/esp_idf/mqtt_transport_esp_idf.h>
```



```cpp
class espectre::EspIdfMqttTransport : public espectre::IMqttTransport
```

  [`espectre::IMqttTransport`](#classespectre_1_1_i_mqtt_transport)



<a id="classespectre_1_1_esp_idf_mqtt_transport_1a2da630d0212338987259bff4a10a9d80"></a>

### `setup`


```cpp
bool espectre::EspIdfMqttTransport::setup(const EspectreDeviceConfig &config) override
```

 

Configure and start connecting.

  

Asynchronous: true means the client started, not that it reached the broker. Wait for the connection callback before expecting publishes to land. Calling it again reconfigures and tears down the previous client.

 

**Returns:** false when the configuration cannot produce a client, such as an empty [`EspectreDeviceConfig::mqtt_host`](#structespectre_1_1_espectre_device_config_1a6bc7843ffc079108684b040e77b59c89).

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1aec31bc8f488bfc7a6b72555a29fc3b3b"></a>

### `loop`


```cpp
void espectre::EspIdfMqttTransport::loop() override
```

 

Pump the client and dispatch callbacks.

  

Called from the frontend loop.

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1a273e04c6fb334df6d1c4e479f8a1e4b3"></a>

### `shutdown`


```cpp
void espectre::EspIdfMqttTransport::shutdown() override
```

 

Disconnect and release resources.

  

Safe to repeat.

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1afa5c443e6863e93a2dd9f32f2e613f35"></a>

### `connected`


```cpp
bool espectre::EspIdfMqttTransport::connected() const override
```

 

True while the broker connection is established.

   

<a id="classespectre_1_1_esp_idf_mqtt_transport_1af284c13242edeeff5b8b3d886cc65579"></a>

### `publish`


```cpp
bool espectre::EspIdfMqttTransport::publish(const std::string &topic, const std::string &payload, bool retain) override
```

 

Publish to an absolute topic.

  

**Parameters**

- `topic`: Full topic name, not a suffix.
- `payload`: Message body, copied before returning.
- `retain`: Ask the broker to retain the message, for state a late subscriber must still see, such as availability.

 

**Returns:** false when disconnected or the bounded publish queue rejects the message. Published at QoS 0, so true means queued locally, not delivered to the broker.

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1a67952e68321ad9cdcfc1b82622ec3a7b"></a>

### `publish_suffix`


```cpp
bool espectre::EspIdfMqttTransport::publish_suffix(const char *suffix, const std::string &payload, bool retain) override
```

 

Publish under this device's protocol topic prefix.

  

The prefix comes from the [`EspectreDeviceConfig`](#structespectre_1_1_espectre_device_config) passed to [`setup()`](#classespectre_1_1_esp_idf_mqtt_transport_1a2da630d0212338987259bff4a10a9d80), so callers pass only the trailing segment, for example `"motion"`.

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1a8cec31260ab4daf4f66751350c8ca667"></a>

### `subscribe`


```cpp
bool espectre::EspIdfMqttTransport::subscribe(const std::string &topic, MessageCallback callback) override
```

 

Register a topic and its handler.

  

Idempotent per topic: subscribing again replaces the handler. May be called before the connection is up; the subscription is issued on connect.

 

**Returns:** false for an empty topic or an empty callback.

  

<a id="classespectre_1_1_esp_idf_mqtt_transport_1aa7f6deb4f262fc2c1ec7afccfeb1200e"></a>

### `set_command_callback`


```cpp
void espectre::EspIdfMqttTransport::set_command_callback(CommandCallback callback) override
```

 

Handler for the device command topic, which the transport subscribes itself.

   

<a id="classespectre_1_1_esp_idf_mqtt_transport_1afb71bdbc4863a47767a5007d654c3b95"></a>

### `set_connection_callback`


```cpp
void espectre::EspIdfMqttTransport::set_connection_callback(ConnectionCallback callback) override
```

 

Handler for connection state changes, including reconnects.

   

<a id="classespectre_1_1_esp_idf_mqtt_transport_1a3a2d1e7ab0d60a4e392bd2fc79b4eddb"></a>

### `diagnostics`


```cpp
MqttTransportDiagnostics espectre::EspIdfMqttTransport::diagnostics() const override
```

 

Bounded outbound queue, drop, failure, and reconnect counters.

   


<a id="classespectre_1_1_esp_idf_peer_discovery_service"></a>

## espectre::EspIdfPeerDiscoveryService



```cpp
#include <runtime/esp_idf/peer_discovery_service_esp_idf.h>
```



```cpp
class espectre::EspIdfPeerDiscoveryService : public espectre::IPeerDiscoveryService
```

  [`espectre::IPeerDiscoveryService`](#classespectre_1_1_i_peer_discovery_service)



<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a40d1c980ae37e291ab24d88d201b757c"></a>

### `~EspIdfPeerDiscoveryService`


```cpp
espectre::EspIdfPeerDiscoveryService::~EspIdfPeerDiscoveryService() override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1ac001c1c13c4cbf01a9c6f27c1f422ad9"></a>

### `set_local_candidate`


```cpp
void espectre::EspIdfPeerDiscoveryService::set_local_candidate(PeerDiscoveryCandidate candidate) override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a7e51c6f94d43415b96582ea34fdf2f72"></a>

### `set_wifi_ready`


```cpp
void espectre::EspIdfPeerDiscoveryService::set_wifi_ready(bool ready) override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a147df34c433a40e27398f15c86fe821a"></a>

### `ready`


```cpp
bool espectre::EspIdfPeerDiscoveryService::ready() const override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a7cfe6e21dbfb5bd468d11c133256228b"></a>

### `active`


```cpp
bool espectre::EspIdfPeerDiscoveryService::active() const override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a8dcaf36dcea15b9bbe995f8c9914d62c"></a>

### `start`


```cpp
bool espectre::EspIdfPeerDiscoveryService::start(Completion completion) override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1a24e9feb077b08613329dc00f73531a0f"></a>

### `loop`


```cpp
void espectre::EspIdfPeerDiscoveryService::loop() override
```

   

<a id="classespectre_1_1_esp_idf_peer_discovery_service_1ad1b83e460b89a31850f30dce514c1794"></a>

### `shutdown`


```cpp
void espectre::EspIdfPeerDiscoveryService::shutdown() override
```

   


<a id="structespectre_1_1_espectre_api_event_descriptor"></a>

## espectre::EspectreApiEventDescriptor



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreApiEventDescriptor
```

  

<a id="structespectre_1_1_espectre_api_event_descriptor_1a7a8c650cd6ccf9c4372ef17bc5b71c36"></a>

### `name`


```cpp
const char* espectre::EspectreApiEventDescriptor::name
```

   

<a id="structespectre_1_1_espectre_api_event_descriptor_1ace0597942f8c3f7cad93752cebf512e6"></a>

### `event`


```cpp
EspectreEvent espectre::EspectreApiEventDescriptor::event
```

   

<a id="structespectre_1_1_espectre_api_event_descriptor_1ab37408482a4f126a88e34f7cebf51bf3"></a>

### `capability`


```cpp
EspectreDirectMethod espectre::EspectreApiEventDescriptor::capability
```

   


<a id="structespectre_1_1_espectre_api_route"></a>

## espectre::EspectreApiRoute



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreApiRoute
```

 

One canonical HTTP/resource mapping used by routing and capability output.

  

<a id="structespectre_1_1_espectre_api_route_1aa9709d67003f68cf23436eac4af47c2e"></a>

### `http_method`


```cpp
const char* espectre::EspectreApiRoute::http_method
```

   

<a id="structespectre_1_1_espectre_api_route_1a6a3ed1667d54ee57d4f8fc708581fd4d"></a>

### `path`


```cpp
const char* espectre::EspectreApiRoute::path
```

   

<a id="structespectre_1_1_espectre_api_route_1a7d6922e283a7c596184408e5ed8d5173"></a>

### `name`


```cpp
const char* espectre::EspectreApiRoute::name
```

   

<a id="structespectre_1_1_espectre_api_route_1a4afdd946b5eb049671a273fcc8f5de23"></a>

### `command`


```cpp
const char* espectre::EspectreApiRoute::command
```

   

<a id="structespectre_1_1_espectre_api_route_1a6e59efe828f71299c8d903d0d4799952"></a>

### `capability`


```cpp
EspectreDirectMethod espectre::EspectreApiRoute::capability
```

   

<a id="structespectre_1_1_espectre_api_route_1aba7095f764f6e13917e91a3e0ea25999"></a>

### `kind`


```cpp
EspectreApiRouteKind espectre::EspectreApiRoute::kind
```

   

<a id="structespectre_1_1_espectre_api_route_1a028522628d85078d9bac937d34941959"></a>

### `asynchronous`


```cpp
bool espectre::EspectreApiRoute::asynchronous
```

   

<a id="structespectre_1_1_espectre_api_route_1aa2589bf5cb55b904bb69b14b75096f15"></a>

### `validate`


```cpp
EspectreCommandValidator espectre::EspectreApiRoute::validate {nullptr}
```

   


<a id="structespectre_1_1_espectre_capability_profile"></a>

## espectre::EspectreCapabilityProfile



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreCapabilityProfile
```

 

Exact Direct command, event, and readable-configuration surface advertised by a frontend.

  

<a id="structespectre_1_1_espectre_capability_profile_1a3754a33de52acb5734ddc4c97b01db6a"></a>

### `methods`


```cpp
std::array<bool, static_cast<size_t>(EspectreDirectMethod::COUNT)> espectre::EspectreCapabilityProfile::methods {}
```

   

<a id="structespectre_1_1_espectre_capability_profile_1a0b35ac4d5e323f6f33573c1d8ccbe418"></a>

### `config_sections`


```cpp
std::array<bool, static_cast<size_t>(EspectreConfigSection::COUNT)> espectre::EspectreCapabilityProfile::config_sections {}
```

   

<a id="structespectre_1_1_espectre_capability_profile_1aaa03a4984112db226532b8fdf554594e"></a>

### `events`


```cpp
std::array<bool, static_cast<size_t>(EspectreEvent::COUNT)> espectre::EspectreCapabilityProfile::events {{true, true, true, true, true}}
```

   

<a id="structespectre_1_1_espectre_capability_profile_1a06c2e9bb86e8d0a0cebddd4a0e138087"></a>

### `extension`


```cpp
const EspectreProtocolExtension* espectre::EspectreCapabilityProfile::extension {nullptr}
```

 

Optional frontend-owned catalog, shared with its transport parsers.

   


<a id="structespectre_1_1_espectre_capability_profile_1af6f094856d4f5e4108cb0751672c007f"></a>

### `supports`


```cpp
bool espectre::EspectreCapabilityProfile::supports(EspectreDirectMethod method) const
```

   

<a id="structespectre_1_1_espectre_capability_profile_1a19fd61ef7f0e7960ff2909a5f6243f2f"></a>

### `set`


```cpp
void espectre::EspectreCapabilityProfile::set(EspectreDirectMethod method, bool enabled=true)
```

   

<a id="structespectre_1_1_espectre_capability_profile_1acb8dbe5a2f5fc8bad1adbec8194105c0"></a>

### `has`


```cpp
bool espectre::EspectreCapabilityProfile::has(EspectreConfigSection section) const
```

   

<a id="structespectre_1_1_espectre_capability_profile_1a0b55fb321de02c836169680bf579c20c"></a>

### `set`


```cpp
void espectre::EspectreCapabilityProfile::set(EspectreConfigSection section, bool enabled=true)
```

   

<a id="structespectre_1_1_espectre_capability_profile_1ae2b3b98049b2856d1feb176c0b7ff19c"></a>

### `publishes`


```cpp
bool espectre::EspectreCapabilityProfile::publishes(EspectreEvent event) const
```

   

<a id="structespectre_1_1_espectre_capability_profile_1a6d960b939d2d7ed6753d984ae159ac58"></a>

### `set`


```cpp
void espectre::EspectreCapabilityProfile::set(EspectreEvent event, bool enabled=true)
```

   

<a id="structespectre_1_1_espectre_capability_profile_1aa8e981afc3beacf03785a5dd13580e14"></a>

### `clear_events`


```cpp
void espectre::EspectreCapabilityProfile::clear_events()
```

   


<a id="structespectre_1_1_espectre_command"></a>

## espectre::EspectreCommand



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreCommand
```

 

A parsed control command.

  

Fields are optional by design: each `has_*` flag says whether the peer actually sent that field, so an unset value is never confused with a zero the caller meant. Apply only the flagged fields.

 

<a id="structespectre_1_1_espectre_command_1ae9f9733cf3d838398d3f8ef2e34b0821"></a>

### `command_id`


```cpp
std::string espectre::EspectreCommand::command_id
```

 

Correlation id echoed in the result payload.

  

May be empty.

  

<a id="structespectre_1_1_espectre_command_1afd0d4b74c5d8fb75f1238fed99612bcd"></a>

### `command`


```cpp
std::string espectre::EspectreCommand::command
```

 

Command verb, for example `"update_sensing"` or `"recalibrate"`.

   

<a id="structespectre_1_1_espectre_command_1a04c58cb2c7dc527168ea428e33310164"></a>

### `diagnostic_fields`


```cpp
std::vector<std::string> espectre::EspectreCommand::diagnostic_fields
```

 

Diagnostic paths to return; empty requests the catalog, and \["\*"\] requests all values.

   

<a id="structespectre_1_1_espectre_command_1a56690f670653ae3479daf1c622dfb6d2"></a>

### `sensing_enabled`


```cpp
bool espectre::EspectreCommand::sensing_enabled {false}
```

 

Requested sensing-service state for `update_sensing`.

   

<a id="structespectre_1_1_espectre_command_1ab7fce7acc1aa3eaf54985c2e2fc30918"></a>

### `has_sensing_enabled`


```cpp
bool espectre::EspectreCommand::has_sensing_enabled {false}
```

   

<a id="structespectre_1_1_espectre_command_1a4a6f143d3f0aa6eac8daa17e7435f316"></a>

### `device_label`


```cpp
std::string espectre::EspectreCommand::device_label
```

 

User-facing label requested by `update_device`; empty clears it.

   

<a id="structespectre_1_1_espectre_command_1aa1fe0f3fe39cfcf457a736113b33a71e"></a>

### `has_device_label`


```cpp
bool espectre::EspectreCommand::has_device_label {false}
```

 

Whether the command carried a valid string-valued [`device_label`](#structespectre_1_1_espectre_command_1a4a6f143d3f0aa6eac8daa17e7435f316).

   

<a id="structespectre_1_1_espectre_command_1ad1c410f2a60ad18eb5a257b486be4fb2"></a>

### `threshold`


```cpp
float espectre::EspectreCommand::threshold {0.0f}
```

   

<a id="structespectre_1_1_espectre_command_1a29fe6ed5b45c203e74bc9a066ff829be"></a>

### `has_threshold`


```cpp
bool espectre::EspectreCommand::has_threshold {false}
```

   

<a id="structespectre_1_1_espectre_command_1a80157a00785372468fa10b0b07ca1c54"></a>

### `motion_on_hits`


```cpp
uint8_t espectre::EspectreCommand::motion_on_hits {0U}
```

   

<a id="structespectre_1_1_espectre_command_1aea051c66df201eda9db54461f910781e"></a>

### `motion_off_hits`


```cpp
uint8_t espectre::EspectreCommand::motion_off_hits {0U}
```

   

<a id="structespectre_1_1_espectre_command_1a4cfaaf9bd50ec4b32f10279c611694f2"></a>

### `has_motion_hits`


```cpp
bool espectre::EspectreCommand::has_motion_hits {false}
```

   

<a id="structespectre_1_1_espectre_command_1a844845cf89bee4e981b10445e3d7751a"></a>

### `csi_traffic_mode`


```cpp
std::string espectre::EspectreCommand::csi_traffic_mode
```

   

<a id="structespectre_1_1_espectre_command_1a311fccf7c7a3ace1c4fdf9349ee11378"></a>

### `has_csi_traffic_mode`


```cpp
bool espectre::EspectreCommand::has_csi_traffic_mode {false}
```

   

<a id="structespectre_1_1_espectre_command_1a216bdbeabae77df5241b82de126dbdb4"></a>

### `traffic_generator_mode`


```cpp
std::string espectre::EspectreCommand::traffic_generator_mode
```

   

<a id="structespectre_1_1_espectre_command_1a89245feb9fe935e4f9207fac6c52a379"></a>

### `has_traffic_generator_mode`


```cpp
bool espectre::EspectreCommand::has_traffic_generator_mode {false}
```

   

<a id="structespectre_1_1_espectre_command_1ad706b46d3d8a0128a06d88cfa7cbefbe"></a>

### `detector`


```cpp
std::string espectre::EspectreCommand::detector
```

   

<a id="structespectre_1_1_espectre_command_1a754b3484de80075b8fa2cc0ea435af1c"></a>

### `has_detector`


```cpp
bool espectre::EspectreCommand::has_detector {false}
```

   

<a id="structespectre_1_1_espectre_command_1a24c6d08b3dacb6745b4c398b2c041234"></a>

### `wifi_bssid`


```cpp
std::string espectre::EspectreCommand::wifi_bssid
```

   

<a id="structespectre_1_1_espectre_command_1a8d345b5004accd98a6c536e34ccfc212"></a>

### `has_wifi_bssid`


```cpp
bool espectre::EspectreCommand::has_wifi_bssid {false}
```

   

<a id="structespectre_1_1_espectre_command_1a269c13bff465eca13b5a9218a238cc15"></a>

### `wifi_bssid_force`


```cpp
bool espectre::EspectreCommand::wifi_bssid_force {false}
```

 

Force reassociation even when [`wifi_bssid`](#structespectre_1_1_espectre_command_1a24c6d08b3dacb6745b4c398b2c041234) is already active.

   

<a id="structespectre_1_1_espectre_command_1a6e9584841c1b52066a4d4ea1fb84e14a"></a>

### `has_wifi_bssid_force`


```cpp
bool espectre::EspectreCommand::has_wifi_bssid_force {false}
```

   

<a id="structespectre_1_1_espectre_command_1a80590239b5b628431a94e8a94f881fc8"></a>

### `mqtt_scheme`


```cpp
std::string espectre::EspectreCommand::mqtt_scheme
```

   

<a id="structespectre_1_1_espectre_command_1a6ccd1af691634288857285ddef21ce43"></a>

### `mqtt_host`


```cpp
std::string espectre::EspectreCommand::mqtt_host
```

   

<a id="structespectre_1_1_espectre_command_1a578d1b64dc9bfecad0b7d2acc5ebdc10"></a>

### `mqtt_username`


```cpp
std::string espectre::EspectreCommand::mqtt_username
```

   

<a id="structespectre_1_1_espectre_command_1a4462672aafd9991d02ccec4897ab31c8"></a>

### `mqtt_password`


```cpp
std::string espectre::EspectreCommand::mqtt_password
```

   

<a id="structespectre_1_1_espectre_command_1a88fdc71c132a8589fc5dd0a62ef2458a"></a>

### `mqtt_topic_prefix`


```cpp
std::string espectre::EspectreCommand::mqtt_topic_prefix
```

   

<a id="structespectre_1_1_espectre_command_1a970cc86b87aa22ed74f7d1761187ad27"></a>

### `mqtt_port`


```cpp
uint16_t espectre::EspectreCommand::mqtt_port {0U}
```

   

<a id="structespectre_1_1_espectre_command_1ae6b2b6b7f272b8168fccba36e046c4b7"></a>

### `has_mqtt_scheme`


```cpp
bool espectre::EspectreCommand::has_mqtt_scheme {false}
```

   

<a id="structespectre_1_1_espectre_command_1a483cee09f1e344a19ab61f85519b37b6"></a>

### `has_mqtt_host`


```cpp
bool espectre::EspectreCommand::has_mqtt_host {false}
```

   

<a id="structespectre_1_1_espectre_command_1ae7ba0aa42d1640c1a059992e9f3e5ad3"></a>

### `has_mqtt_username`


```cpp
bool espectre::EspectreCommand::has_mqtt_username {false}
```

   

<a id="structespectre_1_1_espectre_command_1a3622a2d30ac29af8409fd070dddb09c3"></a>

### `has_mqtt_password`


```cpp
bool espectre::EspectreCommand::has_mqtt_password {false}
```

   

<a id="structespectre_1_1_espectre_command_1aa5b9810294f426dd4f8e3b48abd810d9"></a>

### `has_mqtt_topic_prefix`


```cpp
bool espectre::EspectreCommand::has_mqtt_topic_prefix {false}
```

   

<a id="structespectre_1_1_espectre_command_1ac25f88011125cec697bd5a3cf2fd9067"></a>

### `has_mqtt_port`


```cpp
bool espectre::EspectreCommand::has_mqtt_port {false}
```

   

<a id="structespectre_1_1_espectre_command_1aec085c9f5943af0864d214935cd6c08e"></a>

### `extension_parameters`


```cpp
std::string espectre::EspectreCommand::extension_parameters
```

 

JSON parameters for a frontend extension command.

  

Initially the original request (including the MQTT envelope); its validator may normalize them.

  


<a id="structespectre_1_1_espectre_device_config"></a>

## espectre::EspectreDeviceConfig



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreDeviceConfig
```

 

Device identity and broker settings.

  

Frontends persist this so a device keeps its identity and connection across reboots and reprovisioning.

 

<a id="structespectre_1_1_espectre_device_config_1a81f5bcd174ba6f52c81481ce172d274a"></a>

### `device_id`


```cpp
uint64_t espectre::EspectreDeviceConfig::device_id {ESPECTRE_DEFAULT_DEVICE_ID}
```

 

Stable device identity.

  

Zero means use the runtime-generated value.

  

<a id="structespectre_1_1_espectre_device_config_1aca7110074cb8deafe9fc8653dd2ded4f"></a>

### `device_label`


```cpp
std::string espectre::EspectreDeviceConfig::device_label {ESPECTRE_DEFAULT_DEVICE_LABEL}
```

 

Human-readable name.

  

Empty falls back to the formatted device id.

  

<a id="structespectre_1_1_espectre_device_config_1add9bc633f1f75f7c12ddf44d83965335"></a>

### `mqtt_scheme`


```cpp
std::string espectre::EspectreDeviceConfig::mqtt_scheme
```

 

Broker transport scheme: `mqtt` or `mqtts`.

  

Empty disables MQTT.

  

<a id="structespectre_1_1_espectre_device_config_1a6bc7843ffc079108684b040e77b59c89"></a>

### `mqtt_host`


```cpp
std::string espectre::EspectreDeviceConfig::mqtt_host
```

 

Broker DNS hostname, IPv4 address, or IPv6 address, without URI framing.

   

<a id="structespectre_1_1_espectre_device_config_1ac8aed6d2ebbe21bfc26583502a705f75"></a>

### `mqtt_port`


```cpp
uint16_t espectre::EspectreDeviceConfig::mqtt_port {0U}
```

 

Broker port.

  

Zero means MQTT is not configured.

  

<a id="structespectre_1_1_espectre_device_config_1aaedefcaaec63f7b9bf2d46e69be0e6cb"></a>

### `mqtt_username`


```cpp
std::string espectre::EspectreDeviceConfig::mqtt_username
```

 

Broker credentials.

  

Leave empty for anonymous brokers.

  

<a id="structespectre_1_1_espectre_device_config_1afe6956ffef02ae5a6a5b807c3fbe47cc"></a>

### `mqtt_password`


```cpp
std::string espectre::EspectreDeviceConfig::mqtt_password
```

   

<a id="structespectre_1_1_espectre_device_config_1ae89cde8ec77492cd8dd8fb315206630f"></a>

### `topic_prefix`


```cpp
std::string espectre::EspectreDeviceConfig::topic_prefix {ESPECTRE_TOPIC_PREFIX}
```

 

Topic root.

  

Change it only if you also change every consumer.

  


<a id="structespectre_1_1_espectre_device_info"></a>

## espectre::EspectreDeviceInfo



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreDeviceInfo
```

 

What the device advertises about itself.

  

The `supports_*` flags are internal inputs used to build the filtered `capabilities` catalog. They are deliberately omitted from `info` so clients have one authoritative feature-discovery surface.

 

<a id="structespectre_1_1_espectre_device_info_1a98e0874253f5cc0a4fb98aaa26ecfcab"></a>

### `frontend`


```cpp
std::string espectre::EspectreDeviceInfo::frontend {"unknown"}
```

 

Frontend name, for example `"native"`, `"matter"`, or your own.

   

<a id="structespectre_1_1_espectre_device_info_1a30cedb7142b425b1a8e7ad27840191d1"></a>

### `firmware_version`


```cpp
std::string espectre::EspectreDeviceInfo::firmware_version {"unknown"}
```

 

Application version supplied by the frontend or integrator.

   

<a id="structespectre_1_1_espectre_device_info_1ac0ea5c264b21400d093ec20f44c690a9"></a>

### `chip`


```cpp
std::string espectre::EspectreDeviceInfo::chip {"unknown"}
```

 

Chip target, normally `CONFIG_IDF_TARGET`.

   

<a id="structespectre_1_1_espectre_device_info_1afeac4f05b3c3cc10e8db70d07ce07aab"></a>

### `detector`


```cpp
std::string espectre::EspectreDeviceInfo::detector
```

 

Active detector.

  

Left empty, it is filled from the snapshot.

  

<a id="structespectre_1_1_espectre_device_info_1a8cb8d65d9f6669566e70928e93bd8428"></a>

### `csi_profile`


```cpp
std::string espectre::EspectreDeviceInfo::csi_profile
```

 

Automatically selected CSI capture profile.

  

Left empty, it is filled from the snapshot.

  

<a id="structespectre_1_1_espectre_device_info_1a372030a3cb91330001da9723f4398247"></a>

### `supports_info`


```cpp
bool espectre::EspectreDeviceInfo::supports_info {true}
```

   

<a id="structespectre_1_1_espectre_device_info_1a437aec304310ffbadb7ed306345486f7"></a>

### `supports_diagnostics`


```cpp
bool espectre::EspectreDeviceInfo::supports_diagnostics {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1a3d5ea9c20ebbdf08c195ebf44860af6d"></a>

### `supports_device_config`


```cpp
bool espectre::EspectreDeviceInfo::supports_device_config {false}
```

 

`update_device` is honored and persists the user-facing label.

   

<a id="structespectre_1_1_espectre_device_info_1ac71dfcd58f5a2e8acc8496b742789344"></a>

### `supports_runtime_threshold`


```cpp
bool espectre::EspectreDeviceInfo::supports_runtime_threshold {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1aa5dc916c596456bf20292c70a0ff57d3"></a>

### `supports_runtime_motion_hits`


```cpp
bool espectre::EspectreDeviceInfo::supports_runtime_motion_hits {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1a1dc9fa2a45b8c5264b74378f5a62a0de"></a>

### `supports_runtime_detector`


```cpp
bool espectre::EspectreDeviceInfo::supports_runtime_detector {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1a7cf705f7ef81bc61231f21342ead22ae"></a>

### `supports_manual_recalibration`


```cpp
bool espectre::EspectreDeviceInfo::supports_manual_recalibration {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1ab96702463074b99a02d75e8448457920"></a>

### `supports_traffic_control`


```cpp
bool espectre::EspectreDeviceInfo::supports_traffic_control {false}
```

   

<a id="structespectre_1_1_espectre_device_info_1acec4d08e5d838218079beb88d7a33953"></a>

### `csi_traffic_mode`


```cpp
std::string espectre::EspectreDeviceInfo::csi_traffic_mode
```

 

CSI traffic ownership mode: `"internal"` or `"external"`.

  

Omitted from `info` when empty. Sensing MQTT frontends that own traffic control fill it.

  

<a id="structespectre_1_1_espectre_device_info_1a1ae5306a262f1fceb0ace63065f3319a"></a>

### `traffic_mode`


```cpp
std::string espectre::EspectreDeviceInfo::traffic_mode
```

 

Internal traffic generator mode: `"ping"`, `"dns"`, `"dns_tcp"`, or `"wifi_raw"`.

  

Omitted from `info` when empty.

  

<a id="structespectre_1_1_espectre_device_info_1a9c6cd13342039c01196f9daa1bcf923b"></a>

### `csi_target_pps`


```cpp
uint32_t espectre::EspectreDeviceInfo::csi_target_pps {0U}
```

 

Internal traffic generator and temporal-grid target rate, in packets per second.

  

Omitted from `info` when zero.

  

<a id="structespectre_1_1_espectre_device_info_1addb54a961ad4acc29e410accb302b7f3"></a>

### `csi_traffic_udp_port`


```cpp
uint16_t espectre::EspectreDeviceInfo::csi_traffic_udp_port {0U}
```

 

UDP destination port used by the external CSI traffic generator.

   

<a id="structespectre_1_1_espectre_device_info_1a5e0e130624c638beeb2ca61c619bdecd"></a>

### `csi_traffic_multicast_group`


```cpp
std::string espectre::EspectreDeviceInfo::csi_traffic_multicast_group
```

 

IPv4 multicast group used by external CSI traffic, or empty for unicast-only operation.

   

<a id="structespectre_1_1_espectre_device_info_1a3dd182a7125e610e68f7158e3c09e20e"></a>

### `evaluation_interval_ms`


```cpp
uint32_t espectre::EspectreDeviceInfo::evaluation_interval_ms {0U}
```

 

Detector evaluation cadence, in milliseconds.

  

Omitted from `info` when zero. Canonical MQTT telemetry follows this interval.

  

<a id="structespectre_1_1_espectre_device_info_1a538ad375d04edaca9dc2fad775a23bf0"></a>

### `network`


```cpp
EspectreNetworkInfo espectre::EspectreDeviceInfo::network {}
```

   


<a id="structespectre_1_1_espectre_extension_route"></a>

## espectre::EspectreExtensionRoute



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreExtensionRoute
```

 

One frontend-owned route, shared by capability output and both transports.

  

<a id="structespectre_1_1_espectre_extension_route_1aab83e58cb053c7bb88f5c757f3ffdcb7"></a>

### `http_method`


```cpp
const char* espectre::EspectreExtensionRoute::http_method
```

   

<a id="structespectre_1_1_espectre_extension_route_1a11999df7cabf53bee4cd44e705f3b5ed"></a>

### `path`


```cpp
const char* espectre::EspectreExtensionRoute::path
```

   

<a id="structespectre_1_1_espectre_extension_route_1acb880c342282379b5504f90d611dd6e6"></a>

### `name`


```cpp
const char* espectre::EspectreExtensionRoute::name
```

   

<a id="structespectre_1_1_espectre_extension_route_1a283adbd2404039858219bb25b22c219e"></a>

### `command`


```cpp
const char* espectre::EspectreExtensionRoute::command
```

   

<a id="structespectre_1_1_espectre_extension_route_1a63477d3373b59335ed35c7fc30d44de7"></a>

### `kind`


```cpp
EspectreApiRouteKind espectre::EspectreExtensionRoute::kind
```

   

<a id="structespectre_1_1_espectre_extension_route_1a6259d196f36470a17e7c8e9833c6d609"></a>

### `asynchronous`


```cpp
bool espectre::EspectreExtensionRoute::asynchronous {false}
```

   

<a id="structespectre_1_1_espectre_extension_route_1a63cb47c8281f9d461f8c74c046a874af"></a>

### `mqtt`


```cpp
bool espectre::EspectreExtensionRoute::mqtt {false}
```

 

Whether the frontend command binding permits invocation over MQTT.

   

<a id="structespectre_1_1_espectre_extension_route_1a241fd946420c88d2acc33b131ca8fd17"></a>

### `allowed_during_raw_collection`


```cpp
bool espectre::EspectreExtensionRoute::allowed_during_raw_collection {false}
```

   

<a id="structespectre_1_1_espectre_extension_route_1a6d826025d23f40a66dbe03639c4d4f02"></a>

### `validate`


```cpp
EspectreCommandValidator espectre::EspectreExtensionRoute::validate {nullptr}
```

   


<a id="structespectre_1_1_espectre_network_info"></a>

## espectre::EspectreNetworkInfo



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreNetworkInfo
```

 

Link details available to frontends.

  

Canonical MQTT info publishes only the channel.

 

<a id="structespectre_1_1_espectre_network_info_1a539c43609365b6dc97ca3a953545b8a5"></a>

### `ip_address`


```cpp
std::string espectre::EspectreNetworkInfo::ip_address
```

   

<a id="structespectre_1_1_espectre_network_info_1abd4271a4c76579a0d556462cadd32ccf"></a>

### `mac_address`


```cpp
std::string espectre::EspectreNetworkInfo::mac_address
```

   

<a id="structespectre_1_1_espectre_network_info_1afb3afd351ae9f6c2fe654e23557b2130"></a>

### `channel`


```cpp
uint8_t espectre::EspectreNetworkInfo::channel {0U}
```

 

Wi-Fi channel in use.

  

Zero when unknown.

  


<a id="structespectre_1_1_espectre_protocol_extension"></a>

## espectre::EspectreProtocolExtension



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
struct espectre::EspectreProtocolExtension
```

 

Immutable frontend additions.

  

Keep this object alive while adapters use it.

 

<a id="structespectre_1_1_espectre_protocol_extension_1a09ee85f8d1fe38009b808ff420b13476"></a>

### `routes`


```cpp
std::vector<EspectreExtensionRoute> espectre::EspectreProtocolExtension::routes
```

   

<a id="structespectre_1_1_espectre_protocol_extension_1abcc84f7a49add2cd410f5a8d60de2b76"></a>

### `events`


```cpp
std::vector<std::string> espectre::EspectreProtocolExtension::events
```

   


<a id="structespectre_1_1_frontend_command_context"></a>

## espectre::FrontendCommandContext



```cpp
#include <runtime/frontend_command_engine.h>
```



```cpp
struct espectre::FrontendCommandContext
```

  

<a id="structespectre_1_1_frontend_command_context_1afa2f9a45ea6a720e082bbc48dedcc414"></a>

### `origin`


```cpp
FrontendCommandOrigin espectre::FrontendCommandContext::origin {FrontendCommandOrigin::DIRECT}
```

   

<a id="structespectre_1_1_frontend_command_context_1ab5e3b6101f580199bbf31688f2514d4e"></a>

### `connection_token`


```cpp
uint64_t espectre::FrontendCommandContext::connection_token {0U}
```

 

Opaque request identity used only to complete deferred Direct responses.

   


<a id="classespectre_1_1_frontend_command_engine"></a>

## espectre::FrontendCommandEngine



```cpp
#include <runtime/frontend_command_engine.h>
```



```cpp
class espectre::FrontendCommandEngine
```

  

<a id="classespectre_1_1_frontend_command_engine_1a3a2f4759bb0ec4c400bb661904c3ca8a"></a>

### `execute`


```cpp
FrontendCommandResult espectre::FrontendCommandEngine::execute(const EspectreCommand &command, const FrontendCommandContext &context, const FrontendCommandCapabilities &capabilities, FrontendReadPayloadCallback read_payload_callback, FrontendDeviceLabelCallback device_label_callback={}, FrontendThresholdCallback threshold_callback={}, FrontendMotionHitsCallback motion_hits_callback={}, FrontendCsiTrafficModeCallback csi_traffic_mode_callback={}, FrontendTrafficGeneratorModeCallback traffic_generator_mode_callback={}, FrontendDetectorCallback detector_callback={}, FrontendRecalibrateCallback recalibrate_callback={}, FrontendWifiBssidCallback wifi_bssid_callback={}, FrontendMqttConfigCallback mqtt_config_callback={}, FrontendSensingControlCallback sensing_control_callback={}, FrontendRawStreamCallback raw_stream_callback={}) const
```

 

Execute a successfully parsed command.

  

Call a protocol parser first; this dispatcher checks capabilities and operational state, not parameters.

  


<a id="structespectre_1_1_frontend_command_result"></a>

## espectre::FrontendCommandResult



```cpp
#include <runtime/frontend_command_engine.h>
```



```cpp
struct espectre::FrontendCommandResult
```

  

<a id="structespectre_1_1_frontend_command_result_1a4b54953067c0b0fcd0b038c252ed18d3"></a>

### `handled`


```cpp
bool espectre::FrontendCommandResult::handled {false}
```

   

<a id="structespectre_1_1_frontend_command_result_1a10179374b91551f82aa42c753ac91d4d"></a>

### `accepted`


```cpp
bool espectre::FrontendCommandResult::accepted {false}
```

   

<a id="structespectre_1_1_frontend_command_result_1a35b941acfbc8f0a40cd71fc4444eaa2d"></a>

### `command`


```cpp
EspectreCommand espectre::FrontendCommandResult::command {}
```

   

<a id="structespectre_1_1_frontend_command_result_1a054a49799aafb67785fc8e45f08b14c8"></a>

### `code`


```cpp
std::string espectre::FrontendCommandResult::code {"internal_error"}
```

   

<a id="structespectre_1_1_frontend_command_result_1ab145d66eabc6ed3afd21183d93aecb23"></a>

### `message`


```cpp
std::string espectre::FrontendCommandResult::message
```

   

<a id="structespectre_1_1_frontend_command_result_1a5fad97cea2c08b2568ecd4e6a10a1f9b"></a>

### `data_json`


```cpp
std::string espectre::FrontendCommandResult::data_json
```

   

<a id="structespectre_1_1_frontend_command_result_1ac0e7393f21c05867f32f9678701a4fc6"></a>

### `changes`


```cpp
FrontendCommandChange espectre::FrontendCommandResult::changes {FrontendCommandChange::NONE}
```

   


<a id="structespectre_1_1_frontend_device_config_defaults"></a>

## espectre::FrontendDeviceConfigDefaults



```cpp
#include <runtime/esp_idf/frontend_bootstrap_helpers.h>
```



```cpp
struct espectre::FrontendDeviceConfigDefaults
```

  

<a id="structespectre_1_1_frontend_device_config_defaults_1a659cf3e49fbec2b285fef4fe3189c312"></a>

### `device_label`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::device_label {ESPECTRE_DEFAULT_DEVICE_LABEL}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1a85e6cdbfc4f4af2a7500bbe9445a1c64"></a>

### `mqtt_scheme`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::mqtt_scheme {""}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1a0cd73628ab466d42f4ede69287d42baa"></a>

### `mqtt_host`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::mqtt_host {""}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1ad2fc4516ea752d9bdf04a988edd4455b"></a>

### `mqtt_port`


```cpp
uint16_t espectre::FrontendDeviceConfigDefaults::mqtt_port {0U}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1ab2f2dfda15610082bab1c9ac3e032419"></a>

### `mqtt_username`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::mqtt_username {""}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1aa47a74274c8531654ba4df1df3f18ca3"></a>

### `mqtt_password`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::mqtt_password {""}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1a08565e041545e1d904857ee8a2326657"></a>

### `topic_prefix`


```cpp
const char* espectre::FrontendDeviceConfigDefaults::topic_prefix {ESPECTRE_TOPIC_PREFIX}
```

   

<a id="structespectre_1_1_frontend_device_config_defaults_1a1dcf1af494b14b5fde944157b30cf0ec"></a>

### `runtime_device_id`


```cpp
uint64_t espectre::FrontendDeviceConfigDefaults::runtime_device_id {0U}
```

   


<a id="structespectre_1_1_frontend_ha_diagnostic_sensor"></a>

## espectre::FrontendHaDiagnosticSensor



```cpp
#include <runtime/esp_idf/frontend_ha_mqtt_helpers.h>
```



```cpp
struct espectre::FrontendHaDiagnosticSensor
```

  

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a80fae5ab7d6d680529e1660f032d4ec8"></a>

### `name`


```cpp
std::string espectre::FrontendHaDiagnosticSensor::name
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a7ba7f5fbb9a271e618e1e69c670fdb72"></a>

### `key`


```cpp
std::string espectre::FrontendHaDiagnosticSensor::key
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a99372960224bd99cdf6099536c7180ee"></a>

### `object_id`


```cpp
std::string espectre::FrontendHaDiagnosticSensor::object_id
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a525e99d2d157a616b7f33fa17a4d43b7"></a>

### `state_topic`


```cpp
std::string espectre::FrontendHaDiagnosticSensor::state_topic
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a1e54481a565bb28da66564cc0a48575a"></a>

### `unit_of_measurement`


```cpp
const char* espectre::FrontendHaDiagnosticSensor::unit_of_measurement {nullptr}
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a68c00ff8cadb583266de1caf36b5a266"></a>

### `icon`


```cpp
const char* espectre::FrontendHaDiagnosticSensor::icon {nullptr}
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a84271971a0ad39ca08bf322ec9aacf9f"></a>

### `device_class`


```cpp
const char* espectre::FrontendHaDiagnosticSensor::device_class {nullptr}
```

   

<a id="structespectre_1_1_frontend_ha_diagnostic_sensor_1a88db374adaa551c9be06b4ef2614bec8"></a>

### `state_class_measurement`


```cpp
bool espectre::FrontendHaDiagnosticSensor::state_class_measurement {true}
```

   


<a id="structespectre_1_1_frontend_ha_discovery_message"></a>

## espectre::FrontendHaDiscoveryMessage



```cpp
#include <runtime/esp_idf/frontend_ha_mqtt_helpers.h>
```



```cpp
struct espectre::FrontendHaDiscoveryMessage
```

  

<a id="structespectre_1_1_frontend_ha_discovery_message_1a4e6b8493b03cc44a2bf674e83902cf22"></a>

### `topic`


```cpp
std::string espectre::FrontendHaDiscoveryMessage::topic
```

   

<a id="structespectre_1_1_frontend_ha_discovery_message_1abbf9846a07b76ef77dded5eff7fe2f9a"></a>

### `payload`


```cpp
std::string espectre::FrontendHaDiscoveryMessage::payload
```

   


<a id="structespectre_1_1_frontend_ha_mqtt_settings"></a>

## espectre::FrontendHaMqttSettings



```cpp
#include <runtime/esp_idf/frontend_ha_mqtt_helpers.h>
```



```cpp
struct espectre::FrontendHaMqttSettings
```

  

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a8d698ae0b479152a1541b2feee8c5b3e"></a>

### `discovery_prefix`


```cpp
std::string espectre::FrontendHaMqttSettings::discovery_prefix
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a7fb79e719d7e2d266759eaea05872c96"></a>

### `birth_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::birth_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1afded0cf1d681651914d115c267433088"></a>

### `availability_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::availability_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a1eab8acce95aa4a8a473bbb28383c4d4"></a>

### `availability_template`


```cpp
std::string espectre::FrontendHaMqttSettings::availability_template
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a6a46b306d5abd7cbe82652b88c607205"></a>

### `motion_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a3e9bb24b6ad400338516faf8c35cec1d"></a>

### `movement_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::movement_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a3062c20e610a4ad68e7afe7e850eeaa2"></a>

### `threshold_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::threshold_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a18fbd90a2a3ed2797ce8186f897a0fb3"></a>

### `threshold_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::threshold_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1acf6152f879910c7705e18a7608c1e5cb"></a>

### `motion_on_hits_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_on_hits_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1adf56175738267c11e5b760432603a681"></a>

### `motion_on_hits_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_on_hits_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a6e05ea3194206028b4f93e5d8de0450e"></a>

### `motion_off_hits_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_off_hits_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a26333e2e6f2475429d48a86be0373594"></a>

### `motion_off_hits_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_off_hits_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a22d72ad7a8c2b4fd8904dcfa2418ef8f"></a>

### `calibrate_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::calibrate_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a14ac2de9442389a5861f906465276415"></a>

### `calibrate_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::calibrate_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a9cda7589d40fc3547e29c496d6e02997"></a>

### `detector_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::detector_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a9a985fb5bb45df15025428de5cf0bfbe"></a>

### `detector_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::detector_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1ad6a47d767aebc5d4086a2a48a82c5a44"></a>

### `csi_traffic_mode_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::csi_traffic_mode_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a49aa56cba260432101534c7a973d42de"></a>

### `csi_traffic_mode_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::csi_traffic_mode_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a9e81fc2b48889395da591a07b413b9ef"></a>

### `traffic_generator_mode_state_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::traffic_generator_mode_state_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a5e2c007cec86c2dcb03bf49781dc3d99"></a>

### `traffic_generator_mode_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::traffic_generator_mode_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a1e97a2be49e37b392da23d3093eddfd5"></a>

### `diagnostics_command_topic`


```cpp
std::string espectre::FrontendHaMqttSettings::diagnostics_command_topic
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1aebd7206ac2646bf74d76a78d9e8ed9ba"></a>

### `motion_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a0773e6e2399eb64fa91338f1da547b49"></a>

### `movement_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::movement_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a99b35971b177319b3037efa2ec0c3488"></a>

### `threshold_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::threshold_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1afa3ec3555092976c40b2216d58a377ca"></a>

### `motion_on_hits_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_on_hits_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1aac2915ea47c9dc2db666ae0abc668343"></a>

### `motion_off_hits_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::motion_off_hits_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a8ae34e66f2421743caf648499f1b1219"></a>

### `recalibrate_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::recalibrate_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a678649c91fad8ca213e0f25e0584ff4f"></a>

### `calibration_active_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::calibration_active_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a28772a882f61bba32dcc296ca2cf3c80"></a>

### `detector_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::detector_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a7aaf4b1f557a7f24b4a9edffcb7dc117"></a>

### `csi_traffic_mode_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::csi_traffic_mode_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1aadd5e5d5490b416e8592d69c079da520"></a>

### `traffic_generator_mode_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::traffic_generator_mode_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a80c4edcf18fa2eef5e66d9b437fd533d"></a>

### `diagnostics_object_id`


```cpp
std::string espectre::FrontendHaMqttSettings::diagnostics_object_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a5bf72ba04e894026945f7e412c9c410c"></a>

### `ha_object_prefix`


```cpp
std::string espectre::FrontendHaMqttSettings::ha_object_prefix
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a85a914412682eb7c3ff096355f7a40a7"></a>

### `diagnostic_sensors`


```cpp
std::vector<FrontendHaDiagnosticSensor> espectre::FrontendHaMqttSettings::diagnostic_sensors
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1abf85200e68fefd3aa06ec76013271550"></a>

### `device_id`


```cpp
std::string espectre::FrontendHaMqttSettings::device_id
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a5cf153b3ccf9a024f2d677ef7a9d892d"></a>

### `device_name`


```cpp
std::string espectre::FrontendHaMqttSettings::device_name
```

   

<a id="structespectre_1_1_frontend_ha_mqtt_settings_1a3293eeda4743499c6db7d62d3f4dece6"></a>

### `model`


```cpp
std::string espectre::FrontendHaMqttSettings::model
```

   


<a id="structespectre_1_1_frontend_wifi_station_options"></a>

## espectre::FrontendWifiStationOptions



```cpp
#include <runtime/esp_idf/frontend_bootstrap_helpers.h>
```



```cpp
struct espectre::FrontendWifiStationOptions
```

  

<a id="structespectre_1_1_frontend_wifi_station_options_1a206bffdeb0c807a05829aef07201b18e"></a>

### `ssid`


```cpp
const char* espectre::FrontendWifiStationOptions::ssid {nullptr}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1a29c8958337fe016cfaea779e71405d4e"></a>

### `password`


```cpp
const char* espectre::FrontendWifiStationOptions::password {nullptr}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1a9acbb9d91ae575bb9f865f78ef76d4de"></a>

### `bssid`


```cpp
const char* espectre::FrontendWifiStationOptions::bssid {nullptr}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1a38cbc5d9835a120fb95893d0f43e2448"></a>

### `configured_channel`


```cpp
int espectre::FrontendWifiStationOptions::configured_channel {0}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1aaea0f7e7c6dd4003c799294123f45692"></a>

### `max_retry`


```cpp
int espectre::FrontendWifiStationOptions::max_retry {8}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1acfef20b31152a3bd68da54724e0961c4"></a>

### `manage_csi_lifecycle`


```cpp
bool espectre::FrontendWifiStationOptions::manage_csi_lifecycle {false}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1ab768ec3b3ae37afbb890422e627e9e5d"></a>

### `start_manager`


```cpp
bool espectre::FrontendWifiStationOptions::start_manager {false}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1adc1b615bee32f339ac74c65f6db27683"></a>

### `change_callback`


```cpp
WifiProvisioningService::ChangeCallback espectre::FrontendWifiStationOptions::change_callback {}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1a84d42e71c8939635ed67ff8426c26ef6"></a>

### `connected_callback`


```cpp
standalone_wifi_callback_t espectre::FrontendWifiStationOptions::connected_callback {}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1aeae790292be454b20bf674bdd829592c"></a>

### `disconnected_callback`


```cpp
standalone_wifi_callback_t espectre::FrontendWifiStationOptions::disconnected_callback {}
```

   

<a id="structespectre_1_1_frontend_wifi_station_options_1aaa6cfc09dd4e9d59b5c52de40f8332f6"></a>

### `band_policy`


```cpp
WifiBandPolicy espectre::FrontendWifiStationOptions::band_policy {WifiBandPolicy::BAND_2G}
```

   


<a id="classespectre_1_1_high_accuracy_detector"></a>

## espectre::HighAccuracyDetector



```cpp
#include <core/high_accuracy_detector.h>
```



```cpp
class espectre::HighAccuracyDetector : public espectre::BaseDetector
```

 

Neural motion detector, using the MLP weights exported by training.

  

Unlike [`LightweightDetector`](#classespectre_1_1_lightweight_detector) it does not calibrate to the room: it ships a fixed threshold learned at training time, so it performs best in environments the training corpus represents. Check the per-chip figures in `docs/performance/README.md` before choosing it over Lightweight.

 

Same usage as [`LightweightDetector`](#classespectre_1_1_lightweight_detector) on the core-only path, and the same threading rules. `core/ml_weights.h` is generated by the training script and must not be edited by hand; retraining is documented in `docs/ML_TRAINING.md`.

 [`espectre::BaseDetector`](#classespectre_1_1_base_detector)



<a id="classespectre_1_1_high_accuracy_detector_1a8abe924f8cfc5b950f03a81819660d50"></a>

### `HighAccuracyDetector`


```cpp
espectre::HighAccuracyDetector::HighAccuracyDetector(uint16_t window_size=DETECTOR_DEFAULT_WINDOW_SIZE, float threshold=HIGH_ACCURACY_DEFAULT_THRESHOLD, uint16_t lag=L1_DELTA_LAG)
```

 

Constructor.

  

**Parameters**

- `window_size`: Feature extraction window size in the inclusive range defined by DETECTOR\_MIN\_WINDOW\_SIZE and DETECTOR\_MAX\_WINDOW\_SIZE
- `threshold`: Motion detection threshold (0.0-1.0 on the ML probability scale)
- `lag`: Profile-displacement distance in packets. Production uses the nominal-rate default. Alternate values are for replay experiments and require retraining before deployment.

  

<a id="classespectre_1_1_high_accuracy_detector_1a419cca780bf04a8b49156eab81aba632"></a>

### `~HighAccuracyDetector`


```cpp
espectre::HighAccuracyDetector::~HighAccuracyDetector() override
```

   

<a id="classespectre_1_1_high_accuracy_detector_1aaa26e576e969f50a416ea9fa9be1f534"></a>

### `HighAccuracyDetector`


```cpp
espectre::HighAccuracyDetector::HighAccuracyDetector(HighAccuracyDetector &&other) noexcept
```

   

<a id="classespectre_1_1_high_accuracy_detector_1a753a343d584ca462f941244fa86704c5"></a>

### `operator=`


```cpp
HighAccuracyDetector & espectre::HighAccuracyDetector::operator=(HighAccuracyDetector &&other) noexcept
```

   

<a id="classespectre_1_1_high_accuracy_detector_1ad03f02184534d8d78022c4ef39bfe064"></a>

### `HighAccuracyDetector`


```cpp
espectre::HighAccuracyDetector::HighAccuracyDetector(const HighAccuracyDetector &)=delete
```

   

<a id="classespectre_1_1_high_accuracy_detector_1a88124904a2c79a845223d052c356d3f1"></a>

### `operator=`


```cpp
HighAccuracyDetector & espectre::HighAccuracyDetector::operator=(const HighAccuracyDetector &)=delete
```

   

<a id="classespectre_1_1_high_accuracy_detector_1a6b757cf36e76d564867142fbb7eed886"></a>

### `process_packet`


```cpp
void espectre::HighAccuracyDetector::process_packet(const int8_t *csi_data, size_t csi_len, const uint8_t *selected_subcarriers=nullptr, uint8_t num_subcarriers=0, int8_t rssi_dbm=INT8_MIN) override
```

 

Process one normalized, temporally admitted CSI packet.

  

Calculates spatial turbulence from CSI data, applies filtering, and stores in circular buffer.

 

**Parameters**

- `csi_data`: Normalized CSI data (I/Q interleaved)
- `csi_len`: Length of CSI data
- `selected_subcarriers`: Array of subcarrier indices
- `num_subcarriers`: Number of selected subcarriers
- `rssi_dbm`: Link RSSI for this packet, or INT8\_MIN when unknown

  

<a id="classespectre_1_1_high_accuracy_detector_1a346ad05afbe1ef410c4d66fb93b1ed82"></a>

### `advance_missing_slots`


```cpp
void espectre::HighAccuracyDetector::advance_missing_slots(uint32_t count) override
```

 

Advance packet-indexed feature rings for absent temporal slots.

   

<a id="classespectre_1_1_high_accuracy_detector_1ad2dc97f2244b7480e876aa2ec5434b09"></a>

### `update_state`


```cpp
void espectre::HighAccuracyDetector::update_state() override
```

 

Update state machine (call at the detector evaluation interval).

  

Subclasses implement their detection algorithm here.

  

<a id="classespectre_1_1_high_accuracy_detector_1ad74ad007107531f8d6256382723fdeea"></a>

### `clear_buffer`


```cpp
void espectre::HighAccuracyDetector::clear_buffer() override
```

 

Clear turbulence buffer (cold restart).

  

Virtual so detectors with additional state (e.g. L1-Delta profile rings) can extend the cold clear.

  

<a id="classespectre_1_1_high_accuracy_detector_1a2b06b097b5297dd0657135c35ed495ed"></a>

### `is_ready`


```cpp
bool espectre::HighAccuracyDetector::is_ready() const override
```

 

Check if detector is ready (buffer filled).

   

<a id="classespectre_1_1_high_accuracy_detector_1a5714b924b98643cec4011d1615aa9a42"></a>

### `is_valid`


```cpp
bool espectre::HighAccuracyDetector::is_valid() const override
```

 

Return whether all base detector working storage was allocated.

   

<a id="classespectre_1_1_high_accuracy_detector_1a05da3de784780af05d10273efdc079af"></a>

### `set_threshold`


```cpp
bool espectre::HighAccuracyDetector::set_threshold(float threshold) override
```

 

Set detection threshold.

  

**Parameters**

- `threshold`: New threshold value

 

**Returns:** true if value was accepted

  

<a id="classespectre_1_1_high_accuracy_detector_1aafe80e8f8559c570554a3d2712e68eca"></a>

### `get_threshold`


```cpp
float espectre::HighAccuracyDetector::get_threshold() const override
```

 

Get current threshold.

   

<a id="classespectre_1_1_high_accuracy_detector_1a6695e4d3a97f8387bda3f8ff6a227e81"></a>

### `get_name`


```cpp
const char * espectre::HighAccuracyDetector::get_name() const override
```

 

Get detector name for logging.

   

<a id="classespectre_1_1_high_accuracy_detector_1a1e1e180fb3242297ceb69bb55ad50a51"></a>

### `configure_hampel`


```cpp
void espectre::HighAccuracyDetector::configure_hampel(bool enabled, uint8_t window_size=HAMPEL_TURBULENCE_WINDOW_DEFAULT, float threshold=HAMPEL_TURBULENCE_THRESHOLD_DEFAULT) override
```

 

Configure Hampel filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `window_size`: Window size (3-11)
- `threshold`: MAD multiplier threshold

  

<a id="classespectre_1_1_high_accuracy_detector_1a1924bfdb1e6ae3c85172b3189551f2fe"></a>

### `configure_lowpass`


```cpp
void espectre::HighAccuracyDetector::configure_lowpass(bool enabled, float cutoff_hz=LOWPASS_CUTOFF_DEFAULT) override
```

 

Configure low-pass filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `cutoff_hz`: Cutoff frequency (5.0-20.0 Hz)

  


<a id="classespectre_1_1_i_csi_traffic_generator"></a>

## espectre::ICsiTrafficGenerator



```cpp
#include <runtime/csi_traffic_service.h>
```



```cpp
class espectre::ICsiTrafficGenerator
```

  

<a id="classespectre_1_1_i_csi_traffic_generator_1aa56d7c32d024963291509b76cd11da40"></a>

### `~ICsiTrafficGenerator`


```cpp
virtual espectre::ICsiTrafficGenerator::~ICsiTrafficGenerator()=default
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1a2d51e922c7ab8b9de82c77afc318fd81"></a>

### `init`


```cpp
virtual void espectre::ICsiTrafficGenerator::init(uint32_t target_pps, RuntimeTrafficMode mode)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1aa91ad08e345f9f48335438c89990be27"></a>

### `start`


```cpp
virtual bool espectre::ICsiTrafficGenerator::start(uint32_t target_addr)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1ae941653f3ec776a7b891486682ea053f"></a>

### `stop`


```cpp
virtual void espectre::ICsiTrafficGenerator::stop()=0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1a7e069a25ab8bf08f7fcd07e4855e86e2"></a>

### `loop`


```cpp
virtual void espectre::ICsiTrafficGenerator::loop()=0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1a199e6364991477c334ace5721c3b4b62"></a>

### `is_running`


```cpp
virtual bool espectre::ICsiTrafficGenerator::is_running() const =0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1ae561e9b7aebda5148c1c62b97f9777d2"></a>

### `send_success_count`


```cpp
virtual uint32_t espectre::ICsiTrafficGenerator::send_success_count() const =0
```

   

<a id="classespectre_1_1_i_csi_traffic_generator_1a92124965479b44d35b88a16a26d78775"></a>

### `icmp_identifier`


```cpp
virtual uint16_t espectre::ICsiTrafficGenerator::icmp_identifier() const =0
```

   


<a id="classespectre_1_1_i_csi_traffic_ingress"></a>

## espectre::ICsiTrafficIngress



```cpp
#include <runtime/csi_traffic_service.h>
```



```cpp
class espectre::ICsiTrafficIngress
```

  

<a id="classespectre_1_1_i_csi_traffic_ingress_1a52abe6c059a0e7027b70c98f0f1d1ef5"></a>

### `~ICsiTrafficIngress`


```cpp
virtual espectre::ICsiTrafficIngress::~ICsiTrafficIngress()=default
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1a032e74b603c7c77e9a0c089d37c92784"></a>

### `init`


```cpp
virtual void espectre::ICsiTrafficIngress::init(uint16_t port)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1a4b1a7eafb45b592386a66fbeffcc5bc1"></a>

### `set_multicast_group`


```cpp
virtual void espectre::ICsiTrafficIngress::set_multicast_group(const char *group)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1a3d174084ec84ea73db71c60bee8b8f34"></a>

### `set_expected_payload`


```cpp
virtual void espectre::ICsiTrafficIngress::set_expected_payload(const uint8_t *payload, size_t len)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1aa816a8caaec1016c7998756fd3031d45"></a>

### `set_packet_callback`


```cpp
virtual void espectre::ICsiTrafficIngress::set_packet_callback(csi_traffic_packet_callback_t callback, void *context=nullptr)=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1af32d5cf7242053f8a1998dec716362fd"></a>

### `start`


```cpp
virtual bool espectre::ICsiTrafficIngress::start()=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1af215abbbf80c1431220c5ab000fea810"></a>

### `stop`


```cpp
virtual void espectre::ICsiTrafficIngress::stop()=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1a5a6cc7046c6e4989caf2fa5ee3ac7c51"></a>

### `loop`


```cpp
virtual void espectre::ICsiTrafficIngress::loop()=0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1aa443f08dd27cedcc84d2c732e3d860f5"></a>

### `is_running`


```cpp
virtual bool espectre::ICsiTrafficIngress::is_running() const =0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1ac4cd5819ebc2847255bdfa5d9ecea39c"></a>

### `get_packets_received`


```cpp
virtual uint64_t espectre::ICsiTrafficIngress::get_packets_received() const =0
```

   

<a id="classespectre_1_1_i_csi_traffic_ingress_1aabedf208bf9ee9cd67baa5f03f4cc159"></a>

### `get_last_sender`


```cpp
virtual bool espectre::ICsiTrafficIngress::get_last_sender(UdpDatagramPeer *out_peer) const =0
```

   


<a id="classespectre_1_1_i_direct_http_service"></a>

## espectre::IDirectHttpService



```cpp
#include <runtime/direct_http_service.h>
```



```cpp
class espectre::IDirectHttpService
```

 

Local HTTP endpoints shared by ESPectre firmware frontends.

  [`espectre::IDirectHttpService::DeferredRequestResult`](#structespectre_1_1_i_direct_http_service_1_1_deferred_request_result)



<a id="classespectre_1_1_i_direct_http_service_1a7d0434dbd3a5c12dffb28c2daffe5ec0"></a>

### `RequestHandler`


```cpp
using espectre::IDirectHttpService::RequestHandler = std::function<std::string(const DirectRequest &request)>
```

   

<a id="classespectre_1_1_i_direct_http_service_1a40bce5f4a53bdd8391e97b2cb7bbdb29"></a>

### `ResponseSentCallback`


```cpp
using espectre::IDirectHttpService::ResponseSentCallback = std::function<void(bool sent)>
```

   

<a id="classespectre_1_1_i_direct_http_service_1a01888012eaed141bfcf8cde8b25b36bf"></a>

### `DeferredRequestHandler`


```cpp
using espectre::IDirectHttpService::DeferredRequestHandler = 
std::function<DeferredRequestResult(uint64_t request_token, const DirectRequest &request)>
```

   

<a id="classespectre_1_1_i_direct_http_service_1a79e0cf4b601a74148e34ac9269b2d301"></a>

### `ClientCountCallback`


```cpp
using espectre::IDirectHttpService::ClientCountCallback = std::function<void(size_t event_client_count)>
```

   

<a id="classespectre_1_1_i_direct_http_service_1a586a3df77e489ea451bb53c0825736e2"></a>

### `RawSessionRequestedCallback`


```cpp
using espectre::IDirectHttpService::RawSessionRequestedCallback = std::function<bool(std::string *message)>
```

   

<a id="classespectre_1_1_i_direct_http_service_1af90d02bc26cb3c26b74f47858bfc898c"></a>

### `RawSessionStoppedCallback`


```cpp
using espectre::IDirectHttpService::RawSessionStoppedCallback = std::function<void(RawCsiStopReason reason)>
```

   


<a id="classespectre_1_1_i_direct_http_service_1a6942f8c8d9baa843bb95885b2d02e90f"></a>

### `~IDirectHttpService`


```cpp
virtual espectre::IDirectHttpService::~IDirectHttpService()=default
```

   

<a id="classespectre_1_1_i_direct_http_service_1a21bdc56c51f29cbfdec8545c8e52f705"></a>

### `setup`


```cpp
virtual bool espectre::IDirectHttpService::setup(const DirectHttpServiceConfig &config, RequestHandler request_handler, ClientCountCallback client_count_callback)=0
```

 

Configure and start the endpoint.

  

Safe to call again after shutdown.

  

<a id="classespectre_1_1_i_direct_http_service_1adb3a8a7bf1e9f08ce987142a1e7f9fce"></a>

### `setup_deferred`


```cpp
virtual bool espectre::IDirectHttpService::setup_deferred(const DirectHttpServiceConfig &config, DeferredRequestHandler request_handler, ClientCountCallback client_count_callback)
```

 

Configure a handler that may complete a request later.

  

The default preserves source compatibility for external transports that implement only synchronous Direct requests. A successful deferred handler must eventually call [complete\_deferred\_response()](#classespectre_1_1_i_direct_http_service_1a06fba7cb689b91f7be819faa83959575) with the opaque token.

  

<a id="classespectre_1_1_i_direct_http_service_1a06fba7cb689b91f7be819faa83959575"></a>

### `complete_deferred_response`


```cpp
virtual bool espectre::IDirectHttpService::complete_deferred_response(uint64_t request_token, std::string response)
```

 

Queue a deferred response only if the originating connection is live.

   

<a id="classespectre_1_1_i_direct_http_service_1a6f835ce9e9f17bd58c87b9b295f5a2c0"></a>

### `loop`


```cpp
virtual void espectre::IDirectHttpService::loop()=0
```

 

Pump deferred receive, dispatch, send work, and application callbacks from the frontend task.

  

Request, client-count, and raw-stop callbacks are never delivered from HTTP server or streaming worker tasks.

  

<a id="classespectre_1_1_i_direct_http_service_1ad8f2cf4aa8528504cfadfe34281e6e47"></a>

### `shutdown`


```cpp
virtual void espectre::IDirectHttpService::shutdown()=0
```

 

Stop accepting clients, close sockets, and release queued messages.

   

<a id="classespectre_1_1_i_direct_http_service_1af8e97ce6405baf11e9938a4040954ccd"></a>

### `running`


```cpp
virtual bool espectre::IDirectHttpService::running() const =0
```

   

<a id="classespectre_1_1_i_direct_http_service_1aae1a9b281bfcbbccf9d66df82eb02e0f"></a>

### `event_client_count`


```cpp
virtual size_t espectre::IDirectHttpService::event_client_count() const =0
```

   

<a id="classespectre_1_1_i_direct_http_service_1aebcaa2d23b59c0ab5b59b19ad6ff8b80"></a>

### `publish_event`


```cpp
virtual bool espectre::IDirectHttpService::publish_event(const std::string &event_name, const std::string &data_json, bool replaceable_telemetry)=0
```

 

Queue a normalized event for every connected client.

  

Telemetry events may replace an older queued event with the same name. State transitions and command responses must never be replaced by telemetry. Returns false when no client can accept the event.

  

<a id="classespectre_1_1_i_direct_http_service_1ad9436229255cef3652b5ad01e50776ff"></a>

### `diagnostics`


```cpp
virtual DirectHttpServiceDiagnostics espectre::IDirectHttpService::diagnostics() const =0
```

   

<a id="classespectre_1_1_i_direct_http_service_1a16aa9eb2c01a18b2b866cf6fc00cd29b"></a>

### `set_raw_session_requested_callback`


```cpp
virtual void espectre::IDirectHttpService::set_raw_session_requested_callback(RawSessionRequestedCallback callback)
```

 

Register the frontend-task callback that opens collection for GET /csi.

   

<a id="classespectre_1_1_i_direct_http_service_1a21cb31f0636c6ac84554baa3532c9c5e"></a>

### `start_raw_session`


```cpp
virtual bool espectre::IDirectHttpService::start_raw_session(const RawCsiSessionConfig &config, RawSessionStoppedCallback stopped_callback)
```

 

Begin one owner-bound raw session on the service's binary endpoint.

   

<a id="classespectre_1_1_i_direct_http_service_1ae2917eb53be05f00272a68d65e57b14e"></a>

### `stop_raw_session`


```cpp
virtual bool espectre::IDirectHttpService::stop_raw_session(RawCsiStopReason reason)
```

 

Stop the active raw session and close its binary socket.

  

The stopped callback is delivered by [loop()](#classespectre_1_1_i_direct_http_service_1a6f835ce9e9f17bd58c87b9b295f5a2c0), or synchronously while [shutdown()](#classespectre_1_1_i_direct_http_service_1ad8f2cf4aa8528504cfadfe34281e6e47) completes on the owning frontend task.

  

<a id="classespectre_1_1_i_direct_http_service_1af860d2e8e4bf884954de06e137b4e288"></a>

### `offer_raw_packet`


```cpp
virtual bool espectre::IDirectHttpService::offer_raw_packet(const RawCsiPacketView &packet)
```

 

Copy one callback-scoped sample into the transport's bounded raw slots.

   

<a id="classespectre_1_1_i_direct_http_service_1a78821b4bf5721bea25c4b8d0e8c96a62"></a>

### `raw_diagnostics`


```cpp
virtual RawCsiSessionDiagnostics espectre::IDirectHttpService::raw_diagnostics() const
```

   


<a id="structespectre_1_1_i_direct_http_service_1_1_deferred_request_result"></a>

## espectre::IDirectHttpService::DeferredRequestResult



```cpp
#include <runtime/direct_http_service.h>
```



```cpp
struct espectre::IDirectHttpService::DeferredRequestResult
```

  

<a id="structespectre_1_1_i_direct_http_service_1_1_deferred_request_result_1a15136f0dc1f070fc1d4f92308833610a"></a>

### `deferred`


```cpp
bool espectre::IDirectHttpService::DeferredRequestResult::deferred {false}
```

   

<a id="structespectre_1_1_i_direct_http_service_1_1_deferred_request_result_1a67b7adb4a29195f681c2c036f0b1062b"></a>

### `response`


```cpp
std::string espectre::IDirectHttpService::DeferredRequestResult::response
```

   

<a id="structespectre_1_1_i_direct_http_service_1_1_deferred_request_result_1a86fb9d9ffe614b43ad86ffe37c1b8ea6"></a>

### `response_sent_callback`


```cpp
ResponseSentCallback espectre::IDirectHttpService::DeferredRequestResult::response_sent_callback {}
```

 

Runs on the frontend task after the response send attempt completes.

   


<a id="classespectre_1_1_i_espectre_runtime"></a>

## espectre::IEspectreRuntime



```cpp
#include <runtime/runtime_interface.h>
```



```cpp
class espectre::IEspectreRuntime
```

 

The sensing backend behind [`RuntimeFrontendController`](#classespectre_1_1_runtime_frontend_controller).

  

Implement this only to replace the shipped ESP-IDF backend. Integrations consume it indirectly: the controller owns the instance, forwards control calls, and gates them on [`get_capabilities()`](#classespectre_1_1_i_espectre_runtime_1a4695e857e1394c5f4ddcd82744f0e94d).

 

**Par:** Threading

Implementations are not required to be thread-safe and the shipped one is not. Run [`setup()`](#classespectre_1_1_i_espectre_runtime_1a8e9e61a99b770fae5c1aa81a346d5445), [`loop()`](#classespectre_1_1_i_espectre_runtime_1a150161695d0cfe824e40a3e2bbef1fa2), and [`shutdown()`](#classespectre_1_1_i_espectre_runtime_1a721dcb2f9de7b654c37dd20a1073c990) on the task that owns the runtime, and deliver listener callbacks on the caller's task rather than from an interrupt or a driver callback. See [`espectre_sdk.h`](#espectre__sdk_8h) for the complete contract, including the control-call caveat.

 

<a id="classespectre_1_1_i_espectre_runtime_1a7e7d2c5a30dcd1cf19bf4e6767321708"></a>

### `~IEspectreRuntime`


```cpp
virtual espectre::IEspectreRuntime::~IEspectreRuntime()=default
```

   

<a id="classespectre_1_1_i_espectre_runtime_1a8e9e61a99b770fae5c1aa81a346d5445"></a>

### `setup`


```cpp
virtual bool espectre::IEspectreRuntime::setup()=0
```

 

Bring the runtime up: radio hooks, CSI capture, detector, traffic.

  

**Returns:** false if the runtime cannot sense. The caller must not call [`loop()`](#classespectre_1_1_i_espectre_runtime_1a150161695d0cfe824e40a3e2bbef1fa2) afterwards; the controller drops the instance instead.

  

<a id="classespectre_1_1_i_espectre_runtime_1a721dcb2f9de7b654c37dd20a1073c990"></a>

### `shutdown`


```cpp
virtual void espectre::IEspectreRuntime::shutdown()=0
```

 

Stop sensing and release everything [`setup()`](#classespectre_1_1_i_espectre_runtime_1a8e9e61a99b770fae5c1aa81a346d5445) acquired.

  

Safe to repeat.

  

<a id="classespectre_1_1_i_espectre_runtime_1a150161695d0cfe824e40a3e2bbef1fa2"></a>

### `loop`


```cpp
virtual void espectre::IEspectreRuntime::loop()=0
```

 

Advance runtime work and drain deferred events.

  

Call it continuously from your loop task. This is where listener callbacks are delivered, so a slow callback delays the next iteration.

  

<a id="classespectre_1_1_i_espectre_runtime_1a2d1152954950d468b8f52d04cc501f23"></a>

### `set_services_armed`


```cpp
virtual void espectre::IEspectreRuntime::set_services_armed(bool armed)=0
```

 

Gate the runtime-owned services without tearing the runtime down.

  

Disarmed, the runtime stays configured but starts no CSI capture or traffic. The current Wi-Fi association is preserved so arming again can restart capture without waiting for another IP event. Matter uses this to stay quiet until commissioning completes; Native uses it to pause sensing while a frontend intentionally suspends sensing. During raw collection, the requested state is staged without interrupting the capture callback and takes effect when collection stops.

  

<a id="classespectre_1_1_i_espectre_runtime_1ac60169e2b0da6089a3f27ea0fed24a86"></a>

### `set_live_telemetry_enabled`


```cpp
virtual void espectre::IEspectreRuntime::set_live_telemetry_enabled(bool enabled)=0
```

 

Enable or suppress the high-rate `on_live_telemetry()` stream.

   

<a id="classespectre_1_1_i_espectre_runtime_1ad61f32eff0595b8fff24c43f3efa62ef"></a>

### `set_threshold_runtime`


```cpp
virtual bool espectre::IEspectreRuntime::set_threshold_runtime(float threshold)=0
```

 

Retune the motion threshold while running.

  

**Returns:** false when the value is out of range for the active detector, or when the runtime cannot apply it.

  

<a id="classespectre_1_1_i_espectre_runtime_1aa451516d0d79d5cc6b9148a3e92e78cd"></a>

### `set_motion_hits_runtime`


```cpp
virtual bool espectre::IEspectreRuntime::set_motion_hits_runtime(uint8_t motion_on_hits, uint8_t motion_off_hits)=0
```

 

Retune the hit filter while running.

  

**Returns:** false when either count is outside 1..20, or when the runtime cannot apply the change.

  

<a id="classespectre_1_1_i_espectre_runtime_1ac195f9d4c3c147ed6bc287dc1e4c4576"></a>

### `set_csi_traffic_mode_runtime`


```cpp
virtual bool espectre::IEspectreRuntime::set_csi_traffic_mode_runtime(CsiTrafficMode mode)
```

 

Switch who owns the CSI-bearing traffic while running.

  

Defaulted rather than pure so existing out-of-tree backends keep compiling. A backend that does not implement live traffic retuning should return false and let the frontend reject the command.

  

<a id="classespectre_1_1_i_espectre_runtime_1a12f04b209618a975ae94526abf72d574"></a>

### `set_traffic_generator_mode_runtime`


```cpp
virtual bool espectre::IEspectreRuntime::set_traffic_generator_mode_runtime(RuntimeTrafficMode mode)
```

 

Change the internal traffic generator packet type while running.

  

Backends that do not own traffic retuning keep the default false.

  

<a id="classespectre_1_1_i_espectre_runtime_1a959ecc550006304f3ab0a1542be67305"></a>

### `set_detection_algorithm_runtime`


```cpp
virtual bool espectre::IEspectreRuntime::set_detection_algorithm_runtime(DetectionAlgorithm algorithm)=0
```

 

Switch detector while running, rebuilding detector state.

  

**Returns:** false when the algorithm is unknown or the switch fails.

  

<a id="classespectre_1_1_i_espectre_runtime_1abc0de2a86fe05f9589b9620ae5fff41c"></a>

### `trigger_recalibration`


```cpp
virtual bool espectre::IEspectreRuntime::trigger_recalibration()=0
```

 

Restart startup calibration against the current ambient channel.

  

**Returns:** false when calibration cannot start, for example with no Wi-Fi link yet. Progress arrives through the calibration callbacks.

  

<a id="classespectre_1_1_i_espectre_runtime_1a6fb0c564723fe1b4b3cad024428ecf69"></a>

### `is_calibrating`


```cpp
virtual bool espectre::IEspectreRuntime::is_calibrating() const =0
```

 

True while startup calibration is running and detection is not yet valid.

   

<a id="classespectre_1_1_i_espectre_runtime_1aa2f8a401d41ad7a0370b47433d574538"></a>

### `start_raw_collection`


```cpp
virtual bool espectre::IEspectreRuntime::start_raw_collection(raw_csi_packet_callback_t callback, void *context)
```

 

Enter transient raw collection while preserving persisted sensing config.

  

Defaulted so existing external runtime implementations remain source compatible. The callback runs in the CSI capture context and must remain bounded and allocation-free.

  

<a id="classespectre_1_1_i_espectre_runtime_1a6bcf5611f26eb662e0f93f076ac065f2"></a>

### `stop_raw_collection`


```cpp
virtual bool espectre::IEspectreRuntime::stop_raw_collection(RawCsiStopReason reason)
```

 

Leave raw collection and restore the previous sensing lifecycle.

   

<a id="classespectre_1_1_i_espectre_runtime_1a3756e7bbbdae58c8f0558f8b32b36dda"></a>

### `operation_state`


```cpp
virtual RuntimeOperationState espectre::IEspectreRuntime::operation_state() const
```

 

Current transient operation state.

   

<a id="classespectre_1_1_i_espectre_runtime_1af0cbce64d45cf910475f8438ff788c18"></a>

### `get_snapshot`


```cpp
virtual RuntimeSnapshot espectre::IEspectreRuntime::get_snapshot() const =0
```

 

Current sensing state.

  

Cheap enough to poll from your loop.

  

<a id="classespectre_1_1_i_espectre_runtime_1abbc33eeeb41b139d85e9c0f82fb9f476"></a>

### `get_diagnostics`


```cpp
virtual RuntimeDiagnosticsSnapshot espectre::IEspectreRuntime::get_diagnostics() const
```

 

Capture, traffic, and link counters for diagnostic frontends.

  

The counters are cumulative and monotonic within a session. Feed them to [`RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler) from an existing periodic sensing callback to get rates without adding a diagnostic timer.

 

Defaulted rather than pure so that adding it does not break out-of-tree backends. A runtime that collects nothing keeps the zeroed snapshot, which is what a frontend reads as "no counters from this backend".

  

<a id="classespectre_1_1_i_espectre_runtime_1aa7a2f72d263dace767b4512a87ad4198"></a>

### `get_diagnostics_sample`


```cpp
virtual const RuntimeDiagnosticsSample * espectre::IEspectreRuntime::get_diagnostics_sample() const
```

 

Latest rate sample derived by the runtime on its sensing heartbeat.

  

The pointed-to sample remains owned by the runtime. Backends that do not provide periodic diagnostics may return `nullptr`.

  

<a id="classespectre_1_1_i_espectre_runtime_1a4695e857e1394c5f4ddcd82744f0e94d"></a>

### `get_capabilities`


```cpp
virtual RuntimeCapabilities espectre::IEspectreRuntime::get_capabilities() const =0
```

 

What this backend actually supports.

  

Stable after [`setup()`](#classespectre_1_1_i_espectre_runtime_1a8e9e61a99b770fae5c1aa81a346d5445).

  

<a id="classespectre_1_1_i_espectre_runtime_1a0f47a7c1005e8cee60b73fb6fdf89fe9"></a>

### `set_listener`


```cpp
virtual void espectre::IEspectreRuntime::set_listener(IRuntimeListener *listener)=0
```

 

Install the event sink, or `nullptr` to detach.

  

Set it before [`setup()`](#classespectre_1_1_i_espectre_runtime_1a8e9e61a99b770fae5c1aa81a346d5445) so calibration events are not missed. The runtime does not take ownership; the listener must outlive the runtime.

  


<a id="classespectre_1_1_i_mqtt_transport"></a>

## espectre::IMqttTransport



```cpp
#include <runtime/mqtt_transport.h>
```



```cpp
class espectre::IMqttTransport
```

 

The MQTT client seam.

  

Implement it to carry ESPectre Protocol messages over an MQTT stack you already own, then hand the instance to a frontend. [`EspIdfMqttTransport`](#classespectre_1_1_esp_idf_mqtt_transport) ([`mqtt_transport_esp_idf.h`](#mqtt__transport__esp__idf_8h)) is the shipped implementation over `esp-mqtt`, and `test/cpp/support/mqtt_transport_mock.h` is the host double.

 

Topic layout and payload schemas live in `docs/API.md`, and [`espectre_protocol.h`](#espectre__protocol_8h) builds the payloads, so an implementation only has to move bytes.

 

**Par:** Contract for implementers

- The transport is driven from the frontend's task: [`loop()`](#classespectre_1_1_i_mqtt_transport_1a002372527235e03bac5686a7ef9be0ab) is where you pump your client and deliver queued callbacks.

- Publishing while disconnected must fail cleanly rather than block.

- Registered subscriptions must survive a reconnect. Callers subscribe once and expect the broker subscription to be reissued on the next connect.

 

<a id="classespectre_1_1_i_mqtt_transport_1acc0dc393b8a4f5c5224c1ca0d05f1ac5"></a>

### `CommandCallback`


```cpp
using espectre::IMqttTransport::CommandCallback = std::function<void(const std::string &)>
```

 

Payload of a message on the device command topic.

   

<a id="classespectre_1_1_i_mqtt_transport_1abf12230069adc2e4a4133c576b1b8266"></a>

### `ConnectionCallback`


```cpp
using espectre::IMqttTransport::ConnectionCallback = std::function<void(bool connected)>
```

 

Broker connection state changed; the argument is the new state.

   

<a id="classespectre_1_1_i_mqtt_transport_1af45c762723f4ec009cafb30d82b89952"></a>

### `MessageCallback`


```cpp
using espectre::IMqttTransport::MessageCallback = std::function<void(const std::string &, const std::string &)>
```

 

Message on a topic registered through [`subscribe()`](#classespectre_1_1_i_mqtt_transport_1a114eb79f1af4599ae9648eb87ae89797): `(topic, payload)`.

   


<a id="classespectre_1_1_i_mqtt_transport_1ad0c7866dc6c5ba5cf0d358b66df50349"></a>

### `~IMqttTransport`


```cpp
virtual espectre::IMqttTransport::~IMqttTransport()=default
```

   

<a id="classespectre_1_1_i_mqtt_transport_1ac7f78bbd532a797bf6b53e26d005269c"></a>

### `setup`


```cpp
virtual bool espectre::IMqttTransport::setup(const EspectreDeviceConfig &config)=0
```

 

Configure and start connecting.

  

Asynchronous: true means the client started, not that it reached the broker. Wait for the connection callback before expecting publishes to land. Calling it again reconfigures and tears down the previous client.

 

**Returns:** false when the configuration cannot produce a client, such as an empty [`EspectreDeviceConfig::mqtt_host`](#structespectre_1_1_espectre_device_config_1a6bc7843ffc079108684b040e77b59c89).

  

<a id="classespectre_1_1_i_mqtt_transport_1a002372527235e03bac5686a7ef9be0ab"></a>

### `loop`


```cpp
virtual void espectre::IMqttTransport::loop()=0
```

 

Pump the client and dispatch callbacks.

  

Called from the frontend loop.

  

<a id="classespectre_1_1_i_mqtt_transport_1a367dda8b9a7cc32831c3fec442cd21bc"></a>

### `shutdown`


```cpp
virtual void espectre::IMqttTransport::shutdown()=0
```

 

Disconnect and release resources.

  

Safe to repeat.

  

<a id="classespectre_1_1_i_mqtt_transport_1aef7b264520bd820dd1475efbce2de5df"></a>

### `connected`


```cpp
virtual bool espectre::IMqttTransport::connected() const =0
```

 

True while the broker connection is established.

   

<a id="classespectre_1_1_i_mqtt_transport_1a9a10597cee927b981bd42922ad51cd4e"></a>

### `publish`


```cpp
virtual bool espectre::IMqttTransport::publish(const std::string &topic, const std::string &payload, bool retain)=0
```

 

Publish to an absolute topic.

  

**Parameters**

- `topic`: Full topic name, not a suffix.
- `payload`: Message body, copied before returning.
- `retain`: Ask the broker to retain the message, for state a late subscriber must still see, such as availability.

 

**Returns:** false when disconnected or the bounded publish queue rejects the message. Published at QoS 0, so true means queued locally, not delivered to the broker.

  

<a id="classespectre_1_1_i_mqtt_transport_1adfa1ecc1df9c7fc39fb07181193b6844"></a>

### `publish_suffix`


```cpp
virtual bool espectre::IMqttTransport::publish_suffix(const char *suffix, const std::string &payload, bool retain)=0
```

 

Publish under this device's protocol topic prefix.

  

The prefix comes from the [`EspectreDeviceConfig`](#structespectre_1_1_espectre_device_config) passed to [`setup()`](#classespectre_1_1_i_mqtt_transport_1ac7f78bbd532a797bf6b53e26d005269c), so callers pass only the trailing segment, for example `"motion"`.

  

<a id="classespectre_1_1_i_mqtt_transport_1a114eb79f1af4599ae9648eb87ae89797"></a>

### `subscribe`


```cpp
virtual bool espectre::IMqttTransport::subscribe(const std::string &topic, MessageCallback callback)=0
```

 

Register a topic and its handler.

  

Idempotent per topic: subscribing again replaces the handler. May be called before the connection is up; the subscription is issued on connect.

 

**Returns:** false for an empty topic or an empty callback.

  

<a id="classespectre_1_1_i_mqtt_transport_1a65414cdc22b80c2da4450e2d06d42868"></a>

### `set_command_callback`


```cpp
virtual void espectre::IMqttTransport::set_command_callback(CommandCallback callback)=0
```

 

Handler for the device command topic, which the transport subscribes itself.

   

<a id="classespectre_1_1_i_mqtt_transport_1a383063c67062b06bd8cf8f3da0a07edb"></a>

### `set_connection_callback`


```cpp
virtual void espectre::IMqttTransport::set_connection_callback(ConnectionCallback callback)=0
```

 

Handler for connection state changes, including reconnects.

   

<a id="classespectre_1_1_i_mqtt_transport_1ab54187eeae50e6ded380bb419d005a46"></a>

### `diagnostics`


```cpp
virtual MqttTransportDiagnostics espectre::IMqttTransport::diagnostics() const
```

 

Bounded outbound queue, drop, failure, and reconnect counters.

   


<a id="classespectre_1_1_i_peer_discovery_service"></a>

## espectre::IPeerDiscoveryService



```cpp
#include <runtime/peer_discovery.h>
```



```cpp
class espectre::IPeerDiscoveryService
```

  

<a id="classespectre_1_1_i_peer_discovery_service_1a1cf223ccf5d6d21bf17a9b87ffef8beb"></a>

### `Completion`


```cpp
using espectre::IPeerDiscoveryService::Completion = std::function<void(PeerDiscoverySnapshot snapshot)>
```

   


<a id="classespectre_1_1_i_peer_discovery_service_1a47af08903f6fbd96795f32a2da5d2ee1"></a>

### `~IPeerDiscoveryService`


```cpp
virtual espectre::IPeerDiscoveryService::~IPeerDiscoveryService()=default
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1a8cee7d9b07243b4f198b202acf7e966e"></a>

### `set_local_candidate`


```cpp
virtual void espectre::IPeerDiscoveryService::set_local_candidate(PeerDiscoveryCandidate candidate)
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1a9dd1f18dada5bfa92db388cb380c8169"></a>

### `set_wifi_ready`


```cpp
virtual void espectre::IPeerDiscoveryService::set_wifi_ready(bool ready)=0
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1ac0290e5614d7ba46e6747f8f9c8e76fd"></a>

### `ready`


```cpp
virtual bool espectre::IPeerDiscoveryService::ready() const =0
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1a502f09da0fe65dd3b54377c43418b536"></a>

### `active`


```cpp
virtual bool espectre::IPeerDiscoveryService::active() const =0
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1a273a3530945f1215f9a75f18b83a56b7"></a>

### `start`


```cpp
virtual bool espectre::IPeerDiscoveryService::start(Completion completion)=0
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1aa2a2d8fe5b6313de00d94094f618d009"></a>

### `loop`


```cpp
virtual void espectre::IPeerDiscoveryService::loop()=0
```

   

<a id="classespectre_1_1_i_peer_discovery_service_1a5a198f14c09be33a478887cdb09b213c"></a>

### `shutdown`


```cpp
virtual void espectre::IPeerDiscoveryService::shutdown()=0
```

   


<a id="classespectre_1_1_i_runtime_listener"></a>

## espectre::IRuntimeListener



```cpp
#include <runtime/runtime_events.h>
```



```cpp
class espectre::IRuntimeListener
```

 

Everything the runtime tells your firmware.

  

Subclass it, override only what your product reacts to, and install it with `RuntimeFrontendController::setup(listener)`. Every callback has an empty default, so an integration that only cares about motion overrides one method.

 

**Par:** Threading and reentrancy

Callbacks are always delivered on the caller's task, never from an interrupt or the Wi-Fi driver:

- Sensing events (motion, periodic, live telemetry, calibration completion, and detector-driven threshold adaptation) originate in the CSI callback but are deferred through an internal mailbox and dispatched from `loop()`.

- Control-driven events (runtime threshold writes and detector selection) fire inline on whichever task called the corresponding setter. [`on_threshold_changed()`](#classespectre_1_1_i_runtime_listener_1a6c97b8ed80d39f723a1d244b178c93f2) is used for both: a setter, calibration finish, or Lightweight settled-level recovery.

 Keep callbacks bounded and non-blocking. Slow work delays the next `loop()` iteration and can fill the bounded CSI mailbox, causing incoming frames to be dropped. Queue network publication, NVS writes, and other potentially blocking work for another task. Calling back into the controller is allowed, with one exception noted on [`on_runtime_fault()`](#classespectre_1_1_i_runtime_listener_1ae566b842c3e051c1230fe922a834a70f).

 

**Par:** Snapshot lifetime

The `snapshot` reference is only valid for the duration of the call. Copy it if you need it later.

 

**Par:** Readiness

Snapshots are delivered during startup calibration as well. Gate anything user-visible on [`RuntimeSnapshot::ready_to_publish`](#structespectre_1_1_runtime_snapshot_1a3e917a2d24bbe00e55416b9ddf3bffcd) so you do not report motion from an uncalibrated detector.

 

<a id="classespectre_1_1_i_runtime_listener_1a005de2f93b412c0fa098cb89bf150035"></a>

### `~IRuntimeListener`


```cpp
virtual espectre::IRuntimeListener::~IRuntimeListener()=default
```

   

<a id="classespectre_1_1_i_runtime_listener_1ac791b4ec86d1cfcd3cbb3f4a87981d79"></a>

### `on_sensing_readiness_changed`


```cpp
virtual void espectre::IRuntimeListener::on_sensing_readiness_changed(const RuntimeSnapshot &snapshot)
```

 

Public sensing readiness changed, including warm-up and input expiry.

  

[RuntimeFrontendController](#classespectre_1_1_runtime_frontend_controller) emits this from loop(), after caching the current snapshot. Publish the sensing resource on both availability transitions.

 

**Parameters**

- `snapshot`: Current sensing state, including public readiness.

  

<a id="classespectre_1_1_i_runtime_listener_1a3b0fd8a11331f19d48085ccb4e9623d8"></a>

### `on_motion_state_changed`


```cpp
virtual void espectre::IRuntimeListener::on_motion_state_changed(const RuntimeSnapshot &snapshot)
```

 

The debounced motion state changed.

  

Edge-triggered and already filtered by `motion_on_hits` / `motion_off_hits`, so this is the hook for occupancy, relays, and notifications.

 

It also fires with [`MotionState::IDLE`](#namespaceespectre_1a7d37681f3243ed6bdd97aee1ed776857aa5daf7f2ebbba4975d61dab1c40188c7) when the Wi-Fi link drops, and that call carries `ready_to_publish == false`. The shipped frontends gate on that flag and therefore leave their last published value in place across a disconnect; if your product would rather fail open, handle the not-ready edge explicitly instead of returning early.

 

**Parameters**

- `snapshot`: Sensing state at the moment of the change.

  

<a id="classespectre_1_1_i_runtime_listener_1afaa7c160e87ee7ac46c337efef5b7af1"></a>

### `on_periodic_update`


```cpp
virtual void espectre::IRuntimeListener::on_periodic_update(const RuntimeSnapshot &snapshot, uint32_t packets_received)
```

 

Heartbeat, emitted every fixed [`RUNTIME_HEARTBEAT_INTERVAL_MS`](#namespaceespectre_1adac330f75e60dcf8bbc56efa51cac931) milliseconds.

  

Use it for status logging and diagnostics sampling rather than sensing telemetry. Movement and canonical MQTT telemetry follow detector evaluation through [`on_live_telemetry()`](#classespectre_1_1_i_runtime_listener_1a2473b19c1324d186b11ba596000acde9).

 

**Parameters**

- `snapshot`: Current sensing state, including the metric and threshold.
- `packets_received`: CSI packets accepted since the previous heartbeat, which is the honest measure of the achieved capture rate.

  

<a id="classespectre_1_1_i_runtime_listener_1a6c97b8ed80d39f723a1d244b178c93f2"></a>

### `on_threshold_changed`


```cpp
virtual void espectre::IRuntimeListener::on_threshold_changed(const RuntimeSnapshot &snapshot)
```

 

The active threshold changed, from a control call, calibration, or detector-driven adaptation such as Lightweight settled-level recovery.

  

Refresh any threshold you mirror in a UI or a published entity. Live telemetry still carries the per-sample comparison value; this hook is the control-plane notification when that value itself has moved.

  

<a id="classespectre_1_1_i_runtime_listener_1a514dc3bb10087f78c374ba69265b7282"></a>

### `on_detector_changed`


```cpp
virtual void espectre::IRuntimeListener::on_detector_changed(const RuntimeSnapshot &snapshot)
```

 

The active detector changed.

  

Thresholds are per-detector, so [`on_threshold_changed()`](#classespectre_1_1_i_runtime_listener_1a6c97b8ed80d39f723a1d244b178c93f2) follows this one.

  

<a id="classespectre_1_1_i_runtime_listener_1a5d300e4e6a00a72a718f0c25aa181a34"></a>

### `on_calibration_started`


```cpp
virtual void espectre::IRuntimeListener::on_calibration_started(const RuntimeSnapshot &snapshot)
```

 

Startup calibration began; detection results are not valid yet.

  

Lightweight only. ML ships a fixed threshold and completes immediately.

  

<a id="classespectre_1_1_i_runtime_listener_1a27f8430a4a3b5b5dc6323765a2155e74"></a>

### `on_calibration_finished`


```cpp
virtual void espectre::IRuntimeListener::on_calibration_finished(const RuntimeSnapshot &snapshot, bool success)
```

 

Startup calibration finished.

  

The runtime releases completed threshold calibration resources before notifying the listener.

 

**Parameters**

- `snapshot`: Sensing state at completion, carrying the applied threshold.
- `success`: false when calibration was cancelled or could not settle on a threshold. The runtime keeps sensing with the configured value, so treat this as a signal to surface, not a fatal error.

  

<a id="classespectre_1_1_i_runtime_listener_1a2473b19c1324d186b11ba596000acde9"></a>

### `on_live_telemetry`


```cpp
virtual void espectre::IRuntimeListener::on_live_telemetry(float movement, float threshold)
```

 

High-rate movement stream, one call per detector evaluation.

  

Frontends publish canonical telemetry and Movement Score from this hook. Considerably more frequent than [`on_periodic_update()`](#classespectre_1_1_i_runtime_listener_1afaa7c160e87ee7ac46c337efef5b7af1); suppress it with `set_live_telemetry_enabled(false)` when nothing is watching.

 

**Parameters**

- `movement`: Current motion metric.
- `threshold`: Threshold it is compared against, on the same scale.

  

<a id="classespectre_1_1_i_runtime_listener_1ae566b842c3e051c1230fe922a834a70f"></a>

### `on_runtime_fault`


```cpp
virtual void espectre::IRuntimeListener::on_runtime_fault(const char *message)
```

 

A runtime-owned failure your firmware should surface.

  

**Parameters**

- `message`: Human-readable cause, valid only for this call.

 Do not drive the runtime from here beyond `shutdown()`: the fault is reported from inside runtime work, and re-entering control paths from it is not supported.

  


<a id="classespectre_1_1_i_udp_datagram_socket"></a>

## espectre::IUdpDatagramSocket



```cpp
#include <runtime/udp_datagram_socket.h>
```



```cpp
class espectre::IUdpDatagramSocket
```

  

<a id="classespectre_1_1_i_udp_datagram_socket_1aef6091336756e15eaca69b6c8d9c2614"></a>

### `~IUdpDatagramSocket`


```cpp
virtual espectre::IUdpDatagramSocket::~IUdpDatagramSocket()=default
```

   

<a id="classespectre_1_1_i_udp_datagram_socket_1a0902f85514a6eb87058257f6e03664e4"></a>

### `open`


```cpp
virtual bool espectre::IUdpDatagramSocket::open(uint16_t port, const char *multicast_group)=0
```

   

<a id="classespectre_1_1_i_udp_datagram_socket_1a6de650bf037bab96cc3fb3abe4e332d2"></a>

### `close`


```cpp
virtual void espectre::IUdpDatagramSocket::close()=0
```

   

<a id="classespectre_1_1_i_udp_datagram_socket_1afb8cf45cdfbf8d5ef06a9a05474d754f"></a>

### `receive`


```cpp
virtual UdpReceiveResult espectre::IUdpDatagramSocket::receive(uint8_t *buffer, size_t buffer_len, size_t *received_len, UdpDatagramPeer *peer)=0
```

   


<a id="structespectre_1_1_json_object_field"></a>

## espectre::JsonObjectField



```cpp
#include <runtime/protocol_json.h>
```



```cpp
struct espectre::JsonObjectField
```

  

<a id="structespectre_1_1_json_object_field_1a1af29f07260e57a269cd982209e583b0"></a>

### `name`


```cpp
std::string espectre::JsonObjectField::name
```

   

<a id="structespectre_1_1_json_object_field_1a507478e78e0f77113b1672953cd6094d"></a>

### `type`


```cpp
JsonValueType espectre::JsonObjectField::type {JsonValueType::NULL_VALUE}
```

   

<a id="structespectre_1_1_json_object_field_1a5dd50afd8d4656c599e9681d33a469f1"></a>

### `value`


```cpp
std::string espectre::JsonObjectField::value
```

 

Decoded contents for strings, or the exact JSON token for every other type.

   


<a id="classespectre_1_1_lightweight_detector"></a>

## espectre::LightweightDetector



```cpp
#include <core/lightweight_detector.h>
```



```cpp
class espectre::LightweightDetector : public espectre::BaseDetector
```

 

The default detector: self-calibrating, no training data required.

  

Fuses turbulence autocorrelation with robust spread from a five-bin aggregated turbulence stream, and adapts its threshold to the room during startup calibration. After that, a long quiet stretch can still lower the live threshold when the opening was noisier than the rest of the session. The full runtime emits [`IRuntimeListener::on_threshold_changed()`](#classespectre_1_1_i_runtime_listener_1a6c97b8ed80d39f723a1d244b178c93f2) for that drop; a core-only integration must re-read [`get_threshold()`](#classespectre_1_1_lightweight_detector_1a6ec5c610ed3a5f766ba026a86d3f3110) after [`update_state()`](#classespectre_1_1_lightweight_detector_1a2c115275c63b3e4f4032d5218b1743d1). Prefer it unless you have a reason to run [`HighAccuracyDetector`](#classespectre_1_1_high_accuracy_detector).

 

Most integrations never construct one: [`RuntimeConfig::detection_algorithm`](#structespectre_1_1_runtime_config_1a3d14cc007fe6107bd81c6c6da176327a) selects it and the runtime owns the lifecycle. Drive it directly only on the core-only path, where your firmware already captures CSI:

 

```cpp
espectre::LightweightDetector detector;
if (!detector.is_valid()) { return; }
// For each slot retained by your temporal sampler:
detector.advance_missing_slots(missing_slots_before_this_packet);
detector.set_packet_timestamp_us(packet_timestamp_us);
detector.process_packet(csi, csi_len, espectre::DEFAULT_SUBCARRIERS,
                        espectre::HT20_SELECTED_BAND_SIZE, rssi_dbm);
// on your evaluation cadence:
detector.update_state();
if (detector.is_ready() && detector.get_state() == espectre::MotionState::MOTION) { ... }
```

 

[`is_ready()`](#classespectre_1_1_lightweight_detector_1ae7316e1b71611a18a03ad52b18f03ee7) is false until the window fills; results before that are not meaningful. See `runtime/esp_idf/csi_pipeline.cpp` for the reference normalization, cadence, and hit filtering around these calls, and `docs/ALGORITHMS.md` for the algorithm itself.

 

**Par:** Threading

Not thread-safe. [`process_packet()`](#classespectre_1_1_lightweight_detector_1ad98770bd6ca93a90cc4baca9b45b72ce) and [`update_state()`](#classespectre_1_1_lightweight_detector_1a2c115275c63b3e4f4032d5218b1743d1) must not run concurrently.

 [`espectre::BaseDetector`](#classespectre_1_1_base_detector)



<a id="classespectre_1_1_lightweight_detector_1a2827677c475727e751cd53c70f215c46"></a>

### `LightweightDetector`


```cpp
espectre::LightweightDetector::LightweightDetector(uint16_t window_size=DETECTOR_DEFAULT_WINDOW_SIZE, float threshold=LIGHTWEIGHT_DEFAULT_THRESHOLD, uint16_t autocorr_lag=1U)
```

  

**Parameters**

- `window_size`: Detector window in packets
- `threshold`: Motion probability threshold
- `autocorr_lag`: Turbulence autocorrelation distance in packets

 Production uses the nominal-rate default. Alternate lags are exposed for replay experiments only: changing the feature offset requires validating the fitted coefficients before deployment. See detector\_timing.h.

  

<a id="classespectre_1_1_lightweight_detector_1a3a8e768134861844f23a49dd0ad1cc16"></a>

### `~LightweightDetector`


```cpp
espectre::LightweightDetector::~LightweightDetector() override=default
```

   

<a id="classespectre_1_1_lightweight_detector_1a4dee4a11dd008112747999be2537ed5f"></a>

### `LightweightDetector`


```cpp
espectre::LightweightDetector::LightweightDetector(LightweightDetector &&other) noexcept=default
```

   

<a id="classespectre_1_1_lightweight_detector_1ad56def16d1aac6ff2bf2ff937de4c75f"></a>

### `operator=`


```cpp
LightweightDetector & espectre::LightweightDetector::operator=(LightweightDetector &&other) noexcept=default
```

   

<a id="classespectre_1_1_lightweight_detector_1a943f38c526f8402d109d2aa28a41c8f4"></a>

### `LightweightDetector`


```cpp
espectre::LightweightDetector::LightweightDetector(const LightweightDetector &)=delete
```

   

<a id="classespectre_1_1_lightweight_detector_1ade8a697de335b7644e9c9d4d29934526"></a>

### `operator=`


```cpp
LightweightDetector & espectre::LightweightDetector::operator=(const LightweightDetector &)=delete
```

   

<a id="classespectre_1_1_lightweight_detector_1ad98770bd6ca93a90cc4baca9b45b72ce"></a>

### `process_packet`


```cpp
void espectre::LightweightDetector::process_packet(const int8_t *csi_data, size_t csi_len, const uint8_t *selected_subcarriers=nullptr, uint8_t num_subcarriers=0, int8_t rssi_dbm=INT8_MIN) override
```

 

Process one normalized, temporally admitted CSI packet.

  

Calculates spatial turbulence from CSI data, applies filtering, and stores in circular buffer.

 

**Parameters**

- `csi_data`: Normalized CSI data (I/Q interleaved)
- `csi_len`: Length of CSI data
- `selected_subcarriers`: Array of subcarrier indices
- `num_subcarriers`: Number of selected subcarriers
- `rssi_dbm`: Link RSSI for this packet, or INT8\_MIN when unknown

  

<a id="classespectre_1_1_lightweight_detector_1aa93ad761aa4e7111ed6b0e2e30496366"></a>

### `advance_missing_slots`


```cpp
void espectre::LightweightDetector::advance_missing_slots(uint32_t count) override
```

 

Advance packet-indexed feature rings for absent temporal slots.

   

<a id="classespectre_1_1_lightweight_detector_1a2c115275c63b3e4f4032d5218b1743d1"></a>

### `update_state`


```cpp
void espectre::LightweightDetector::update_state() override
```

 

Update state machine (call at the detector evaluation interval).

  

Subclasses implement their detection algorithm here.

  

<a id="classespectre_1_1_lightweight_detector_1aadbd176e74980d13d4560b36d55728d7"></a>

### `reset`


```cpp
void espectre::LightweightDetector::reset() override
```

 

Reset detector state.

  

Resets state machine but preserves buffer ("warm" restart).

  

<a id="classespectre_1_1_lightweight_detector_1ae3c4afa60d1448f142853b296c9c94eb"></a>

### `clear_buffer`


```cpp
void espectre::LightweightDetector::clear_buffer() override
```

 

Clear turbulence buffer (cold restart).

  

Virtual so detectors with additional state (e.g. L1-Delta profile rings) can extend the cold clear.

  

<a id="classespectre_1_1_lightweight_detector_1a593fe23304af8dcedea11856fc1c495b"></a>

### `configure_hampel`


```cpp
void espectre::LightweightDetector::configure_hampel(bool enabled, uint8_t window_size=HAMPEL_TURBULENCE_WINDOW_DEFAULT, float threshold=HAMPEL_TURBULENCE_THRESHOLD_DEFAULT) override
```

 

Configure Hampel filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `window_size`: Window size (3-11)
- `threshold`: MAD multiplier threshold

  

<a id="classespectre_1_1_lightweight_detector_1a49437a685bbd6f18e6439e2d2cd1a650"></a>

### `configure_lowpass`


```cpp
void espectre::LightweightDetector::configure_lowpass(bool enabled, float cutoff_hz=LOWPASS_CUTOFF_DEFAULT) override
```

 

Configure low-pass filter.

  

**Parameters**

- `enabled`: Whether to enable the filter
- `cutoff_hz`: Cutoff frequency (5.0-20.0 Hz)

  

<a id="classespectre_1_1_lightweight_detector_1ae7316e1b71611a18a03ad52b18f03ee7"></a>

### `is_ready`


```cpp
bool espectre::LightweightDetector::is_ready() const override
```

 

Check if detector is ready (buffer filled).

   

<a id="classespectre_1_1_lightweight_detector_1a5313035ca79adb3270764b4f53021cdf"></a>

### `is_valid`


```cpp
bool espectre::LightweightDetector::is_valid() const override
```

 

Return whether all base detector working storage was allocated.

   

<a id="classespectre_1_1_lightweight_detector_1a03a94bf71221845a156b778aba9f2c4a"></a>

### `set_threshold`


```cpp
bool espectre::LightweightDetector::set_threshold(float threshold) override
```

 

Set detection threshold.

  

**Parameters**

- `threshold`: New threshold value

 

**Returns:** true if value was accepted

  

<a id="classespectre_1_1_lightweight_detector_1ab5359cd2f8ac714c018d6f0b11745ca1"></a>

### `set_adaptive_threshold`


```cpp
bool espectre::LightweightDetector::set_adaptive_threshold(float threshold) override
```

 

Apply a detector-specific startup-calibrated threshold.

   

<a id="classespectre_1_1_lightweight_detector_1a6ec5c610ed3a5f766ba026a86d3f3110"></a>

### `get_threshold`


```cpp
float espectre::LightweightDetector::get_threshold() const override
```

 

Get current threshold.

   

<a id="classespectre_1_1_lightweight_detector_1a9a64dac4614bdc6013375f59a15ecfe1"></a>

### `get_name`


```cpp
const char * espectre::LightweightDetector::get_name() const override
```

 

Get detector name for logging.

   

<a id="classespectre_1_1_lightweight_detector_1a7aa058c0d53152d81f5da9d1989fd141"></a>

### `get_startup_threshold_factor`


```cpp
float espectre::LightweightDetector::get_startup_threshold_factor() const override
```

 

Get the detector-specific automatic startup multiplier.

  

threshold = threshold\_metric x factor. Matches the Python runtime's detector STARTUP\_THRESHOLD\_FACTOR convention, where `threshold_metric` comes from the shared startup calibrator.

  

<a id="classespectre_1_1_lightweight_detector_1a16b1483216710ef4779e25f9ab2a5f2c"></a>

### `startup_gate_enabled`


```cpp
bool espectre::LightweightDetector::startup_gate_enabled() const override
```

 

Whether startup calibration uses the consistency gate (threshold.h).

  

Enabled only for detectors with a tight quiet floor (l1\_delta). Matches the Python runtime's detector STARTUP\_GATE convention.

  

<a id="classespectre_1_1_lightweight_detector_1a5c3f2b65e433379face4641fb3398bb0"></a>

### `on_startup_calibration_begin`


```cpp
void espectre::LightweightDetector::on_startup_calibration_begin() override
```

 

Hook called immediately before startup calibration begins.

   

<a id="classespectre_1_1_lightweight_detector_1a3d0cb8a72ad26769ffddacc1db32b8ba"></a>

### `on_startup_calibration_complete`


```cpp
void espectre::LightweightDetector::on_startup_calibration_complete() override
```

 

Hook called when startup calibration completes successfully.

  

Detectors can freeze session-specific state here before the runtime performs its warm clear between calibration and steady-state detection.

  

<a id="classespectre_1_1_lightweight_detector_1a7c69093cdce4f6390740e79d4ec21647"></a>

### `get_turb_autocorr`


```cpp
float espectre::LightweightDetector::get_turb_autocorr() const
```

   

<a id="classespectre_1_1_lightweight_detector_1a79cc507df17c747f3340fdc600cce909"></a>

### `get_turb_iqr_over_mean_aggr`


```cpp
float espectre::LightweightDetector::get_turb_iqr_over_mean_aggr() const
```

   

<a id="classespectre_1_1_lightweight_detector_1a9759c675e359c00c802e049339f5327d"></a>

### `get_logit`


```cpp
float espectre::LightweightDetector::get_logit() const
```

   


<a id="structespectre_1_1_log_sink"></a>

## espectre::LogSink



```cpp
#include <core/espectre_log.h>
```



```cpp
struct espectre::LogSink
```

 

Frontend-owned logging callbacks.

  

ESPectre copies this value when it is registered but does not own [`context`](#structespectre_1_1_log_sink_1a0766bd86173c1c6da6bd67fecdd70e20). The context and callbacks must remain valid until the sink is cleared.

 

<a id="structespectre_1_1_log_sink_1a0766bd86173c1c6da6bd67fecdd70e20"></a>

### `context`


```cpp
void* espectre::LogSink::context {nullptr}
```

   

<a id="structespectre_1_1_log_sink_1a308ac37737bd18dc082d8b9efef056f2"></a>

### `enabled`


```cpp
LogEnabledCallback espectre::LogSink::enabled {nullptr}
```

   

<a id="structespectre_1_1_log_sink_1a27a477296e13456e0557b6b55cf57185"></a>

### `write`


```cpp
LogWriteCallback espectre::LogSink::write {nullptr}
```

   


<a id="classespectre_1_1_mdns_bootstrap_responder"></a>

## espectre::MdnsBootstrapResponder



```cpp
#include <runtime/esp_idf/mdns_bootstrap_responder.h>
```



```cpp
class espectre::MdnsBootstrapResponder
```

  

<a id="classespectre_1_1_mdns_bootstrap_responder_1a2b2f05c55613a24569190cb622829f7c"></a>

### `NONCE_HEX_LENGTH`


```cpp
constexpr size_t espectre::MdnsBootstrapResponder::NONCE_HEX_LENGTH = 24U
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1a6c834267d8586769daacedbfc5581981"></a>

### `RESPONSE_TTL_SECONDS`


```cpp
constexpr uint32_t espectre::MdnsBootstrapResponder::RESPONSE_TTL_SECONDS = 10U
```

   


<a id="classespectre_1_1_mdns_bootstrap_responder_1ad7c040408ec79f780ea13978cd007fa3"></a>

### `~MdnsBootstrapResponder`


```cpp
espectre::MdnsBootstrapResponder::~MdnsBootstrapResponder()
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1ab95bbcd82c6192e292f3f77658901262"></a>

### `setup`


```cpp
bool espectre::MdnsBootstrapResponder::setup()
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1ab785ffa19ea97dd9c4d05b5387959e06"></a>

### `update`


```cpp
bool espectre::MdnsBootstrapResponder::update(uint32_t ipv4_address)
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1a05d87c09dc6a1ee0072639e7dc45e573"></a>

### `loop`


```cpp
void espectre::MdnsBootstrapResponder::loop()
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1a6f5cfb8d78d6a2d0ca71ef60b3729478"></a>

### `shutdown`


```cpp
void espectre::MdnsBootstrapResponder::shutdown()
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1a19e169721cd9ef76e08250f05a009619"></a>

### `active`


```cpp
bool espectre::MdnsBootstrapResponder::active() const
```

   

<a id="classespectre_1_1_mdns_bootstrap_responder_1a8e12a6a872421c51e02d49853dc64ea7"></a>

### `ingest_query`


```cpp
void espectre::MdnsBootstrapResponder::ingest_query(const uint8_t *packet, size_t length, size_t interface, uint32_t source_ipv4, uint16_t source_port)
```

   


<a id="classespectre_1_1_mdns_discovery_service"></a>

## espectre::MdnsDiscoveryService



```cpp
#include <runtime/esp_idf/mdns_discovery_service.h>
```



```cpp
class espectre::MdnsDiscoveryService
```

  

<a id="classespectre_1_1_mdns_discovery_service_1a9bca4f5edf7810ea3426c21807da432d"></a>

### `setup`


```cpp
bool espectre::MdnsDiscoveryService::setup(const MdnsDiscoveryServiceConfig &config)
```

   

<a id="classespectre_1_1_mdns_discovery_service_1a8a4ead7333e20ee71e19fce8140fe287"></a>

### `update_txt`


```cpp
bool espectre::MdnsDiscoveryService::update_txt(const MdnsTxtRecords &txt_records)
```

   

<a id="classespectre_1_1_mdns_discovery_service_1a4756ee87d05459a8a95bb97062088c5b"></a>

### `on_wifi_connected`


```cpp
void espectre::MdnsDiscoveryService::on_wifi_connected()
```

   

<a id="classespectre_1_1_mdns_discovery_service_1a90fffb53d97c2d76c5d1af84e3e5c681"></a>

### `on_wifi_disconnected`


```cpp
void espectre::MdnsDiscoveryService::on_wifi_disconnected()
```

   

<a id="classespectre_1_1_mdns_discovery_service_1aea78330e76641592ac570c395273a9b4"></a>

### `shutdown`


```cpp
void espectre::MdnsDiscoveryService::shutdown()
```

   

<a id="classespectre_1_1_mdns_discovery_service_1aa8896a8b2d043d58738b340d72dafb58"></a>

### `initialized`


```cpp
bool espectre::MdnsDiscoveryService::initialized() const
```

   

<a id="classespectre_1_1_mdns_discovery_service_1a5bc9235099cda7de927791866c0c9547"></a>

### `service_enabled`


```cpp
bool espectre::MdnsDiscoveryService::service_enabled() const
```

   


<a id="structespectre_1_1_mdns_discovery_service_config"></a>

## espectre::MdnsDiscoveryServiceConfig



```cpp
#include <runtime/esp_idf/mdns_discovery_service.h>
```



```cpp
struct espectre::MdnsDiscoveryServiceConfig
```

  

<a id="structespectre_1_1_mdns_discovery_service_config_1a1b122f1021e95de3f1668fcb67346cf9"></a>

### `hostname`


```cpp
std::string espectre::MdnsDiscoveryServiceConfig::hostname
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1a9c632f66f8b84dd2aabf6c5c75d46202"></a>

### `instance_name`


```cpp
std::string espectre::MdnsDiscoveryServiceConfig::instance_name
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1a2b72aeb06aa4a27468f88314c1e1b8bd"></a>

### `service_type`


```cpp
std::string espectre::MdnsDiscoveryServiceConfig::service_type
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1addcc38c93c25c34118c999bca3ec233a"></a>

### `service_protocol`


```cpp
std::string espectre::MdnsDiscoveryServiceConfig::service_protocol
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1a872e38c6f5141daa04bfa58db661efa7"></a>

### `port`


```cpp
uint16_t espectre::MdnsDiscoveryServiceConfig::port {0U}
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1a046eb2615b1c2196f28367e02ebc87e9"></a>

### `txt_records`


```cpp
MdnsTxtRecords espectre::MdnsDiscoveryServiceConfig::txt_records
```

   

<a id="structespectre_1_1_mdns_discovery_service_config_1a43c7aa08b72548d6c707a2acef1b92b6"></a>

### `responder_mode`


```cpp
MdnsResponderMode espectre::MdnsDiscoveryServiceConfig::responder_mode {MdnsResponderMode::OWN_RESPONDER}
```

   


<a id="classespectre_1_1_mqtt_payload_assembler"></a>

## espectre::MqttPayloadAssembler



```cpp
#include <runtime/mqtt_payload_assembler.h>
```



```cpp
class espectre::MqttPayloadAssembler
```

  

<a id="classespectre_1_1_mqtt_payload_assembler_1ae7648d5e3141b89ddd898b43a21527f8"></a>

### `Result`


```cpp
enum class Result
```

   

<a id="classespectre_1_1_mqtt_payload_assembler_1ae7648d5e3141b89ddd898b43a21527f8a2e47f45b8584e07c8ebd4f693d8cfe10"></a>

`INCOMPLETE`

  

<a id="classespectre_1_1_mqtt_payload_assembler_1ae7648d5e3141b89ddd898b43a21527f8a3de44296982e58199afc513a715b12ba"></a>

`COMPLETE`

  

<a id="classespectre_1_1_mqtt_payload_assembler_1ae7648d5e3141b89ddd898b43a21527f8accc0377a8afbf50e7094f5c23a8af223"></a>

`INVALID`

  


<a id="classespectre_1_1_mqtt_payload_assembler_1a92e491dad0240bc4e4885b0400aecc8b"></a>

### `MAX_PAYLOAD_SIZE`


```cpp
constexpr size_t espectre::MqttPayloadAssembler::MAX_PAYLOAD_SIZE = ESPECTRE_COMMAND_MAX_PAYLOAD_SIZE
```

   


<a id="classespectre_1_1_mqtt_payload_assembler_1abe9b537f730d61ed783ba8b7d6b3e1fa"></a>

### `append`


```cpp
Result espectre::MqttPayloadAssembler::append(const char *data, size_t data_len, size_t total_len, size_t offset)
```

   

<a id="classespectre_1_1_mqtt_payload_assembler_1a2be44e2d3cb32c9add9f1c06eb3737ca"></a>

### `payload`


```cpp
std::string_view espectre::MqttPayloadAssembler::payload() const
```

   

<a id="classespectre_1_1_mqtt_payload_assembler_1afa907c956ada6e8b6da584de292088f1"></a>

### `reset`


```cpp
void espectre::MqttPayloadAssembler::reset()
```

   


<a id="structespectre_1_1_mqtt_transport_diagnostics"></a>

## espectre::MqttTransportDiagnostics



```cpp
#include <runtime/mqtt_transport.h>
```



```cpp
struct espectre::MqttTransportDiagnostics
```

  

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a57f23464d94bd6e89343fa67a9c5d891"></a>

### `queue_capacity`


```cpp
size_t espectre::MqttTransportDiagnostics::queue_capacity {0U}
```

   

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a25432ed4113bcf1ba97f39fe73777c9f"></a>

### `outbox_capacity_bytes`


```cpp
size_t espectre::MqttTransportDiagnostics::outbox_capacity_bytes {0U}
```

   

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a1a9aedeafb50f0aeda3b56b3912661a5"></a>

### `queued_publishes`


```cpp
size_t espectre::MqttTransportDiagnostics::queued_publishes {0U}
```

   

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a25bba45d97b4adeb25d61e3773829985"></a>

### `dropped_publishes`


```cpp
uint32_t espectre::MqttTransportDiagnostics::dropped_publishes {0U}
```

   

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a8b6bd7d2dfaac1e23aea8ecf8898eca2"></a>

### `publish_failures`


```cpp
uint32_t espectre::MqttTransportDiagnostics::publish_failures {0U}
```

   

<a id="structespectre_1_1_mqtt_transport_diagnostics_1a6a8233be7136f4a79616df527108b258"></a>

### `reconnects`


```cpp
uint32_t espectre::MqttTransportDiagnostics::reconnects {0U}
```

   


<a id="structespectre_1_1_peer_discovery_candidate"></a>

## espectre::PeerDiscoveryCandidate



```cpp
#include <runtime/peer_discovery.h>
```



```cpp
struct espectre::PeerDiscoveryCandidate
```

  

<a id="structespectre_1_1_peer_discovery_candidate_1a2d5778b7ef895ea38a0cfc176e28866e"></a>

### `instance`


```cpp
std::string espectre::PeerDiscoveryCandidate::instance
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1ab89b27af773b55a3928fd8062ee2d86b"></a>

### `hostname`


```cpp
std::string espectre::PeerDiscoveryCandidate::hostname
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a0cb2d0eeab818141ddb73739215e56e8"></a>

### `device_id`


```cpp
std::string espectre::PeerDiscoveryCandidate::device_id
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1abad2df8531fd04b073e07f0cad38ad4a"></a>

### `name`


```cpp
std::string espectre::PeerDiscoveryCandidate::name
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1acbb95beb16745ead3f6f278dbd62d03b"></a>

### `frontend`


```cpp
std::string espectre::PeerDiscoveryCandidate::frontend
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a8a1a8899c7557f2b1e0cdf9684792731"></a>

### `txt_version`


```cpp
std::string espectre::PeerDiscoveryCandidate::txt_version
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a7d354f75bec29ca21378d5258cdf3b94"></a>

### `protocol_version`


```cpp
std::string espectre::PeerDiscoveryCandidate::protocol_version
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1ac354bb8df10122355d7eabf1072be6c0"></a>

### `transport`


```cpp
std::string espectre::PeerDiscoveryCandidate::transport
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a7ed3aee56d18d0e3a23a9f0f25b178cd"></a>

### `path`


```cpp
std::string espectre::PeerDiscoveryCandidate::path
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a1d45f9d1267ac44d120bf0d2c4266f03"></a>

### `firmware`


```cpp
std::string espectre::PeerDiscoveryCandidate::firmware
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a20721debec00cbc2392fbbc87473bd3d"></a>

### `chip`


```cpp
std::string espectre::PeerDiscoveryCandidate::chip
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a571b201c3eefb9ff5df2704436a9cd3f"></a>

### `capabilities`


```cpp
std::string espectre::PeerDiscoveryCandidate::capabilities
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a340e803e81a292c10c0bd5a868abb6d3"></a>

### `port`


```cpp
uint16_t espectre::PeerDiscoveryCandidate::port {0U}
```

   

<a id="structespectre_1_1_peer_discovery_candidate_1a4c4748768d568fcd2417c54669d0f28d"></a>

### `ipv4_addresses`


```cpp
std::vector<uint32_t> espectre::PeerDiscoveryCandidate::ipv4_addresses
```

   


<a id="structespectre_1_1_peer_discovery_snapshot"></a>

## espectre::PeerDiscoverySnapshot



```cpp
#include <runtime/peer_discovery.h>
```



```cpp
struct espectre::PeerDiscoverySnapshot
```

  

<a id="structespectre_1_1_peer_discovery_snapshot_1a473a8af1eaf8d087b009d62ab3f551ba"></a>

### `elapsed_ms`


```cpp
uint32_t espectre::PeerDiscoverySnapshot::elapsed_ms {0U}
```

   

<a id="structespectre_1_1_peer_discovery_snapshot_1a2a6b95456424813636302cdc39624ca2"></a>

### `timed_out`


```cpp
bool espectre::PeerDiscoverySnapshot::timed_out {false}
```

   

<a id="structespectre_1_1_peer_discovery_snapshot_1a79217af1072e21bb9c45b8c3a722f872"></a>

### `truncated`


```cpp
bool espectre::PeerDiscoverySnapshot::truncated {false}
```

   

<a id="structespectre_1_1_peer_discovery_snapshot_1abd303c6912222a2338686f1a0c120b8e"></a>

### `rejected_results`


```cpp
size_t espectre::PeerDiscoverySnapshot::rejected_results {0U}
```

   

<a id="structespectre_1_1_peer_discovery_snapshot_1ae14eb3461048718dbadd944cc5b6bf03"></a>

### `devices`


```cpp
std::vector<PeerDiscoveryCandidate> espectre::PeerDiscoverySnapshot::devices
```

   


<a id="classespectre_1_1_pending_event"></a>

## espectre::PendingEvent



```cpp
#include <runtime/pending_event.h>
```



```cpp
template <typename... Ts>
class espectre::PendingEvent
```

 

Single-slot mailbox carrying an event with an optional payload.

  

[post()](#classespectre_1_1_pending_event_1af79ae9ab56f40807b4bbff6b16bba1e0) records the event and overwrites any unconsumed payload, so events coalesce to the most recent one. [take()](#classespectre_1_1_pending_event_1ad03dda7136be67a473aea263aaa82bae) consumes at most one event per call. Single producer, single consumer.

 

Access is serialized with a lightweight critical section. On ESP-IDF this remains safe from both task and ISR context, including the CSI callback path. On host builds, tests use a regular mutex with the same coalescing semantics.

 

<a id="classespectre_1_1_pending_event_1af79ae9ab56f40807b4bbff6b16bba1e0"></a>

### `post`


```cpp
void espectre::PendingEvent< Ts >::post(Ts... values)
```

   

<a id="classespectre_1_1_pending_event_1ad03dda7136be67a473aea263aaa82bae"></a>

### `take`


```cpp
bool espectre::PendingEvent< Ts >::take(Ts &...out)
```

   

<a id="classespectre_1_1_pending_event_1aed0bf169385a4196d542dedec1ff35f5"></a>

### `clear`


```cpp
void espectre::PendingEvent< Ts >::clear()
```

   


<a id="classespectre_1_1_pending_queue"></a>

## espectre::PendingQueue



```cpp
#include <runtime/pending_queue.h>
```



```cpp
template <typename T, size_t Capacity>
class espectre::PendingQueue
```

 

Fixed-capacity FIFO for callback-to-loop handoff.

  

[post()](#classespectre_1_1_pending_queue_1aa971a069073a9d16138ff75e5ccb2ad4) never allocates or blocks: it returns false when the queue is full. The consumer drains records with [take()](#classespectre_1_1_pending_queue_1aa9b530fa51f2b30d7a1688bf10d32d58) from its owning task. T must remain trivially copyable because ESP-IDF protects the short copy with a critical section that must not run constructors, destructors, or heap allocation.

 

<a id="classespectre_1_1_pending_queue_1aa971a069073a9d16138ff75e5ccb2ad4"></a>

### `post`


```cpp
bool espectre::PendingQueue< T, Capacity >::post(const T &value)
```

   

<a id="classespectre_1_1_pending_queue_1a7d3f4c1a69924ab5eb5bfec2e0c8baca"></a>

### `post_overwrite_oldest`


```cpp
bool espectre::PendingQueue< T, Capacity >::post_overwrite_oldest(const T &value)
```

 

Append a record, discarding the oldest record when the queue is full.

  

**Returns:** true when no record was discarded.

  

<a id="classespectre_1_1_pending_queue_1aa9b530fa51f2b30d7a1688bf10d32d58"></a>

### `take`


```cpp
bool espectre::PendingQueue< T, Capacity >::take(T &value)
```

   

<a id="classespectre_1_1_pending_queue_1a38633383c3a20b1b53f82d8890e17525"></a>

### `clear`


```cpp
void espectre::PendingQueue< T, Capacity >::clear()
```

   

<a id="classespectre_1_1_pending_queue_1adf95f881daf5bbf3376b5f34c5199276"></a>

### `size`


```cpp
size_t espectre::PendingQueue< T, Capacity >::size() const
```

   


<a id="structespectre_1_1_raw_csi_http_frame_prefix"></a>

## espectre::RawCsiHttpFramePrefix



```cpp
#include <runtime/raw_csi.h>
```



```cpp
struct espectre::RawCsiHttpFramePrefix
```

  

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1aff63ce4fc7a4e08371da97d54cb746c5"></a>

### `magic`


```cpp
uint32_t espectre::RawCsiHttpFramePrefix::magic
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1ac4f5786b99681c4cad962c0f97dfafbf"></a>

### `version`


```cpp
uint8_t espectre::RawCsiHttpFramePrefix::version
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1a16b90d015a0fdb3b5fbc67ea5c925480"></a>

### `record_version`


```cpp
uint8_t espectre::RawCsiHttpFramePrefix::record_version
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1a4310fd9517fadbec9303fe3305c0a36d"></a>

### `header_len`


```cpp
uint16_t espectre::RawCsiHttpFramePrefix::header_len
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1a4519c8824b89b80a0fe4236319e2f840"></a>

### `session_id`


```cpp
uint8_t espectre::RawCsiHttpFramePrefix::session_id[ESPECTRE_RAW_CSI_SESSION_ID_BYTES][ESPECTRE_RAW_CSI_SESSION_ID_BYTES]
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1a1aab45e916774b1d37733a135b6ad862"></a>

### `stream_sequence`


```cpp
uint64_t espectre::RawCsiHttpFramePrefix::stream_sequence
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1ae2ce8f1c1b320fd785fa96cb84902e91"></a>

### `record_len`


```cpp
uint16_t espectre::RawCsiHttpFramePrefix::record_len
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1a1afdf43be2cc516e3a13302a17fa1d9e"></a>

### `flags`


```cpp
uint16_t espectre::RawCsiHttpFramePrefix::flags
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1aff647ce0eab14075108180bf3dabd939"></a>

### `fresh_record_total`


```cpp
uint64_t espectre::RawCsiHttpFramePrefix::fresh_record_total
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1abea7ebe4270089f9268e923847b02bf9"></a>

### `raw_drop_total`


```cpp
uint64_t espectre::RawCsiHttpFramePrefix::raw_drop_total
```

   

<a id="structespectre_1_1_raw_csi_http_frame_prefix_1ade022647201de886fa85623153e474fd"></a>

### `raw_send_backpressure_total`


```cpp
uint64_t espectre::RawCsiHttpFramePrefix::raw_send_backpressure_total
```

   


<a id="structespectre_1_1_raw_csi_packet_view"></a>

## espectre::RawCsiPacketView



```cpp
#include <runtime/raw_csi.h>
```



```cpp
struct espectre::RawCsiPacketView
```

 

Callback-scoped view of one normalized raw CSI packet.

  

The struct and the bytes addressed by [`csi`](#structespectre_1_1_raw_csi_packet_view_1a518f5bc92cc9b0b4d2d8ac60cda60cb1) are valid only for the duration of the capture callback. Copy them before returning if another task needs the sample. The built-in capture pipeline supplies HT20\_CSI\_LEN bytes (64 complex subcarriers) after LLTF, HT, or VHT normalization. This normalized capture bound is independent of RAW\_CSI\_MAX\_PAYLOAD\_BYTES, the record-format limit.

 

<a id="structespectre_1_1_raw_csi_packet_view_1a518f5bc92cc9b0b4d2d8ac60cda60cb1"></a>

### `csi`


```cpp
const int8_t* espectre::RawCsiPacketView::csi {nullptr}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a595517f6c85eedfe92c2bd0f3b27fdef"></a>

### `csi_len`


```cpp
uint16_t espectre::RawCsiPacketView::csi_len {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1ab750df6d53c73e68797581458488b832"></a>

### `captured_at_us`


```cpp
uint64_t espectre::RawCsiPacketView::captured_at_us {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a0961514d44a91e8922fb371098117fd2"></a>

### `wifi_rx_ts_us`


```cpp
uint32_t espectre::RawCsiPacketView::wifi_rx_ts_us {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1af3a7348adcbc7adff1ea8f07f9f75c75"></a>

### `wifi_rx_start_ts_ns`


```cpp
uint64_t espectre::RawCsiPacketView::wifi_rx_start_ts_ns {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a4550d70cf63fd67ecaaba4a96f7532aa"></a>

### `record_flags`


```cpp
uint8_t espectre::RawCsiPacketView::record_flags {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1af2ded4c9345b6b13f1136a1cc3d34f22"></a>

### `channel`


```cpp
uint8_t espectre::RawCsiPacketView::channel {0U}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a6b31d1c641df6c888905d3d1d2a15bc4"></a>

### `rssi_dbm`


```cpp
int8_t espectre::RawCsiPacketView::rssi_dbm {0}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a1c4362c1daa8093dccf22a2f20ef5529"></a>

### `noise_floor_dbm`


```cpp
int8_t espectre::RawCsiPacketView::noise_floor_dbm {0}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a66bf7a3613a973d694bed6c12e3b6948"></a>

### `phy_mode`


```cpp
RawCsiPhyMode espectre::RawCsiPacketView::phy_mode {RawCsiPhyMode::UNKNOWN}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a94a64374b6cedf012a2a0dfc63edcc94"></a>

### `ltf_type`


```cpp
RawCsiLtfType espectre::RawCsiPacketView::ltf_type {RawCsiLtfType::UNKNOWN}
```

   

<a id="structespectre_1_1_raw_csi_packet_view_1a1df4e8233c12a8488b33f692f28ab34f"></a>

### `channel_width`


```cpp
RawCsiChannelWidth espectre::RawCsiPacketView::channel_width {RawCsiChannelWidth::UNKNOWN}
```

   


<a id="structespectre_1_1_raw_csi_record_header_v7"></a>

## espectre::RawCsiRecordHeaderV7



```cpp
#include <runtime/csi_raw_record.h>
```



```cpp
struct espectre::RawCsiRecordHeaderV7
```

  

<a id="structespectre_1_1_raw_csi_record_header_v7_1a93f9976a07e973bec081ff4b8272ffbc"></a>

### `magic`


```cpp
uint16_t espectre::RawCsiRecordHeaderV7::magic
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1afb7b0fe8577ab7989e57323f8cca3fe0"></a>

### `version`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::version
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a1d3e26816a135f92dc23db44f9c0ce6d"></a>

### `header_len`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::header_len
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1add7b57b09edbb810989fae3a2daa4533"></a>

### `chip`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::chip
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a238a7b3f25a9741cdfaca8ce9ebdc1a9"></a>

### `flags`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::flags
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a5c2c5ce6944f9628a4cb2d207a7d959d"></a>

### `seq_num`


```cpp
uint32_t espectre::RawCsiRecordHeaderV7::seq_num
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a21317d8a74cea682a62326607078d5b8"></a>

### `num_subcarriers`


```cpp
uint16_t espectre::RawCsiRecordHeaderV7::num_subcarriers
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1ad3422bf4b898d003882e585d689fabaa"></a>

### `csi_len_bytes`


```cpp
uint16_t espectre::RawCsiRecordHeaderV7::csi_len_bytes
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a47ae5e50512d802c51bf3cd13be856af"></a>

### `device_id`


```cpp
uint64_t espectre::RawCsiRecordHeaderV7::device_id
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1ab03f7c1c53320d0797cce996284aa276"></a>

### `device_ticks_us`


```cpp
uint64_t espectre::RawCsiRecordHeaderV7::device_ticks_us
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a2f8ce8997e5a2eb71922bcf5487031af"></a>

### `wifi_rx_ts_us`


```cpp
uint32_t espectre::RawCsiRecordHeaderV7::wifi_rx_ts_us
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a13de444682924ede1862e3e625e5cdc8"></a>

### `wifi_rx_start_ts_ns`


```cpp
uint64_t espectre::RawCsiRecordHeaderV7::wifi_rx_start_ts_ns
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1aacd024efb5a72097899a6fd8df5ac257"></a>

### `channel`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::channel
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a4c04d20afbdcec22381e57cc9a8fde55"></a>

### `rssi_dbm`


```cpp
int8_t espectre::RawCsiRecordHeaderV7::rssi_dbm
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1ab636e81b4234fb7ee0f6d6752d1a09c1"></a>

### `noise_floor_dbm`


```cpp
int8_t espectre::RawCsiRecordHeaderV7::noise_floor_dbm
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a5fd2e260cff665197ba5542916b5006e"></a>

### `transport_backpressure_total`


```cpp
uint64_t espectre::RawCsiRecordHeaderV7::transport_backpressure_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1ac6199be884583c4c0bfe2793bfb2ccd8"></a>

### `fresh_record_total`


```cpp
uint32_t espectre::RawCsiRecordHeaderV7::fresh_record_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a22e63d1fc7989660f9f4eb1e762380e7"></a>

### `traffic_packets_total`


```cpp
uint32_t espectre::RawCsiRecordHeaderV7::traffic_packets_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1adb3ddc7d490ba5914c251549bbced459"></a>

### `phy_mode`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::phy_mode
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1aa631001993d93a3f99ff10a21bda81e0"></a>

### `ltf_type`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::ltf_type
```

   

<a id="structespectre_1_1_raw_csi_record_header_v7_1a712bc6d3f3e38d3a8fa6d374220cc90f"></a>

### `channel_width`


```cpp
uint8_t espectre::RawCsiRecordHeaderV7::channel_width
```

   


<a id="structespectre_1_1_raw_csi_record_header_v8"></a>

## espectre::RawCsiRecordHeaderV8



```cpp
#include <runtime/csi_raw_record.h>
```



```cpp
struct espectre::RawCsiRecordHeaderV8
```

 

Transport-neutral raw CSI record emitted by Direct raw collection.

  

<a id="structespectre_1_1_raw_csi_record_header_v8_1a2be7e3fe64a7ad696429405bc01eb145"></a>

### `magic`


```cpp
uint16_t espectre::RawCsiRecordHeaderV8::magic
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a63bfbc147266f17ce8e0ca11fbd4eecc"></a>

### `version`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::version
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a9600a4ab094c962b3551e1886523e9f8"></a>

### `header_len`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::header_len
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a5f3a5c11eabed7999a830d818ec4904e"></a>

### `chip`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::chip
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a7e2b9459ba67ad46bb4a93384b35beff"></a>

### `flags`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::flags
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1aef74dacf16ba25a8ce3bde3d46b6979b"></a>

### `seq_num`


```cpp
uint32_t espectre::RawCsiRecordHeaderV8::seq_num
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1acd10191805ae0cc24b2cf50ce5b0ec86"></a>

### `num_subcarriers`


```cpp
uint16_t espectre::RawCsiRecordHeaderV8::num_subcarriers
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a023ae711e0a5af78d436ee6927e72a93"></a>

### `csi_len_bytes`


```cpp
uint16_t espectre::RawCsiRecordHeaderV8::csi_len_bytes
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1ad9da0926689f413708e83d94e29aa3e9"></a>

### `device_id`


```cpp
uint64_t espectre::RawCsiRecordHeaderV8::device_id
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a2309743c2ab9d1ec26e9e3f7ff4c8881"></a>

### `device_ticks_us`


```cpp
uint64_t espectre::RawCsiRecordHeaderV8::device_ticks_us
```

 

Monotonic device time captured with the CSI sample.

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a79e1bfe6b2254f5be7cf4f4a40020877"></a>

### `wifi_rx_ts_us`


```cpp
uint32_t espectre::RawCsiRecordHeaderV8::wifi_rx_ts_us
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1acf55ce899c8d2cf518a15b4c0f59b705"></a>

### `wifi_rx_start_ts_ns`


```cpp
uint64_t espectre::RawCsiRecordHeaderV8::wifi_rx_start_ts_ns
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1acc3237a83d4782265ec7256b0823e3f8"></a>

### `channel`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::channel
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1ad954b162911a918cff26d75ef6e4d07d"></a>

### `rssi_dbm`


```cpp
int8_t espectre::RawCsiRecordHeaderV8::rssi_dbm
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a95e7928f62ae72588421ba826bd080cc"></a>

### `noise_floor_dbm`


```cpp
int8_t espectre::RawCsiRecordHeaderV8::noise_floor_dbm
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a2a0ceacb775707eb740176834364b33a"></a>

### `transport_backpressure_total`


```cpp
uint64_t espectre::RawCsiRecordHeaderV8::transport_backpressure_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a9bea32173dff7bc07a0537cf8f41acf9"></a>

### `fresh_record_total`


```cpp
uint32_t espectre::RawCsiRecordHeaderV8::fresh_record_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a994a6ea793326afe12c8ecfde222a7b3"></a>

### `request_accepted_total`


```cpp
uint32_t espectre::RawCsiRecordHeaderV8::request_accepted_total
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1abd87cbb6fdffc6f3e26a0e9ed12725ad"></a>

### `phy_mode`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::phy_mode
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a855dfc7a80986911adf5c337c2dea3e1"></a>

### `ltf_type`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::ltf_type
```

   

<a id="structespectre_1_1_raw_csi_record_header_v8_1a1442437f89c541d25b34a6539d934916"></a>

### `channel_width`


```cpp
uint8_t espectre::RawCsiRecordHeaderV8::channel_width
```

   


<a id="structespectre_1_1_raw_csi_session_config"></a>

## espectre::RawCsiSessionConfig



```cpp
#include <runtime/raw_csi.h>
```



```cpp
struct espectre::RawCsiSessionConfig
```

  

<a id="structespectre_1_1_raw_csi_session_config_1a64034c747a85e38ec0b3e3393d87610d"></a>

### `session_id`


```cpp
uint8_t espectre::RawCsiSessionConfig::session_id[ESPECTRE_RAW_CSI_SESSION_ID_BYTES][ESPECTRE_RAW_CSI_SESSION_ID_BYTES] {}
```

   

<a id="structespectre_1_1_raw_csi_session_config_1a330ce1101930b0bc35e51a6dddfbeb89"></a>

### `device_id`


```cpp
uint64_t espectre::RawCsiSessionConfig::device_id {0U}
```

   

<a id="structespectre_1_1_raw_csi_session_config_1a3b93ff18005d0b24237d29635cb7184d"></a>

### `chip`


```cpp
RawCsiChipType espectre::RawCsiSessionConfig::chip {RawCsiChipType::UNKNOWN}
```

   


<a id="classespectre_1_1_raw_csi_session_controller"></a>

## espectre::RawCsiSessionController



```cpp
#include <runtime/esp_idf/raw_csi_session_controller.h>
```



```cpp
class espectre::RawCsiSessionController
```

  

<a id="classespectre_1_1_raw_csi_session_controller_1ae9cf91a097cfb99ff2017f48b0175201"></a>

### `StoppedCallback`


```cpp
using espectre::RawCsiSessionController::StoppedCallback = std::function<void(RawCsiStopReason reason)>
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1abd15e43bf15014bdd32b80449dd791cb"></a>

### `StartedCallback`


```cpp
using espectre::RawCsiSessionController::StartedCallback = std::function<void()>
```

   


<a id="classespectre_1_1_raw_csi_session_controller_1aad3fc3c7ed2079d4945e2a61054e42dc"></a>

### `configure`


```cpp
void espectre::RawCsiSessionController::configure(IDirectHttpService *service, RuntimeFrontendController *runtime, uint64_t device_id, std::string chip, StoppedCallback stopped_callback={}, StartedCallback started_callback={})
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1a45dd512dc354889488db60208e551660"></a>

### `handle_command`


```cpp
bool espectre::RawCsiSessionController::handle_command(const EspectreCommand &command, const FrontendCommandContext &context, std::string *code, std::string *message, std::string *data_json)
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1a1e7634c8a365a87f71f760acbc675f37"></a>

### `begin`


```cpp
bool espectre::RawCsiSessionController::begin(std::string *message=nullptr)
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1a52e62ad8344a6e0ed58060f483fa0191"></a>

### `ensure_runtime_consistency`


```cpp
void espectre::RawCsiSessionController::ensure_runtime_consistency()
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1aedcad49435d24cd25e14fff9ee1b79ba"></a>

### `shutdown`


```cpp
void espectre::RawCsiSessionController::shutdown(RawCsiStopReason reason=RawCsiStopReason::SHUTDOWN)
```

   

<a id="classespectre_1_1_raw_csi_session_controller_1a520a1ab907c02b461de790cd6342881e"></a>

### `active`


```cpp
bool espectre::RawCsiSessionController::active() const
```

   


<a id="structespectre_1_1_raw_csi_session_diagnostics"></a>

## espectre::RawCsiSessionDiagnostics



```cpp
#include <runtime/raw_csi.h>
```



```cpp
struct espectre::RawCsiSessionDiagnostics
```

  

<a id="structespectre_1_1_raw_csi_session_diagnostics_1a9d6559b9af3fe917d1d706cdfa9908fd"></a>

### `active`


```cpp
bool espectre::RawCsiSessionDiagnostics::active {false}
```

   

<a id="structespectre_1_1_raw_csi_session_diagnostics_1a00dfeb74a7853d881d5daf28fe46d19a"></a>

### `binary_bound`


```cpp
bool espectre::RawCsiSessionDiagnostics::binary_bound {false}
```

   

<a id="structespectre_1_1_raw_csi_session_diagnostics_1af028b03fa5574f470cb775528e731902"></a>

### `raw_drop_total`


```cpp
uint64_t espectre::RawCsiSessionDiagnostics::raw_drop_total {0U}
```

   

<a id="structespectre_1_1_raw_csi_session_diagnostics_1a949a317f2743710686258f4315cf8250"></a>

### `raw_send_backpressure_total`


```cpp
uint64_t espectre::RawCsiSessionDiagnostics::raw_send_backpressure_total {0U}
```

   

<a id="structespectre_1_1_raw_csi_session_diagnostics_1a4c48a663c7d565f0b9fe478e218b76a3"></a>

### `fresh_record_total`


```cpp
uint64_t espectre::RawCsiSessionDiagnostics::fresh_record_total {0U}
```

   

<a id="structespectre_1_1_raw_csi_session_diagnostics_1af7f644fe02ab9bea2e3ba52d33a5bc59"></a>

### `stream_sequence`


```cpp
uint64_t espectre::RawCsiSessionDiagnostics::stream_sequence {0U}
```

   


<a id="structespectre_1_1_runtime_capabilities"></a>

## espectre::RuntimeCapabilities



```cpp
#include <runtime/runtime_capabilities.h>
```



```cpp
struct espectre::RuntimeCapabilities
```

 

What a runtime actually offers its frontend.

  

Every flag defaults to false on purpose: API.md makes this block the contract clients read, so a capability has to be declared rather than inherited from a permissive default. Previously only the stream runtime declared anything and the sensing runtime shipped whatever the struct happened to default to.

 

[`supports_live_telemetry`](#structespectre_1_1_runtime_capabilities_1a7c29851c92d3dce3570e44946c055948) describes the runtime side of the surface: whether it drives the live-telemetry callback at all.

 

<a id="structespectre_1_1_runtime_capabilities_1a73c517a443cb659c29fe03926926d7b6"></a>

### `supports_runtime_threshold_updates`


```cpp
bool espectre::RuntimeCapabilities::supports_runtime_threshold_updates {false}
```

 

`set_threshold_runtime()` is honored.

   

<a id="structespectre_1_1_runtime_capabilities_1a84d3b5bb447e02b9026bdb81f69db236"></a>

### `supports_runtime_motion_hits_updates`


```cpp
bool espectre::RuntimeCapabilities::supports_runtime_motion_hits_updates {false}
```

 

`set_motion_hits_runtime()` is honored; otherwise the controller refuses it.

   

<a id="structespectre_1_1_runtime_capabilities_1a8a74863f469d46c8a8441ef4e58c6b66"></a>

### `supports_runtime_detector_selection`


```cpp
bool espectre::RuntimeCapabilities::supports_runtime_detector_selection {false}
```

 

`set_detection_algorithm_runtime()` is honored.

  

Driven by [`RuntimeConfig::runtime_detector_selection_enabled`](#structespectre_1_1_runtime_config_1adb8b5784fab9a57ecc354c281b3cd799), since switching detectors also means persisting and restoring the choice.

  

<a id="structespectre_1_1_runtime_capabilities_1a1457a33557663be153d4472ac9192b20"></a>

### `supports_manual_recalibration`


```cpp
bool espectre::RuntimeCapabilities::supports_manual_recalibration {false}
```

 

`trigger_recalibration()` is honored; otherwise the controller refuses it.

   

<a id="structespectre_1_1_runtime_capabilities_1a7c29851c92d3dce3570e44946c055948"></a>

### `supports_live_telemetry`


```cpp
bool espectre::RuntimeCapabilities::supports_live_telemetry {false}
```

 

The runtime drives [`IRuntimeListener::on_live_telemetry()`](#classespectre_1_1_i_runtime_listener_1a2473b19c1324d186b11ba596000acde9) at all.

  

Native uses that callback for MQTT sensing telemetry and Home Assistant Movement Score. Transport adapters decide how to forward live sensing.

  

<a id="structespectre_1_1_runtime_capabilities_1ab38fbc94f33d1f3dace27cca8e48f0c3"></a>

### `supports_extended_diagnostics`


```cpp
bool espectre::RuntimeCapabilities::supports_extended_diagnostics {false}
```

 

The runtime reports the extended fields used by diagnostics payloads.

   

<a id="structespectre_1_1_runtime_capabilities_1a9cb79d6a0f22efbcfecabc4d4747fedb"></a>

### `supports_traffic_control`


```cpp
bool espectre::RuntimeCapabilities::supports_traffic_control {false}
```

 

The runtime owns CSI traffic generation and can be asked to retune it.

   

<a id="structespectre_1_1_runtime_capabilities_1ae02edf210122c8ba729173b427c0dec2"></a>

### `supports_raw_csi`


```cpp
bool espectre::RuntimeCapabilities::supports_raw_csi {false}
```

 

The runtime can temporarily bypass sensing and expose normalized raw CSI.

   


<a id="structespectre_1_1_runtime_config"></a>

## espectre::RuntimeConfig



```cpp
#include <runtime/runtime_interface.h>
```



```cpp
struct espectre::RuntimeConfig
```

 

Everything the runtime needs to know before `setup()`.

  

Every member is default-constructed to a supported production value, so [`RuntimeConfig{}`](#structespectre_1_1_runtime_config) is a working configuration for Lightweight Detection on internally generated traffic. Override only what your product changes.

 

Ranges are declared in [`runtime_sensing_schema.h`](#runtime__sensing__schema_8h) as `RUNTIME_<FIELD>_MIN` / `_MAX` / `_DEFAULT`, and the free functions in [`runtime_config_utils.h`](#runtime__config__utils_8h) validate against them. On ESP-IDF you can build this from menuconfig with [`make_runtime_sensing_config_from_kconfig()`](#namespaceespectre_1ab070877204ffb133b519d0b163420df6) instead of assigning fields by hand.

 

The config is copied into the runtime at `setup()`. Later edits to your own copy have no effect; use the `set_*_runtime()` control methods instead.

 

<a id="structespectre_1_1_runtime_config_1a25ee9c5959eab5442f6404873431c83b"></a>

### `runtime_profile`


```cpp
RuntimeProfile espectre::RuntimeConfig::runtime_profile {RuntimeProfile::SENSING}
```

 

Which backend to build: motion sensing, or raw CSI streaming to a collector.

   

<a id="structespectre_1_1_runtime_config_1a8802e0c9228e203ce428e689604eed0a"></a>

### `wifi_band_policy`


```cpp
WifiBandPolicy espectre::RuntimeConfig::wifi_band_policy {WifiBandPolicy::BAND_2G}
```

 

Band available to the station while the runtime keeps the PHY at HT20.

  

`BAND_5G` and `AUTO` require dual-band silicon. Keeping `BAND_2G` as the default preserves the band covered by the production detector corpus.

  

<a id="structespectre_1_1_runtime_config_1aa9f87f98efcfc12d94c9fc5a54b86866"></a>

### `csi_capture_profile`


```cpp
CsiCapturePolicy espectre::RuntimeConfig::csi_capture_profile {CsiCapturePolicy::AUTO}
```

 

Build-time CSI profile; AUTO resolves from chip, band, and the active traffic source.

  

No runtime setter.

  

<a id="structespectre_1_1_runtime_config_1a3d14cc007fe6107bd81c6c6da176327a"></a>

### `detection_algorithm`


```cpp
DetectionAlgorithm espectre::RuntimeConfig::detection_algorithm {DetectionAlgorithm::LIGHTWEIGHT}
```

 

Detection profile to run.

  

Lightweight self-calibrates; High Accuracy uses trained weights.

  

<a id="structespectre_1_1_runtime_config_1a6964f57f534bc0e5e8156b93d39266c4"></a>

### `segmentation_threshold`


```cpp
float espectre::RuntimeConfig::segmentation_threshold {RUNTIME_SEGMENTATION_THRESHOLD_DEFAULT}
```

 

Motion probability threshold, on the same 0..1 scale as [`RuntimeSnapshot::movement_metric`](#structespectre_1_1_runtime_snapshot_1a6844aeb15178c5088d4564c5719361c7).

  

Lightweight Detection overwrites this during startup calibration, so the configured value only governs the pre-calibration window. High-Accuracy Detection keeps it as given.

  

<a id="structespectre_1_1_runtime_config_1a1e4b55ccb756b4610b72be1d8cacf88d"></a>

### `segmentation_window_size_ms`


```cpp
uint32_t espectre::RuntimeConfig::segmentation_window_size_ms {RUNTIME_SEGMENTATION_WINDOW_SIZE_MS_DEFAULT}
```

 

Detector window duration in milliseconds (1000..2000).

  

Runtimes resolve the duration to a fixed temporal grid from [`csi_target_pps`](#structespectre_1_1_runtime_config_1a0dbde3a8ad2fed884033fe0855153461); live arrival jitter never resizes the detector.

  

<a id="structespectre_1_1_runtime_config_1adb8b5784fab9a57ecc354c281b3cd799"></a>

### `runtime_detector_selection_enabled`


```cpp
bool espectre::RuntimeConfig::runtime_detector_selection_enabled {false}
```

 

Advertise runtime detector switching.

  

When true the runtime restores the persisted detector choice at `setup()` and sets [`RuntimeCapabilities::supports_runtime_detector_selection`](#structespectre_1_1_runtime_capabilities_1a8a74863f469d46c8a8441ef4e58c6b66).

  

<a id="structespectre_1_1_runtime_config_1a0dbde3a8ad2fed884033fe0855153461"></a>

### `csi_target_pps`


```cpp
uint32_t espectre::RuntimeConfig::csi_target_pps {RUNTIME_CSI_TARGET_PPS_DEFAULT}
```

 

Target CSI sensing cadence, in packets per second.

  

This value is always positive and defines detector temporal slots as well as the target for managed traffic. [`csi_traffic_mode`](#structespectre_1_1_runtime_config_1a059d93605b13ae1192e9cceb390d755b) alone selects who supplies traffic. The detector coefficients are fitted at 100 pps; see `docs/ALGORITHMS.md` before moving far from it.

  

<a id="structespectre_1_1_runtime_config_1a69c0bba44b81eab12c24c106e2591119"></a>

### `traffic_generator_mode`


```cpp
RuntimeTrafficMode espectre::RuntimeConfig::traffic_generator_mode {RuntimeTrafficMode::PING}
```

 

Which packet the internal generator sends to solicit CSI.

   

<a id="structespectre_1_1_runtime_config_1a3724c06056cbaa57995ec053a955403f"></a>

### `traffic_generator_target_ip`


```cpp
std::string espectre::RuntimeConfig::traffic_generator_target_ip
```

 

Unicast IPv4 destination for internal IP traffic; empty uses the Wi-Fi gateway.

  

Ignored by `wifi_raw`.

  

<a id="structespectre_1_1_runtime_config_1a059d93605b13ae1192e9cceb390d755b"></a>

### `csi_traffic_mode`


```cpp
CsiTrafficMode espectre::RuntimeConfig::csi_traffic_mode {CsiTrafficMode::INTERNAL}
```

 

Where the CSI-bearing traffic comes from.

  

See [`csi_traffic_types.h`](#csi__traffic__types_8h).

  

<a id="structespectre_1_1_runtime_config_1a351c09d60c62894a66d78bbcff516ba4"></a>

### `csi_traffic_udp_port`


```cpp
uint16_t espectre::RuntimeConfig::csi_traffic_udp_port {RUNTIME_CSI_TRAFFIC_UDP_PORT_DEFAULT}
```

 

UDP port used by the external CSI traffic mode.

   

<a id="structespectre_1_1_runtime_config_1a030014458960bd11b3848bba7f770d8e"></a>

### `csi_traffic_multicast_group`


```cpp
std::string espectre::RuntimeConfig::csi_traffic_multicast_group {RUNTIME_CSI_TRAFFIC_MULTICAST_GROUP_DEFAULT}
```

 

IPv4 multicast group joined by the UDP listener in `external`.

  

Empty disables the IGMP join. Unicast to the device IP still works.

  

<a id="structespectre_1_1_runtime_config_1a9ed14bbc7a7bbef728b2db39fc484553"></a>

### `device_id`


```cpp
uint64_t espectre::RuntimeConfig::device_id {0U}
```

 

Stable device identity used by the ESPectre Protocol and CSI streaming.

  

Assign [`derive_runtime_device_id()`](#namespaceespectre_1a34031a60d78bbb6306047b3540b4f905) to use the SDK's stable pseudonym from the Wi-Fi MAC. Zero is an unresolved sentinel; the controller does not replace it automatically.

  

<a id="structespectre_1_1_runtime_config_1ac210376be06dd066fcf78547733ee8af"></a>

### `evaluation_interval_ms`


```cpp
uint32_t espectre::RuntimeConfig::evaluation_interval_ms {RUNTIME_EVALUATION_INTERVAL_MS_DEFAULT}
```

 

Detector evaluation cadence in milliseconds.

   

<a id="structespectre_1_1_runtime_config_1a9ffb875a52b525060dc7996787d6fd3a"></a>

### `motion_on_hits`


```cpp
uint8_t espectre::RuntimeConfig::motion_on_hits {RUNTIME_MOTION_ON_HITS_DEFAULT}
```

 

Consecutive above-threshold evaluations before reporting motion (1..20).

   

<a id="structespectre_1_1_runtime_config_1a53ebfb156a2125c61fa675788784c301"></a>

### `motion_off_hits`


```cpp
uint8_t espectre::RuntimeConfig::motion_off_hits {RUNTIME_MOTION_OFF_HITS_DEFAULT}
```

 

Consecutive below-threshold evaluations before clearing motion (1..20).

   

<a id="structespectre_1_1_runtime_config_1a6b833d1269bc157a791dc100241087b7"></a>

### `lowpass_enabled`


```cpp
bool espectre::RuntimeConfig::lowpass_enabled {RUNTIME_LOWPASS_ENABLED_DEFAULT}
```

 

Enable the low-pass filter on the turbulence stream.

  

Off by default.

  

<a id="structespectre_1_1_runtime_config_1aa6a480f526a935faef46ee91c286ee5d"></a>

### `lowpass_cutoff`


```cpp
float espectre::RuntimeConfig::lowpass_cutoff {RUNTIME_LOWPASS_CUTOFF_DEFAULT}
```

 

Low-pass cutoff in Hz (5.0..20.0).

  

Ignored unless [`lowpass_enabled`](#structespectre_1_1_runtime_config_1a6b833d1269bc157a791dc100241087b7).

  

<a id="structespectre_1_1_runtime_config_1a36be148ebec6f2e07240cbd1c39e1ccb"></a>

### `hampel_enabled`


```cpp
bool espectre::RuntimeConfig::hampel_enabled {RUNTIME_HAMPEL_ENABLED_DEFAULT}
```

 

Enable Hampel outlier rejection on the turbulence stream.

  

On by default.

  

<a id="structespectre_1_1_runtime_config_1a034ce1a3a20c5509049fff9ba5e76c54"></a>

### `hampel_window`


```cpp
uint8_t espectre::RuntimeConfig::hampel_window {RUNTIME_HAMPEL_WINDOW_DEFAULT}
```

 

Hampel window in samples (3..11).

  

Ignored unless [`hampel_enabled`](#structespectre_1_1_runtime_config_1a36be148ebec6f2e07240cbd1c39e1ccb).

  

<a id="structespectre_1_1_runtime_config_1a36d865a656d4cd1856c709a340d3c63b"></a>

### `hampel_threshold`


```cpp
float espectre::RuntimeConfig::hampel_threshold {RUNTIME_HAMPEL_THRESHOLD_DEFAULT}
```

 

Hampel MAD multiplier (1.0..10.0).

  

Ignored unless [`hampel_enabled`](#structespectre_1_1_runtime_config_1a36be148ebec6f2e07240cbd1c39e1ccb).

  


<a id="structespectre_1_1_runtime_diagnostics_sample"></a>

## espectre::RuntimeDiagnosticsSample



```cpp
#include <runtime/runtime_diagnostics.h>
```



```cpp
struct espectre::RuntimeDiagnosticsSample
```

 

Rate and link diagnostics derived from cumulative runtime counters.

  

Produced by the runtime-owned [`RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler). The rates are what the runtime's monotonic totals moved by between two periodic sensing updates, and every frontend reads the same latest sample.

 

A zero rate means the counter did not move over the interval, and the first sample after [`RuntimeDiagnosticsSampler::reset()`](#classespectre_1_1_runtime_diagnostics_sampler_1a255a7d6a981df30ffdce72d1b89495df) reports zero rates because it establishes the baseline. The link fields are carried through either way.

 

<a id="structespectre_1_1_runtime_diagnostics_sample_1a3ff1ff0161be346bff367985d0721824"></a>

### `traffic_tx_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::traffic_tx_pps {0.0f}
```

 

Traffic packets per second sent or observed by the active traffic source.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a43ac7ee8b3dfdf6f3274d4e81dafcd16"></a>

### `csi_callback_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_callback_pps {0.0f}
```

 

Raw CSI callbacks per second, before any capture-level validation.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a125500562a6bc3ad824cf696cae8c9a4"></a>

### `csi_accepted_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_accepted_pps {0.0f}
```

 

CSI packets per second accepted by capture validation.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a701ee4b43a9b5f7a09a2f75a717e51ca"></a>

### `csi_admitted_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_admitted_pps {0.0f}
```

 

CSI packets per second admitted to the detector's temporal grid.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a76312bc2c4556eaf7bfa17a577d38dc9"></a>

### `csi_filtered_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_filtered_pps {0.0f}
```

 

CSI packets per second rejected by capture-level validation.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1aabbfd5e2dba6cd01ee3063247f02e314"></a>

### `csi_hw_error_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_hw_error_pps {0.0f}
```

 

Hardware-quality rejections per second, with one reason per rejected callback.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a4ef885c63bffa884bea39ae6a52785af"></a>

### `csi_pending_frame_drop_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_pending_frame_drop_pps {0.0f}
```

 

Valid CSI callbacks per second dropped because the pending queue was full.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a3027d157b651e64d5b50e08b0a88357c"></a>

### `csi_missing_slots_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_missing_slots_pps {0.0f}
```

 

Missing detector slots per second.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1aba879cef28a0cc1d02aa752f3bb09819"></a>

### `csi_excess_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_excess_pps {0.0f}
```

 

Same-slot excess drops per second.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a205207163e1676ca349806e25ca91107"></a>

### `csi_stale_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_stale_pps {0.0f}
```

 

Stale temporal drops per second.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a4351f6e1c87593f9c38fd5ae30657141"></a>

### `csi_out_of_order_pps`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_out_of_order_pps {0.0f}
```

 

Out-of-order temporal drops per second.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1a7cecc77e01848e3f2978a5814ec1568a"></a>

### `csi_occupancy_ratio`


```cpp
float espectre::RuntimeDiagnosticsSample::csi_occupancy_ratio {0.0f}
```

 

Valid-slot occupancy of the active temporal detector window.

   

<a id="structespectre_1_1_runtime_diagnostics_sample_1abac2acdc8b1e74cbde558ef87578c5fe"></a>

### `wifi_rssi_dbm`


```cpp
int8_t espectre::RuntimeDiagnosticsSample::wifi_rssi_dbm {INT8_MIN}
```

 

RSSI of the current association.

  

`INT8_MIN` when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_sample_1a0dbd610d4f5bf12a6467446a19a98ecd"></a>

### `wifi_channel`


```cpp
uint8_t espectre::RuntimeDiagnosticsSample::wifi_channel {0U}
```

 

Primary channel of the current association.

  

Zero when unavailable.

  


<a id="classespectre_1_1_runtime_diagnostics_sampler"></a>

## espectre::RuntimeDiagnosticsSampler



```cpp
#include <runtime/runtime_diagnostics.h>
```



```cpp
class espectre::RuntimeDiagnosticsSampler
```

 

Converts cumulative diagnostics into rates over the interval between reads.

  

Call [`reset()`](#classespectre_1_1_runtime_diagnostics_sampler_1a255a7d6a981df30ffdce72d1b89495df) when the owning runtime starts. Counter resets are treated as a new epoch, so rearming a traffic source cannot underflow a rate.

 

```cpp
// once, when the runtime starts sensing:
sampler.reset(runtime.get_diagnostics(), now_ms);
// on the runtime's existing sensing heartbeat:
latest = sampler.sample(runtime.get_diagnostics(), now_ms);
```

 

**Par:** Threading

Not synchronized, and it holds the previous read. Sample it from the task that owns the runtime.

 

<a id="classespectre_1_1_runtime_diagnostics_sampler_1a255a7d6a981df30ffdce72d1b89495df"></a>

### `reset`


```cpp
void espectre::RuntimeDiagnosticsSampler::reset(const RuntimeDiagnosticsSnapshot &snapshot, uint32_t now_ms)
```

 

Establish the baseline the next [`sample()`](#classespectre_1_1_runtime_diagnostics_sampler_1aa63e9035ae799879686273cfab48e0bb) measures against.

  

**Parameters**

- `snapshot`: Current cumulative counters.
- `now_ms`: Monotonic frontend clock, in milliseconds.

  

<a id="classespectre_1_1_runtime_diagnostics_sampler_1aa63e9035ae799879686273cfab48e0bb"></a>

### `sample`


```cpp
RuntimeDiagnosticsSample espectre::RuntimeDiagnosticsSampler::sample(const RuntimeDiagnosticsSnapshot &snapshot, uint32_t now_ms)
```

 

Derive rates since the previous read and adopt this one as the baseline.

  

The caller owns the window. Shipped frontends invoke this from their existing periodic sensing update, so diagnostics do not add a timer.

 

**Parameters**

- `snapshot`: Current cumulative counters.
- `now_ms`: Monotonic frontend clock, in milliseconds.

 

**Returns:** Rates over the elapsed interval. The link fields are always carried through; the rates are zero when there is no baseline yet or no time has elapsed.

  


<a id="structespectre_1_1_runtime_diagnostics_snapshot"></a>

## espectre::RuntimeDiagnosticsSnapshot



```cpp
#include <runtime/runtime_snapshot.h>
```



```cpp
struct espectre::RuntimeDiagnosticsSnapshot
```

 

Low-frequency counters and radio state used by optional diagnostic surfaces.

  

This deliberately stays separate from [`RuntimeSnapshot`](#structespectre_1_1_runtime_snapshot): sensing snapshots travel through the hot callback path, while frontends query diagnostics when they already handle a periodic sensing update.

 

Counters are cumulative and monotonic within a session; pass them through [`RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler) to turn them into rates.

 

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ae3ae00b3f20c965b0a3d7b1d70801821"></a>

### `wifi_rssi_dbm`


```cpp
int8_t espectre::RuntimeDiagnosticsSnapshot::wifi_rssi_dbm {INT8_MIN}
```

 

RSSI of the current Wi-Fi association.

  

`INT8_MIN` when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1aa251f30afa6f35d3bcc7918fa55b8a41"></a>

### `wifi_channel`


```cpp
uint8_t espectre::RuntimeDiagnosticsSnapshot::wifi_channel {0U}
```

 

Primary channel of the current Wi-Fi association.

  

Zero when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a8f9876608e810741f431ae87ba3d3025"></a>

### `traffic_packets_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::traffic_packets_total {0U}
```

 

Traffic packets sent or observed by the active traffic source.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a61723fa700a8f90f9c2db4943a482549"></a>

### `csi_callbacks_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_callbacks_total {0U}
```

 

Raw invocations of the ESP-IDF CSI callback.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1acb33f769da690fd0bf21137f0225152c"></a>

### `csi_provenance_rejected_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_provenance_rejected_total {0U}
```

 

CSI callbacks rejected because their packet provenance did not match.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a32323d3d355e24f76ed339640c7f2f88"></a>

### `csi_accepted_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_accepted_total {0U}
```

 

CSI packets accepted by capture validation, before temporal admission.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1abbd1f7e1f152c4503bbbed12648234d0"></a>

### `csi_admitted_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_admitted_total {0U}
```

 

CSI packets admitted to the detector's temporal grid.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1aa612aa8f8818b804d548ee2464c41054"></a>

### `csi_filtered_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_filtered_total {0U}
```

 

CSI packets rejected by capture-level validation.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a4a695e75408553d3359a0bed201f9db5"></a>

### `csi_rx_error_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_rx_error_total {0U}
```

 

Packets rejected because the receiver reported an error.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a44a4e60a25b64e8d1a1bc60e904c259a"></a>

### `csi_rx_end_error_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_rx_end_error_total {0U}
```

 

Packets rejected because reception ended with an error (HE-capable chips).

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a1f71fd49a081cd3fc971505181fec6ff"></a>

### `csi_invalid_estimate_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_invalid_estimate_total {0U}
```

 

Packets rejected because the hardware CSI estimate was invalid (HE-capable chips).

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1acc3e0e041ee62464236d7ccc28e870f0"></a>

### `csi_invalid_first_word_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_invalid_first_word_total {0U}
```

 

Packets rejected because hardware-invalid source pairs affect live or unknown tones.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a4a3075e0d8966fb7009f0a499783a0e8"></a>

### `csi_sanitized_first_word_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_sanitized_first_word_total {0U}
```

 

Frames whose hardware-invalid guard pairs were zeroed without changing live tones.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ad9f8561a71712206067ee5c53673abf8"></a>

### `csi_pending_frame_drops_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_pending_frame_drops_total {0U}
```

 

Valid CSI callbacks dropped because the callback-to-runtime queue was full.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ab0866ea943033ffa115ac424801a511a"></a>

### `csi_missing_slots_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_missing_slots_total {0U}
```

 

Empty temporal detector slots observed before admitted packets.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a7931262c06a4e669a59fd7737191278b"></a>

### `csi_excess_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_excess_total {0U}
```

 

Valid packets dropped because their temporal slot was already occupied.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a26857bbd9e1d191375713cbd1b2dc1e7"></a>

### `csi_stale_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_stale_total {0U}
```

 

Packets rejected because processing began after the active window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1aa88fc78f8f97075e040964cfe11561d3"></a>

### `csi_out_of_order_total`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::csi_out_of_order_total {0U}
```

 

Packets rejected because their timestamp moved backwards.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a8e709f2f2d3fd971f4d6a01103b2a958"></a>

### `csi_occupancy_slots`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::csi_occupancy_slots {0U}
```

 

Valid slots in the current detector window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a0fe7fc2b5e0d866892d14dfd5baef1e6"></a>

### `csi_window_slots`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::csi_window_slots {0U}
```

 

Total slots in the configured detector window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a84b8113db117315f4a86104b33ad001b"></a>

### `csi_pending_frames`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::csi_pending_frames {0U}
```

 

Frames currently waiting in the callback-to-runtime queue.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ab10bdb925eb4b352392ffbc42b0127e5"></a>

### `csi_pending_frame_capacity`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::csi_pending_frame_capacity {0U}
```

 

Fixed capacity of the callback-to-runtime queue.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1acadb5df1f9041872855c0945817a66fa"></a>

### `free_memory_bytes`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::free_memory_bytes {0U}
```

 

Current free heap in bytes.

  

Zero when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a22f08dafbd1f814a61b3a3c079088f1a"></a>

### `minimum_free_memory_bytes`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::minimum_free_memory_bytes {0U}
```

 

Minimum free heap observed since boot, in bytes.

  

Zero when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a3ae566beed65c14d17f69736d81f8d5c"></a>

### `largest_free_memory_block_bytes`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::largest_free_memory_block_bytes {0U}
```

 

Largest currently allocatable heap block, in bytes.

  

Zero when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a8bd8754d3d410b89c0b9634d29675c60"></a>

### `cpu_frequency_mhz`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::cpu_frequency_mhz {0U}
```

 

Resolved CPU frequency in MHz.

  

Zero when unavailable.

  

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a05745d5bba9ab4f88d0d85fba5ffc997"></a>

### `performance_window_ready`


```cpp
bool espectre::RuntimeDiagnosticsSnapshot::performance_window_ready {false}
```

 

True after the first complete performance aggregation window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a173be948d15c7c65c13e0839b576f0d6"></a>

### `performance_window_duration_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::performance_window_duration_us {0U}
```

 

Duration of the latest complete performance window, in microseconds.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a21918899df41ce2f82f3aadad20b5064"></a>

### `runtime_load_percent`


```cpp
float espectre::RuntimeDiagnosticsSnapshot::runtime_load_percent {0.0f}
```

 

Share of the window spent inside the ESPectre runtime loop.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a2b8084036e7ae6c3b59da51a20380295"></a>

### `loop_samples`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::loop_samples {0U}
```

 

Runtime loop iterations measured in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a3f1bf11f4ce7f14c4085662ac0db1788"></a>

### `loop_average_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::loop_average_us {0U}
```

 

Mean runtime loop duration in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a2bc605713200b5be62c253759e4464fd"></a>

### `loop_maximum_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::loop_maximum_us {0U}
```

 

Maximum runtime loop duration in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1aeca58e56388bbc83888b6d28984daeef"></a>

### `detection_timing_supported`


```cpp
bool espectre::RuntimeDiagnosticsSnapshot::detection_timing_supported {false}
```

 

Whether this runtime executes a detector and reports its timing.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ac1f1a3f23686fe034cac009cdfd35497"></a>

### `detection_samples`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::detection_samples {0U}
```

 

Detector evaluations measured in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1af08d4d3ff91ae77d5b637327e425b5fc"></a>

### `detection_sum_us`


```cpp
uint64_t espectre::RuntimeDiagnosticsSnapshot::detection_sum_us {0U}
```

 

Total detector evaluation time in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1a2ba85f9468e53fc2ca7db86801893513"></a>

### `detection_average_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::detection_average_us {0U}
```

 

Mean detector evaluation time in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1abf02f7b7b1aab56203029d91cc29137b"></a>

### `detection_minimum_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::detection_minimum_us {0U}
```

 

Minimum detector evaluation time in the latest complete window.

   

<a id="structespectre_1_1_runtime_diagnostics_snapshot_1ada13c07bb64c71c4cf9b15c90c37d77a"></a>

### `detection_maximum_us`


```cpp
uint32_t espectre::RuntimeDiagnosticsSnapshot::detection_maximum_us {0U}
```

 

Maximum detector evaluation time in the latest complete window.

   


<a id="classespectre_1_1_runtime_direct_http_bridge"></a>

## espectre::RuntimeDirectHttpBridge



```cpp
#include <runtime/esp_idf/runtime_direct_http_bridge.h>
```



```cpp
class espectre::RuntimeDirectHttpBridge
```

 

Exposes the common runtime controls over the versioned Direct HTTP API.

  

Frontends retain ownership of their runtime and transport. The optional callback lets an adapter republish frontend-native entities after a Direct mutation, for example ESPHome number and select entities.

 

<a id="classespectre_1_1_runtime_direct_http_bridge_1a08b3b850fdc2a6fa96b6f77f00e381c6"></a>

### `ConfigChangedCallback`


```cpp
using espectre::RuntimeDirectHttpBridge::ConfigChangedCallback = std::function<void()>
```

   


<a id="classespectre_1_1_runtime_direct_http_bridge_1a11186d3fd85075cfa76082d3dcc2089f"></a>

### `setup`


```cpp
bool espectre::RuntimeDirectHttpBridge::setup(IDirectHttpService *service, RuntimeFrontendController *runtime, const RuntimeDirectHttpBridgeConfig &config, ConfigChangedCallback config_changed={})
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1a14f48cfe088fdc4d9e3b4983630d8840"></a>

### `loop`


```cpp
void espectre::RuntimeDirectHttpBridge::loop()
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1a3b7ed14517fe314ad124e7eaac7f2647"></a>

### `shutdown`


```cpp
void espectre::RuntimeDirectHttpBridge::shutdown()
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1a41168a884b23afcfaa6207b4232eaac4"></a>

### `running`


```cpp
bool espectre::RuntimeDirectHttpBridge::running() const
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1a3d62c7c02fe9edc2f9fdd446a6ff28ff"></a>

### `event_client_count`


```cpp
size_t espectre::RuntimeDirectHttpBridge::event_client_count() const
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1a2860a623e4969bcd4e6ab0a40162027c"></a>

### `publish_event`


```cpp
bool espectre::RuntimeDirectHttpBridge::publish_event(const char *event_name, const std::string &data_json, bool replaceable_telemetry=false)
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1ac737e2da4c867bcf341f3bfeb22d59bf"></a>

### `publish_motion`


```cpp
bool espectre::RuntimeDirectHttpBridge::publish_motion(const RuntimeSnapshot &snapshot)
```

   

<a id="classespectre_1_1_runtime_direct_http_bridge_1ad59141bad149054a36f26958a9d3c1d7"></a>

### `publish_changes`


```cpp
bool espectre::RuntimeDirectHttpBridge::publish_changes(FrontendCommandChange changes)
```

   


<a id="structespectre_1_1_runtime_direct_http_bridge_config"></a>

## espectre::RuntimeDirectHttpBridgeConfig



```cpp
#include <runtime/esp_idf/runtime_direct_http_bridge.h>
```



```cpp
struct espectre::RuntimeDirectHttpBridgeConfig
```

  

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a98a38f7328ca6e75524eaa76ae061b4c"></a>

### `frontend`


```cpp
std::string espectre::RuntimeDirectHttpBridgeConfig::frontend
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1aad0a4b9509731f7d97ddd668a73fc4a7"></a>

### `device_name`


```cpp
std::string espectre::RuntimeDirectHttpBridgeConfig::device_name
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a6d04303fb7d2db4b0f06c58cabf02a75"></a>

### `hostname`


```cpp
std::string espectre::RuntimeDirectHttpBridgeConfig::hostname
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1ac3bbaf6e0368a05bf57f6d51e6a199ac"></a>

### `firmware_version`


```cpp
std::string espectre::RuntimeDirectHttpBridgeConfig::firmware_version
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1ae9f04c562da67f6e9fd70129f7e70309"></a>

### `chip`


```cpp
std::string espectre::RuntimeDirectHttpBridgeConfig::chip
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1af7b33835649bf55581e73e0fc93df7ad"></a>

### `device_id`


```cpp
uint64_t espectre::RuntimeDirectHttpBridgeConfig::device_id {0U}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a0d722df897a745d3c48282f3a5badd7f"></a>

### `port`


```cpp
uint16_t espectre::RuntimeDirectHttpBridgeConfig::port {ESPECTRE_DIRECT_HTTP_PORT}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a16bfff616ea05aa8a9086a31aa8d8dc6"></a>

### `raw_csi`


```cpp
bool espectre::RuntimeDirectHttpBridgeConfig::raw_csi {false}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a357de25db9703b755cf566d95730092c"></a>

### `allow_missing_origin`


```cpp
bool espectre::RuntimeDirectHttpBridgeConfig::allow_missing_origin {false}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a157215245d7518fe4483f056a278f798"></a>

### `device_label_getter`


```cpp
std::function<std::string()> espectre::RuntimeDirectHttpBridgeConfig::device_label_getter
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1ab41b1bc76a6dc3eb78f6bcae2cc7c88e"></a>

### `device_label_setter`


```cpp
FrontendDeviceLabelCallback espectre::RuntimeDirectHttpBridgeConfig::device_label_setter
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a1de58ab64ec772200f6bf159a6b0bb67"></a>

### `wifi_snapshot_getter`


```cpp
std::function<DirectWifiSnapshot()> espectre::RuntimeDirectHttpBridgeConfig::wifi_snapshot_getter
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1ae284c51c72571be70a3a6d89aebf4c34"></a>

### `peer_discovery`


```cpp
IPeerDiscoveryService* espectre::RuntimeDirectHttpBridgeConfig::peer_discovery {nullptr}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1acab815a09347ea06d6f08d711c7cc284"></a>

### `diagnostics_sample_getter`


```cpp
std::function<const RuntimeDiagnosticsSample *()> espectre::RuntimeDirectHttpBridgeConfig::diagnostics_sample_getter
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a650302f6eeae5abd967d3ada89ff72fc"></a>

### `runtime_events`


```cpp
const RuntimeEventMailbox* espectre::RuntimeDirectHttpBridgeConfig::runtime_events {nullptr}
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a8930371a045d3abd60310248a304df6b"></a>

### `wifi_bssid_pin_setter`


```cpp
std::function<bool(const std::string &bssid, bool force, std::string *message)> espectre::RuntimeDirectHttpBridgeConfig::wifi_bssid_pin_setter
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1a8870d38f405961f6c2f95f7a2dd2317a"></a>

### `wifi_bssid_pin_preflight`


```cpp
std::function<bool(std::string *message)> espectre::RuntimeDirectHttpBridgeConfig::wifi_bssid_pin_preflight
```

   

<a id="structespectre_1_1_runtime_direct_http_bridge_config_1ab1411fd0f73a5d394dbfa1c3eb3cae34"></a>

### `loop_time_ms_getter`


```cpp
std::function<float()> espectre::RuntimeDirectHttpBridgeConfig::loop_time_ms_getter {}
```

 

Latest complete frontend loop duration in milliseconds; omitted callbacks yield null.

   


<a id="classespectre_1_1_runtime_event_mailbox"></a>

## espectre::RuntimeEventMailbox



```cpp
#include <runtime/runtime_event_mailbox.h>
```



```cpp
class espectre::RuntimeEventMailbox
```

 

Fixed-memory handoff from runtime listener callbacks to a frontend loop.

  

Motion-state changes retain FIFO ordering. If their bounded queue fills, posting keeps the newest state by discarding the oldest unconsumed state and reports the loss to the caller. Live telemetry is replaceable by design, so repeated posts coalesce to the newest snapshot.

 

All operations serialize their short value copies and are safe to call from different tasks. Drain the mailbox from one owning frontend task. This class is not intended for raw CSI callbacks or other ISR/driver contexts.

 

The mailbox never allocates and never invokes frontend code. The frontend remains responsible for publication, transport policy, and error handling.

 

<a id="classespectre_1_1_runtime_event_mailbox_1aa261f423c540d7b25a634e026893c9d2"></a>

### `kMotionStateCapacity`


```cpp
constexpr size_t espectre::RuntimeEventMailbox::kMotionStateCapacity = 4U
```

 

Maximum number of ordered motion-state changes retained.

   


<a id="classespectre_1_1_runtime_event_mailbox_1a210fe73397d29832b8437e54284b2b3a"></a>

### `RuntimeEventMailbox`


```cpp
espectre::RuntimeEventMailbox::RuntimeEventMailbox()=default
```

 

Construct an empty mailbox.

   

<a id="classespectre_1_1_runtime_event_mailbox_1acac8ca0bfe508013021819de3c513496"></a>

### `RuntimeEventMailbox`


```cpp
espectre::RuntimeEventMailbox::RuntimeEventMailbox(const RuntimeEventMailbox &)=delete
```

 

Mailboxes own synchronization state and cannot be copied.

   

<a id="classespectre_1_1_runtime_event_mailbox_1a27c244ca2820533e76bb5d84389deccc"></a>

### `operator=`


```cpp
RuntimeEventMailbox & espectre::RuntimeEventMailbox::operator=(const RuntimeEventMailbox &)=delete
```

 

Mailboxes own synchronization state and cannot be assigned.

   

<a id="classespectre_1_1_runtime_event_mailbox_1aa1e5bdcc75d829bd1bb7a0436d5f6f3c"></a>

### `post_motion_state`


```cpp
bool espectre::RuntimeEventMailbox::post_motion_state(const RuntimeSnapshot &snapshot)
```

 

Append a motion-state snapshot for ordered delivery.

  

When the queue is full, the oldest unconsumed snapshot is discarded so the eventual consumer still observes the newest state.

 

**Parameters**

- `snapshot`: Runtime state captured by `on_motion_state_changed()`.

 

**Returns:** `true` when every queued state was retained, or `false` when the oldest state had to be discarded.

  

<a id="classespectre_1_1_runtime_event_mailbox_1af2f3ac8fa1590beec480fbd97a5b1c5c"></a>

### `take_motion_state`


```cpp
bool espectre::RuntimeEventMailbox::take_motion_state(RuntimeSnapshot &snapshot)
```

 

Consume the oldest pending motion-state snapshot.

  

**Parameters**

- `snapshot`: Receives the snapshot when one is pending and remains unchanged otherwise.

 

**Returns:** `true` when a snapshot was consumed.

  

<a id="classespectre_1_1_runtime_event_mailbox_1add3140e9171121d8e525a71c74c8506d"></a>

### `post_live_telemetry`


```cpp
void espectre::RuntimeEventMailbox::post_live_telemetry(const RuntimeSnapshot &snapshot)
```

 

Store the newest replaceable live-telemetry snapshot.

  

**Parameters**

- `snapshot`: Runtime state with the callback's movement and threshold.

  

<a id="classespectre_1_1_runtime_event_mailbox_1a6f186ff4189a415c534c9192ecd8138f"></a>

### `take_live_telemetry`


```cpp
bool espectre::RuntimeEventMailbox::take_live_telemetry(RuntimeSnapshot &snapshot)
```

 

Consume the newest pending live-telemetry snapshot.

  

**Parameters**

- `snapshot`: Receives the snapshot when one is pending and remains unchanged otherwise.

 

**Returns:** `true` when a snapshot was consumed.

  

<a id="classespectre_1_1_runtime_event_mailbox_1aa70fbc51557b6a20ff80885a75b02fa8"></a>

### `post_threshold`


```cpp
void espectre::RuntimeEventMailbox::post_threshold(float threshold)
```

 

Store the newest replaceable threshold update.

   

<a id="classespectre_1_1_runtime_event_mailbox_1a6287a832d6ca1af858b56f1587ffea90"></a>

### `take_threshold`


```cpp
bool espectre::RuntimeEventMailbox::take_threshold(float &threshold)
```

 

Consume the newest pending threshold update.

   

<a id="classespectre_1_1_runtime_event_mailbox_1ad9a7a83373f51ddca801cf66653ab72b"></a>

### `motion_state_drops_total`


```cpp
uint32_t espectre::RuntimeEventMailbox::motion_state_drops_total() const
```

 

Cumulative ordered motion events discarded since construction.

   

<a id="classespectre_1_1_runtime_event_mailbox_1af50f6976e3f6cf006e62ea4863207d7f"></a>

### `clear`


```cpp
void espectre::RuntimeEventMailbox::clear()
```

 

Discard every unconsumed runtime event.

   


<a id="classespectre_1_1_runtime_frontend_controller"></a>

## espectre::RuntimeFrontendController



```cpp
#include <runtime/esp_idf/runtime_frontend_controller.h>
```



```cpp
class espectre::RuntimeFrontendController : private espectre::IRuntimeListener
```

 

The recommended entry point for firmware embedding ESPectre.

  

It owns the sensing runtime, caches the latest snapshot and discovered capabilities, and validates control calls before they reach the backend.

 

```cpp
class ProductFrontend : public espectre::IRuntimeListener {
 public:
  bool setup() {
    espectre::RuntimeConfig config;
    config.detection_algorithm = espectre::DetectionAlgorithm::LIGHTWEIGHT;
    runtime_.set_config(config);
    return runtime_.setup(this);
  }

  void loop() { runtime_.loop(); }

  void on_motion_state_changed(const espectre::RuntimeSnapshot &snapshot) override {
    if (snapshot.ready_to_publish) publish(snapshot.motion_state);
  }

 private:
  espectre::RuntimeFrontendController runtime_;
};
```

 

**Par:** Lifecycle

[`set_config()`](#classespectre_1_1_runtime_frontend_controller_1a6bc5d2dea03c406e822c0fc917e54840) -&gt; `setup(listener)` -&gt; [`loop()`](#classespectre_1_1_runtime_frontend_controller_1aa66c6b1a1a453f9ef9b4dfd27768c6f1) repeatedly -&gt; [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215). The controller is reusable after [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215): configuration survives, and [`set_config()`](#classespectre_1_1_runtime_frontend_controller_1a6bc5d2dea03c406e822c0fc917e54840) becomes effective again.

 

**Par:** Threading

Carries no internal locking. Run [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153), [`loop()`](#classespectre_1_1_runtime_frontend_controller_1aa66c6b1a1a453f9ef9b4dfd27768c6f1), and [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215) on one task. See [`espectre_sdk.h`](#espectre__sdk_8h) for the full contract, including where listener callbacks land and how to handle controls driven from a transport callback.

 

**Par:** Control calls before setup

The setters work before [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153) and simply update the pending configuration, so a frontend can accept provisioning commands during boot without special-casing the ordering.

 [`espectre::IRuntimeListener`](#classespectre_1_1_i_runtime_listener)



<a id="classespectre_1_1_runtime_frontend_controller_1ac4cb2c38604472e5a91773d63e4f86e9"></a>

### `~RuntimeFrontendController`


```cpp
espectre::RuntimeFrontendController::~RuntimeFrontendController() override
```

 

Shut the runtime down on scope exit.

  

Explicit [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215) remains recommended.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a6bc5d2dea03c406e822c0fc917e54840"></a>

### `set_config`


```cpp
void espectre::RuntimeFrontendController::set_config(const RuntimeConfig &config)
```

 

Stage the configuration used by the next [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153).

  

Ignored once setup has started, so reconfiguring a running runtime means [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215) first, or the `set_*_runtime()` methods for the fields that support live changes.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a0c93736a1d6dc29e8bd4bfb03bffa25a"></a>

### `config`


```cpp
RuntimeConfig & espectre::RuntimeFrontendController::config()
```

 

Mutable access to the staged configuration.

  

Provided so a frontend can adjust individual fields before [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153) without rebuilding the whole struct. After a successful setup it reflects the backend's effective configuration, including persisted overrides. Writing to it after setup stages the next setup only; live controls continue to validate against the active configuration.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a835cf53e8614e7b7dac7b2b5f5ac31e3"></a>

### `config`


```cpp
const RuntimeConfig & espectre::RuntimeFrontendController::config() const
```

 

Read-only view of the staged or last effective configuration.

   

<a id="classespectre_1_1_runtime_frontend_controller_1abe9fba2fd299106438728026bc018888"></a>

### `snapshot`


```cpp
const RuntimeSnapshot & espectre::RuntimeFrontendController::snapshot() const
```

 

Latest known snapshot, without querying the backend.

  

Refreshed automatically at [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153), by control calls, and before every listener callback is forwarded to your frontend. Use the cached snapshot for on-demand reads such as answering a status query; use the listener callbacks to react to change.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a621291d366aa0d0f47748724927c8a75"></a>

### `diagnostics`


```cpp
RuntimeDiagnosticsSnapshot espectre::RuntimeFrontendController::diagnostics() const
```

 

Read backend counters without touching the cached sensing snapshot.

  

Unlike [`snapshot()`](#classespectre_1_1_runtime_frontend_controller_1abe9fba2fd299106438728026bc018888), this queries the backend on every call. Invoke it from an existing periodic sensing callback, not from the hot loop. Returns a zeroed snapshot before [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153).

  

<a id="classespectre_1_1_runtime_frontend_controller_1a9fe6055dcea10b65dc4e07a5855d38a9"></a>

### `diagnostics_sample`


```cpp
const RuntimeDiagnosticsSample * espectre::RuntimeFrontendController::diagnostics_sample() const
```

 

Latest runtime-owned rate sample, or `nullptr` before setup.

   

<a id="classespectre_1_1_runtime_frontend_controller_1a7dc5dd34287ce0af14346d436e15e8ef"></a>

### `capabilities`


```cpp
const RuntimeCapabilities & espectre::RuntimeFrontendController::capabilities() const
```

 

What the active backend supports.

  

Meaningful only after [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153).

 

Gate your product surface on it rather than hardcoding: the controller already refuses capability-gated calls, and this is how you avoid exposing a control the runtime will reject.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a93a43bbf7657e0681fd870504b2da3bf"></a>

### `is_setup_complete`


```cpp
bool espectre::RuntimeFrontendController::is_setup_complete() const
```

 

True between a successful [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153) and the next [`shutdown()`](#classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215).

   

<a id="classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153"></a>

### `setup`


```cpp
bool espectre::RuntimeFrontendController::setup(IRuntimeListener *listener)
```

 

Create the backend, apply the configuration, and start sensing.

  

Calling it twice is a no-op that returns true.

 

**Parameters**

- `listener`: Event sink, or `nullptr` for none. Not owned; it must outlive the controller.

 

**Returns:** false when the backend cannot start or its bounded working storage cannot be allocated. On failure the backend is dropped and the controller stays un-setup, so it is safe to fix the config and retry.

  

<a id="classespectre_1_1_runtime_frontend_controller_1aa66c6b1a1a453f9ef9b4dfd27768c6f1"></a>

### `loop`


```cpp
void espectre::RuntimeFrontendController::loop()
```

 

Advance runtime work and deliver pending listener callbacks.

  

Call it continuously from your loop task. Safe, and a no-op, before setup.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a676b16e92ff6025de8fdc400d2344215"></a>

### `shutdown`


```cpp
void espectre::RuntimeFrontendController::shutdown()
```

 

Stop sensing and release the backend.

  

Safe before setup and to repeat.

  

<a id="classespectre_1_1_runtime_frontend_controller_1abcf381fd02a5b47f239f61680f79a773"></a>

### `set_services_armed`


```cpp
void espectre::RuntimeFrontendController::set_services_armed(bool armed)
```

 

Gate runtime-owned services without tearing the runtime down.

  

Sticky: the value is remembered and reapplied to the backend created by a later [`setup()`](#classespectre_1_1_runtime_frontend_controller_1a4e448eb22ec37407f04ca7de09ee1153). Matter uses it to stay silent until commissioning. Frontends use it to pause CSI without dropping Wi-Fi. During raw collection the requested value is staged and applied when collection stops, because changing sensing services cannot interrupt the capture callback in place.

  

<a id="classespectre_1_1_runtime_frontend_controller_1ae334cb483e672900ac987aba31d073f0"></a>

### `set_live_telemetry_enabled`


```cpp
void espectre::RuntimeFrontendController::set_live_telemetry_enabled(bool enabled)
```

 

Enable or suppress [`IRuntimeListener::on_live_telemetry()`](#classespectre_1_1_i_runtime_listener_1a2473b19c1324d186b11ba596000acde9).

  

Also sticky.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a72ce3c88bf076a26033c2ff796e91db7"></a>

### `services_armed`


```cpp
bool espectre::RuntimeFrontendController::services_armed() const
```

 

Current armed state, including before setup.

   

<a id="classespectre_1_1_runtime_frontend_controller_1aa34bdedcf70f7a13dc90c91929123eec"></a>

### `quiesce`


```cpp
void espectre::RuntimeFrontendController::quiesce()
```

 

Temporarily quiet the runtime without releasing its backend or configuration.

  

Disables live telemetry and sensing services, and stops active raw collection. Restore the desired service and telemetry gates explicitly when resuming.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a0e1584a609e9e8f8c78cf320c0904f1a"></a>

### `set_threshold_runtime`


```cpp
bool espectre::RuntimeFrontendController::set_threshold_runtime(float threshold)
```

 

Set the motion threshold, validating it against the active detector.

  

**Parameters**

- `threshold`: Value on the 0..1 metric scale.

 

**Returns:** false when out of range, or when the backend refuses it. Before setup the value is staged and returns true.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a446aabaac2af39aeb416bd73959a858c"></a>

### `set_motion_hits_runtime`


```cpp
bool espectre::RuntimeFrontendController::set_motion_hits_runtime(uint8_t motion_on_hits, uint8_t motion_off_hits)
```

 

Set the hit filter.

  

**Parameters**

- `motion_on_hits`: Consecutive above-threshold evaluations to report motion (1..20). Higher trades latency for fewer false positives.
- `motion_off_hits`: Consecutive below-threshold evaluations to clear it (1..20).

 

**Returns:** false when either value is out of range, or when the runtime is up and does not advertise [`RuntimeCapabilities::supports_runtime_motion_hits_updates`](#structespectre_1_1_runtime_capabilities_1a84d3b5bb447e02b9026bdb81f69db236).

  

<a id="classespectre_1_1_runtime_frontend_controller_1a30e9537d99e0fff3604dc43b23de808a"></a>

### `set_csi_traffic_mode_runtime`


```cpp
bool espectre::RuntimeFrontendController::set_csi_traffic_mode_runtime(CsiTrafficMode mode)
```

 

Change the live CSI traffic ownership mode.

  

**Returns:** false when the mode is invalid, or when the runtime is up and does not advertise [`RuntimeCapabilities::supports_traffic_control`](#structespectre_1_1_runtime_capabilities_1a9cb79d6a0f22efbcfecabc4d4747fedb).

  

<a id="classespectre_1_1_runtime_frontend_controller_1a08ebe4b8ffb775326387f0deb078f64e"></a>

### `set_traffic_generator_mode_runtime`


```cpp
bool espectre::RuntimeFrontendController::set_traffic_generator_mode_runtime(RuntimeTrafficMode mode)
```

 

Change the live internal traffic generator packet type.

  

**Returns:** false when the mode is invalid, or when the runtime is up and does not advertise [`RuntimeCapabilities::supports_traffic_control`](#structespectre_1_1_runtime_capabilities_1a9cb79d6a0f22efbcfecabc4d4747fedb).

  

<a id="classespectre_1_1_runtime_frontend_controller_1afd9245f0f4e16527465f66a3ac2eeabb"></a>

### `set_detection_algorithm_runtime`


```cpp
bool espectre::RuntimeFrontendController::set_detection_algorithm_runtime(DetectionAlgorithm algorithm)
```

 

Switch detector while running.

  

The threshold follows the detector: the controller adopts the new detector's threshold rather than carrying the old value across scales.

 

**Returns:** false for an unknown algorithm, or when the runtime is up and does not advertise [`RuntimeCapabilities::supports_runtime_detector_selection`](#structespectre_1_1_runtime_capabilities_1a8a74863f469d46c8a8441ef4e58c6b66).

  

<a id="classespectre_1_1_runtime_frontend_controller_1a2607dfb2e9eb34c51fe780e4d036548a"></a>

### `trigger_recalibration`


```cpp
bool espectre::RuntimeFrontendController::trigger_recalibration()
```

 

Restart startup calibration.

  

**Returns:** false before setup, or when the backend does not advertise [`RuntimeCapabilities::supports_manual_recalibration`](#structespectre_1_1_runtime_capabilities_1a1457a33557663be153d4472ac9192b20). Success only means calibration started; the outcome arrives through [`IRuntimeListener::on_calibration_finished()`](#classespectre_1_1_i_runtime_listener_1a27f8430a4a3b5b5dc6323765a2155e74).

  

<a id="classespectre_1_1_runtime_frontend_controller_1a4cdb8ac518bf507346f83b88cec6009e"></a>

### `is_calibrating`


```cpp
bool espectre::RuntimeFrontendController::is_calibrating() const
```

 

True while the backend is calibrating.

  

False before setup.

  

<a id="classespectre_1_1_runtime_frontend_controller_1a471ae93254ac292e6808dd04bddb4277"></a>

### `start_raw_collection`


```cpp
bool espectre::RuntimeFrontendController::start_raw_collection(raw_csi_packet_callback_t callback, void *context)
```

 

Enter transient raw collection through the active sensing backend.

  

The callback runs synchronously in the Wi-Fi CSI capture context, not from [`loop()`](#classespectre_1_1_runtime_frontend_controller_1aa66c6b1a1a453f9ef9b4dfd27768c6f1). It must remain bounded, non-blocking, and allocation-free. Copy any bytes needed after the callback returns; the packet view and its CSI buffer expire with the call. See [`raw_csi_packet_callback_t`](#namespaceespectre_1a7b0352147eec65c1f73a9d8714c4596d) for the return convention.

 

**Parameters**

- `callback`: Capture-context packet consumer. Must not be `nullptr`.
- `context`: Opaque caller-owned value passed to every callback. The caller must keep it valid until collection stops.

 

**Returns:** false before setup, without raw-CSI capability, with no Wi-Fi link, or when another transient operation is active.

  

<a id="classespectre_1_1_runtime_frontend_controller_1afe421ca5c348fe22cfa49461a24ecca0"></a>

### `stop_raw_collection`


```cpp
bool espectre::RuntimeFrontendController::stop_raw_collection(RawCsiStopReason reason=RawCsiStopReason::REQUESTED)
```

 

Leave transient raw collection and restore the prior armed state.

   

<a id="classespectre_1_1_runtime_frontend_controller_1ab81dbd7ee21318fd03015731064dc2df"></a>

### `operation_state`


```cpp
RuntimeOperationState espectre::RuntimeFrontendController::operation_state() const
```

 

Current transient backend operation.

   


<a id="structespectre_1_1_runtime_snapshot"></a>

## espectre::RuntimeSnapshot



```cpp
#include <runtime/runtime_snapshot.h>
```



```cpp
struct espectre::RuntimeSnapshot
```

 

A consistent view of the sensing state at one instant.

  

Passed to every [`IRuntimeListener`](#classespectre_1_1_i_runtime_listener) callback and returned by [`RuntimeFrontendController::snapshot()`](#classespectre_1_1_runtime_frontend_controller_1abe9fba2fd299106438728026bc018888). It is a plain value type: copy it freely, and copy it if you need it past the callback that delivered it.

 

Read [`ready_to_publish`](#structespectre_1_1_runtime_snapshot_1a3e917a2d24bbe00e55416b9ddf3bffcd) before anything else. The runtime keeps emitting snapshots while it calibrates, and [`motion_state`](#structespectre_1_1_runtime_snapshot_1a39dbe81761f12a45799c1845d8d8f8af) is not meaningful until that flag is true.

 

<a id="structespectre_1_1_runtime_snapshot_1a39dbe81761f12a45799c1845d8d8f8af"></a>

### `motion_state`


```cpp
MotionState espectre::RuntimeSnapshot::motion_state {MotionState::IDLE}
```

 

Debounced motion state, after the `motion_on_hits` / `motion_off_hits` filter.

   

<a id="structespectre_1_1_runtime_snapshot_1a6844aeb15178c5088d4564c5719361c7"></a>

### `movement_metric`


```cpp
float espectre::RuntimeSnapshot::movement_metric {0.0f}
```

 

Current motion metric, on a 0..1 probability scale for both detectors.

  

Comparable to [`threshold`](#structespectre_1_1_runtime_snapshot_1ad26aab6b3715a69403a257668c6699c3), but not comparable across detectors: Lightweight and ML produce the number differently even though the scale matches.

  

<a id="structespectre_1_1_runtime_snapshot_1ad26aab6b3715a69403a257668c6699c3"></a>

### `threshold`


```cpp
float espectre::RuntimeSnapshot::threshold {RUNTIME_SEGMENTATION_THRESHOLD_DEFAULT}
```

 

Threshold [`movement_metric`](#structespectre_1_1_runtime_snapshot_1a6844aeb15178c5088d4564c5719361c7) is compared against, on the same scale.

   

<a id="structespectre_1_1_runtime_snapshot_1a60ac8110de78ba7af0de788667e3702b"></a>

### `link_rssi_dbm`


```cpp
int8_t espectre::RuntimeSnapshot::link_rssi_dbm {INT8_MIN}
```

 

RSSI of the packets behind this metric.

  

`INT8_MIN` when unknown.

  

<a id="structespectre_1_1_runtime_snapshot_1a3b92bf25fed1f8f66d22ead1af2b7585"></a>

### `link_channel`


```cpp
uint8_t espectre::RuntimeSnapshot::link_channel {0}
```

 

Wi-Fi channel those packets arrived on.

  

Zero when unknown.

  

<a id="structespectre_1_1_runtime_snapshot_1a5d52ce9114fd4a374f93d26f6d6a4ab6"></a>

### `csi_capture_profile`


```cpp
CsiCaptureProfile espectre::RuntimeSnapshot::csi_capture_profile {CsiCaptureProfile::HT20}
```

 

Automatically selected CSI training-field and 20 MHz PHY profile.

   

<a id="structespectre_1_1_runtime_snapshot_1a83dbe442c55df68823a88b7270f3e5ab"></a>

### `calibrating`


```cpp
bool espectre::RuntimeSnapshot::calibrating {false}
```

 

Startup calibration is running; detection results are not valid yet.

   

<a id="structespectre_1_1_runtime_snapshot_1a334eddad66b0f849390574e3fef45400"></a>

### `calibration_packets`


```cpp
uint32_t espectre::RuntimeSnapshot::calibration_packets {0}
```

 

Packets observed by the current Lightweight startup calibrator.

  

Zero when calibration is not running. Lightweight can finish early once motion evidence is accepted, so this may stay below [`calibration_target_packets`](#structespectre_1_1_runtime_snapshot_1a6c8c6bffd0f2903d6dd8b0dd656d30ee).

  

<a id="structespectre_1_1_runtime_snapshot_1a6c8c6bffd0f2903d6dd8b0dd656d30ee"></a>

### `calibration_target_packets`


```cpp
uint16_t espectre::RuntimeSnapshot::calibration_target_packets {0}
```

 

Packet budget for the current Lightweight startup calibrator.

  

Zero when calibration is not running. `csi:`/`miss:` on the status heartbeat are last-second pipeline rates, not remaining calibration work.

  

<a id="structespectre_1_1_runtime_snapshot_1a3e917a2d24bbe00e55416b9ddf3bffcd"></a>

### `ready_to_publish`


```cpp
bool espectre::RuntimeSnapshot::ready_to_publish {false}
```

 

The runtime is calibrated, linked, and its output is safe to act on.

  

Gate every user-visible publication on this. It goes false again when the Wi-Fi link drops.

  

<a id="structespectre_1_1_runtime_snapshot_1a347d4e5da325362a17fa2d227fe3b900"></a>

### `startup_threshold`


```cpp
float espectre::RuntimeSnapshot::startup_threshold {0.0f}
```

 

Threshold startup calibration settled on.

  

Zero before it completes.

  

<a id="structespectre_1_1_runtime_snapshot_1a8839c547761d0f0f42121d48f48e34ee"></a>

### `detector_name`


```cpp
const char* espectre::RuntimeSnapshot::detector_name {"unknown"}
```

 

Active detector label: `"lightweight"` or `"high_accuracy"`.

  

Always a static string literal, so it stays valid for the process, but the pointer changes when the detector changes. [`parse_detection_algorithm()`](#namespaceespectre_1a58cce43945e826bdfe8db0e85cd5732c) turns it back into a [`DetectionAlgorithm`](#namespaceespectre_1ae6098340c58c0355e67beaa092880c6b). Note these are the protocol names, not [`BaseDetector::get_name()`](#classespectre_1_1_base_detector_1af1a3b2c9adb5ad7b550acfd7230a1503), which is capitalized for logs.

  

<a id="structespectre_1_1_runtime_snapshot_1aa1da2a1cf1d740fce18dcc1892b9aac8"></a>

### `subcarrier_source`


```cpp
RuntimeSubcarrierSource espectre::RuntimeSnapshot::subcarrier_source {RuntimeSubcarrierSource::FIXED_DEFAULT}
```

 

How [`fixed_subcarriers`](#structespectre_1_1_runtime_snapshot_1af07f47f60934759ebb5b1ef20fa0e97e) was chosen.

   

<a id="structespectre_1_1_runtime_snapshot_1af07f47f60934759ebb5b1ef20fa0e97e"></a>

### `fixed_subcarriers`


```cpp
SelectedSubcarriers espectre::RuntimeSnapshot::fixed_subcarriers {make_default_subcarriers()}
```

 

Subcarrier indices the detector is measuring on.

   


<a id="structespectre_1_1_standalone_wifi_access_point"></a>

## espectre::StandaloneWifiAccessPoint



```cpp
#include <runtime/esp_idf/standalone_wifi_service.h>
```



```cpp
struct espectre::StandaloneWifiAccessPoint
```

  

<a id="structespectre_1_1_standalone_wifi_access_point_1a4e5b5f856bdc024db112112b3278ef5d"></a>

### `ssid`


```cpp
std::string espectre::StandaloneWifiAccessPoint::ssid
```

   

<a id="structespectre_1_1_standalone_wifi_access_point_1a74bdab16629ec51c89eb5ca38affe56b"></a>

### `bssid`


```cpp
std::string espectre::StandaloneWifiAccessPoint::bssid
```

   

<a id="structespectre_1_1_standalone_wifi_access_point_1a524b7b539a7ad9cb317565f80d956536"></a>

### `rssi_dbm`


```cpp
int8_t espectre::StandaloneWifiAccessPoint::rssi_dbm {0}
```

   

<a id="structespectre_1_1_standalone_wifi_access_point_1a2ea237c462588011a59460cc6da2bfb9"></a>

### `channel`


```cpp
uint8_t espectre::StandaloneWifiAccessPoint::channel {0U}
```

   


<a id="structespectre_1_1_standalone_wifi_config"></a>

## espectre::StandaloneWifiConfig



```cpp
#include <runtime/esp_idf/standalone_wifi_service.h>
```



```cpp
struct espectre::StandaloneWifiConfig
```

  

<a id="structespectre_1_1_standalone_wifi_config_1a49bc4d2503cf2b54dc855c65e99ffd32"></a>

### `ssid`


```cpp
const char* espectre::StandaloneWifiConfig::ssid {""}
```

 

Borrowed, null-terminated credentials.

  

Keep them alive until shutdown or replacement.

  

<a id="structespectre_1_1_standalone_wifi_config_1a957f816303c0875d685350c4d20e8604"></a>

### `password`


```cpp
const char* espectre::StandaloneWifiConfig::password {""}
```

   

<a id="structespectre_1_1_standalone_wifi_config_1a66f2ee63c5333f92f34868c8b05bebac"></a>

### `bssid`


```cpp
const char* espectre::StandaloneWifiConfig::bssid {""}
```

   

<a id="structespectre_1_1_standalone_wifi_config_1a89507eb952f0bdbc814370e7d4735914"></a>

### `channel`


```cpp
uint8_t espectre::StandaloneWifiConfig::channel {0U}
```

   

<a id="structespectre_1_1_standalone_wifi_config_1a0dc87d4cf1fc77af1596e504cf0a1153"></a>

### `max_retry`


```cpp
int espectre::StandaloneWifiConfig::max_retry {8}
```

 

Immediate retries per burst; exhausted bursts restart after 30 seconds.

  

Zero skips immediate retries.

  

<a id="structespectre_1_1_standalone_wifi_config_1a1fa7c525d96db4d9729b0bc3be689ce2"></a>

### `manage_csi_lifecycle`


```cpp
bool espectre::StandaloneWifiConfig::manage_csi_lifecycle {false}
```

   

<a id="structespectre_1_1_standalone_wifi_config_1acefebff0c192715fe326af1e85878f66"></a>

### `band_policy`


```cpp
WifiBandPolicy espectre::StandaloneWifiConfig::band_policy {WifiBandPolicy::BAND_2G}
```

   


<a id="structespectre_1_1_standalone_wifi_info"></a>

## espectre::StandaloneWifiInfo



```cpp
#include <runtime/esp_idf/standalone_wifi_service.h>
```



```cpp
struct espectre::StandaloneWifiInfo
```

  

<a id="structespectre_1_1_standalone_wifi_info_1a7da10e8f5c15eee10602ee65e0b1fb4e"></a>

### `connected`


```cpp
bool espectre::StandaloneWifiInfo::connected {false}
```

   

<a id="structespectre_1_1_standalone_wifi_info_1ab82b00cba6e171807a274106a6129a17"></a>

### `ip_address`


```cpp
char espectre::StandaloneWifiInfo::ip_address[16][16] {}
```

   

<a id="structespectre_1_1_standalone_wifi_info_1ae54e242d978be13305357da7cdabfd77"></a>

### `mac_address`


```cpp
char espectre::StandaloneWifiInfo::mac_address[18][18] {}
```

   

<a id="structespectre_1_1_standalone_wifi_info_1a57fbee42754f9a27fac1a8f8e236f25e"></a>

### `channel`


```cpp
uint8_t espectre::StandaloneWifiInfo::channel {0U}
```

   


<a id="classespectre_1_1_standalone_wifi_service"></a>

## espectre::StandaloneWifiService



```cpp
#include <runtime/esp_idf/standalone_wifi_service.h>
```



```cpp
class espectre::StandaloneWifiService
```

  


<a id="classespectre_1_1_standalone_wifi_service_1aef1b01da7ccaa70fa30c5a0622a8322f"></a>

### `~StandaloneWifiService`


```cpp
espectre::StandaloneWifiService::~StandaloneWifiService()
```

 

Release the station driver, netif, and registered handlers.

   

<a id="classespectre_1_1_standalone_wifi_service_1af6031ac873d13c5c31203be7a7b24db4"></a>

### `setup`


```cpp
esp_err_t espectre::StandaloneWifiService::setup(const StandaloneWifiConfig &config, standalone_wifi_callback_t connected_cb={}, standalone_wifi_callback_t disconnected_cb={})
```

 

Own a new station driver and netif; the application must not already own them.

  

Requires initialized NVS. The default event loop is created if needed and remains available after shutdown. Credentials are borrowed; SSIDs up to 32 bytes and passwords up to 64 bytes are preserved without truncation. Failure releases acquired resources so setup can be retried. Calling setup while active returns ESP\_ERR\_INVALID\_STATE. Use one owner task for all methods; callbacks run from [loop()](#classespectre_1_1_standalone_wifi_service_1ad1e165e7f0eb286a2c1b68b573cee60c).

  

<a id="classespectre_1_1_standalone_wifi_service_1a533d0f1dec909d9ce1580c3d23395d07"></a>

### `start`


```cpp
esp_err_t espectre::StandaloneWifiService::start()
```

   

<a id="classespectre_1_1_standalone_wifi_service_1ab8f6a62aafef564c0f4cd1ac1686ce4d"></a>

### `update_station_config`


```cpp
esp_err_t espectre::StandaloneWifiService::update_station_config(const StandaloneWifiConfig &config)
```

   

<a id="classespectre_1_1_standalone_wifi_service_1a69941cd23b980c89c46985b87fddbbb1"></a>

### `request_scan`


```cpp
esp_err_t espectre::StandaloneWifiService::request_scan(standalone_wifi_scan_callback_t callback)
```

 

Scan every allowed channel for the configured SSID and report its bounded snapshot from [loop()](#classespectre_1_1_standalone_wifi_service_1ad1e165e7f0eb286a2c1b68b573cee60c).

   

<a id="classespectre_1_1_standalone_wifi_service_1ad1e165e7f0eb286a2c1b68b573cee60c"></a>

### `loop`


```cpp
void espectre::StandaloneWifiService::loop()
```

   

<a id="classespectre_1_1_standalone_wifi_service_1a72c20691db34234a5984ac316b304141"></a>

### `get_info`


```cpp
bool espectre::StandaloneWifiService::get_info(StandaloneWifiInfo *info) const
```

   

<a id="classespectre_1_1_standalone_wifi_service_1a1d8ca8218dc20f1007034de43983693d"></a>

### `shutdown`


```cpp
void espectre::StandaloneWifiService::shutdown()
```

 

Stop and release owned Wi-Fi resources.

  

Safe to repeat; setup can be called again.

  


<a id="structespectre_1_1_stored_wifi_config"></a>

## espectre::StoredWifiConfig



```cpp
#include <runtime/esp_idf/device_config_store.h>
```



```cpp
struct espectre::StoredWifiConfig
```

  

<a id="structespectre_1_1_stored_wifi_config_1a0962ca8aab4664861378f9a32e7bfbd8"></a>

### `ssid`


```cpp
std::string espectre::StoredWifiConfig::ssid
```

   

<a id="structespectre_1_1_stored_wifi_config_1a526e922f19f013af34d8340b7593bd4a"></a>

### `password`


```cpp
std::string espectre::StoredWifiConfig::password
```

   

<a id="structespectre_1_1_stored_wifi_config_1a6916305746a8f7b1a6583a48dc68da1a"></a>

### `bssid`


```cpp
std::string espectre::StoredWifiConfig::bssid
```

   

<a id="structespectre_1_1_stored_wifi_config_1a6b11dd58df8efc4cf26dd01d1484734a"></a>

### `channel`


```cpp
uint8_t espectre::StoredWifiConfig::channel {0U}
```

   

<a id="structespectre_1_1_stored_wifi_config_1a59c1d0e8d1a9a1029eec2de177568353"></a>

### `band_policy`


```cpp
WifiBandPolicy espectre::StoredWifiConfig::band_policy {WifiBandPolicy::BAND_2G}
```

   

<a id="structespectre_1_1_stored_wifi_config_1a936af3c1785f5eed84182c66457a3ee9"></a>

### `has_saved_band_policy`


```cpp
bool espectre::StoredWifiConfig::has_saved_band_policy {false}
```

   

<a id="structespectre_1_1_stored_wifi_config_1af2972a09f2650d2f0dc172e6990bb1d4"></a>

### `has_saved_config`


```cpp
bool espectre::StoredWifiConfig::has_saved_config {false}
```

   


<a id="classespectre_1_1_temporal_csi_sampler"></a>

## espectre::TemporalCsiSampler



```cpp
#include <core/temporal_csi_sampler.h>
```



```cpp
class espectre::TemporalCsiSampler
```

 

Admit timestamped CSI packets onto the production fixed-time grid.

  

The sampler retains at most one candidate per target-rate slot, preserves missing slots, rejects invalid timestamp progress, and reports when a gap requires detector history to be cleared. A core-only integration should apply its admission result before forwarding CSI to a detector.

 

The sampler stores timing and slot state, not CSI payloads. The caller keeps the currently selected payload. When [admit()](#classespectre_1_1_temporal_csi_sampler_1a1791e9ab49629b200e9273ae61ebd4aa) commits a prior slot, consume that retained payload before replacing it when [selected\_current()](#classespectre_1_1_temporal_csi_sampler_1ae1ec9c3c8e6f8989c600bab39e628c93) is true.

 

Not thread-safe. Construct, configure, admit, and read it from the task that owns the custom capture pipeline. Construction and [configure()](#classespectre_1_1_temporal_csi_sampler_1af439a77c9ee2831f65801d359ca6a995) use non-throwing storage allocation; check [is\_valid()](#classespectre_1_1_temporal_csi_sampler_1a6815a334d670439cd680f2bd156095d5) after construction and the [configure()](#classespectre_1_1_temporal_csi_sampler_1af439a77c9ee2831f65801d359ca6a995) result before consuming packets. The sampler is movable and intentionally non-copyable because the slot window owns live temporal state.

 

<a id="classespectre_1_1_temporal_csi_sampler_1a223fef3f5d5c971137c31cb937aef12e"></a>

### `TemporalCsiSampler`


```cpp
explicit espectre::TemporalCsiSampler::TemporalCsiSampler(uint32_t target_pps=100U, uint32_t window_size_ms=1000U)
```

 

Construct a sampler for the requested target rate and window duration.

   

<a id="classespectre_1_1_temporal_csi_sampler_1ae08dd76f204e50fa60c43c628a2bbbf2"></a>

### `TemporalCsiSampler`


```cpp
espectre::TemporalCsiSampler::TemporalCsiSampler(TemporalCsiSampler &&) noexcept=default
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ae0fdbbaa165cbd540a6cceae7ccee675"></a>

### `operator=`


```cpp
TemporalCsiSampler & espectre::TemporalCsiSampler::operator=(TemporalCsiSampler &&) noexcept=default
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a7ddc81d12caa7fc7ef9be73eb83db54d"></a>

### `TemporalCsiSampler`


```cpp
espectre::TemporalCsiSampler::TemporalCsiSampler(const TemporalCsiSampler &)=delete
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1af4d593a870758620ec7674408e19dcd7"></a>

### `operator=`


```cpp
TemporalCsiSampler & espectre::TemporalCsiSampler::operator=(const TemporalCsiSampler &)=delete
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1af439a77c9ee2831f65801d359ca6a995"></a>

### `configure`


```cpp
bool espectre::TemporalCsiSampler::configure(uint32_t target_pps, uint32_t window_size_ms)
```

 

Reconfigure the grid and clear its timestamp epoch and window state.

   

<a id="classespectre_1_1_temporal_csi_sampler_1a6815a334d670439cd680f2bd156095d5"></a>

### `is_valid`


```cpp
bool espectre::TemporalCsiSampler::is_valid() const
```

 

Return whether the active slot window owns complete storage.

   

<a id="classespectre_1_1_temporal_csi_sampler_1a2f519ceeb7c1948c6380e13db258376f"></a>

### `reset`


```cpp
void espectre::TemporalCsiSampler::reset()
```

 

Clear the timestamp epoch, window state, and lifetime counters.

   

<a id="classespectre_1_1_temporal_csi_sampler_1a711c178e7646d3e21cd7263c4f9fdfb0"></a>

### `clear_history`


```cpp
void espectre::TemporalCsiSampler::clear_history()
```

 

Clear the window and timestamp grid while retaining lifetime counters.

   

<a id="classespectre_1_1_temporal_csi_sampler_1ad40635b15a773affa083090355b87ee7"></a>

### `clear_window_preserving_phase`


```cpp
void espectre::TemporalCsiSampler::clear_window_preserving_phase()
```

 

Clear admitted window data while retaining the active timestamp grid.

   

<a id="classespectre_1_1_temporal_csi_sampler_1a1791e9ab49629b200e9273ae61ebd4aa"></a>

### `admit`


```cpp
bool espectre::TemporalCsiSampler::admit(uint32_t timestamp_us, bool has_timestamp=true, uint32_t now_us=0U, bool has_now=false)
```

 

Observe one candidate and report whether the retained payload was committed.

  

`now_us` is optional processing time on the same unsigned 32-bit clock as `timestamp_us`. Omit it when the clocks differ, including classic ESP32 Wi-Fi RX timestamps versus `esp_timer`.

  

<a id="classespectre_1_1_temporal_csi_sampler_1a20e40f1dff05429d21aa8a98adc1f45d"></a>

### `flush`


```cpp
bool espectre::TemporalCsiSampler::flush()
```

 

Commit the retained payload when the input stream ends.

   

<a id="classespectre_1_1_temporal_csi_sampler_1a8b8dae0e5fe5148b924e66af47cab22a"></a>

### `target_pps`


```cpp
uint32_t espectre::TemporalCsiSampler::target_pps() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a2b931007fb93c841a71fa7d23a463d62"></a>

### `window_size_ms`


```cpp
uint32_t espectre::TemporalCsiSampler::window_size_ms() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ae2c7518168da096d5fa018b095b9bfb1"></a>

### `window_slots`


```cpp
uint32_t espectre::TemporalCsiSampler::window_slots() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a7a3d5d2332ffa7d8a9f05704f412e5a7"></a>

### `minimum_valid_slots`


```cpp
uint32_t espectre::TemporalCsiSampler::minimum_valid_slots() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a5e631296ec639219dfc7c91eb8cc2928"></a>

### `minimum_sample_spacing_us`


```cpp
uint32_t espectre::TemporalCsiSampler::minimum_sample_spacing_us() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a193d03754a56bc4e09d2604a41aed345"></a>

### `occupancy_slots`


```cpp
uint32_t espectre::TemporalCsiSampler::occupancy_slots() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1adcc84addf47197494916c3f57884daf8"></a>

### `occupancy_ratio`


```cpp
float espectre::TemporalCsiSampler::occupancy_ratio() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a7fcea0bff326d0a049d9c9bb48eb265c"></a>

### `is_ready`


```cpp
bool espectre::TemporalCsiSampler::is_ready() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1afe7474e33d824553b2d33323597dc48a"></a>

### `accepted`


```cpp
bool espectre::TemporalCsiSampler::accepted() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ae1ec9c3c8e6f8989c600bab39e628c93"></a>

### `selected_current`


```cpp
bool espectre::TemporalCsiSampler::selected_current() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ab936c9db7ed7a1c0716272b7c2993933"></a>

### `has_pending_candidate`


```cpp
bool espectre::TemporalCsiSampler::has_pending_candidate() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a8cacc760d7b7599cc2233bde30c7350e"></a>

### `reset_required`


```cpp
bool espectre::TemporalCsiSampler::reset_required() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ac21e227f4e489f3586f13577a18ccc66"></a>

### `gap_reset_required`


```cpp
bool espectre::TemporalCsiSampler::gap_reset_required() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ace42717de24f9c381c0c85a728bcf069"></a>

### `current_slot`


```cpp
uint64_t espectre::TemporalCsiSampler::current_slot() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a32402864d8caa2f17d149cfe95b2caab"></a>

### `slots_advanced`


```cpp
uint64_t espectre::TemporalCsiSampler::slots_advanced() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a8956697103963cddff22fa05626053cc"></a>

### `missing_slots_before`


```cpp
uint64_t espectre::TemporalCsiSampler::missing_slots_before() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a6af061429ee800be178ae81db2141e6f"></a>

### `accepted_packets`


```cpp
uint64_t espectre::TemporalCsiSampler::accepted_packets() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a95f0c153916f097cdcae970f0a5fe322"></a>

### `excess_packets`


```cpp
uint64_t espectre::TemporalCsiSampler::excess_packets() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a49794045bc9b78765549614cfa82b6b2"></a>

### `out_of_order_packets`


```cpp
uint64_t espectre::TemporalCsiSampler::out_of_order_packets() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1ad73b99e1810a1e83292075ec34e34409"></a>

### `stale_packets`


```cpp
uint64_t espectre::TemporalCsiSampler::stale_packets() const
```

   

<a id="classespectre_1_1_temporal_csi_sampler_1a91fdaedfdbc09d6f74a4fec4d37544ae"></a>

### `missing_slots`


```cpp
uint64_t espectre::TemporalCsiSampler::missing_slots() const
```

   


<a id="classespectre_1_1_traffic_generator_manager"></a>

## espectre::TrafficGeneratorManager



```cpp
#include <runtime/esp_idf/traffic_generator_manager.h>
```



```cpp
class espectre::TrafficGeneratorManager : public espectre::ICsiTrafficGenerator
```

 

Paced ESP-IDF traffic generator with a firmware-owned lifecycle.

  [`espectre::ICsiTrafficGenerator`](#classespectre_1_1_i_csi_traffic_generator)



<a id="classespectre_1_1_traffic_generator_manager_1a548e0ec9211af6ac0d8983f06b5b8683"></a>

### `init`


```cpp
void espectre::TrafficGeneratorManager::init(uint32_t target_pps, RuntimeTrafficMode mode=RuntimeTrafficMode::PING) override
```

 

Configure the send rate and backend while stopped.

   

<a id="classespectre_1_1_traffic_generator_manager_1a04d7c96a83f8cbf0a6244fcbe129619d"></a>

### `start`


```cpp
bool espectre::TrafficGeneratorManager::start(uint32_t target_addr) override
```

 

Start sending to an IPv4 address in network byte order; WIFI\_RAW ignores the address.

   

<a id="classespectre_1_1_traffic_generator_manager_1a71b888ef51013730d88e5d1c2554679f"></a>

### `loop`


```cpp
void espectre::TrafficGeneratorManager::loop() override
```

 

Check send progress and report a stalled generator from the owner task.

   

<a id="classespectre_1_1_traffic_generator_manager_1af5c7a6638c9d90e5d4aa289444cc9604"></a>

### `stop`


```cpp
void espectre::TrafficGeneratorManager::stop() override
```

   

<a id="classespectre_1_1_traffic_generator_manager_1aeb69bab1ad47e746c35ec76e879ffded"></a>

### `is_running`


```cpp
bool espectre::TrafficGeneratorManager::is_running() const override
```

   

<a id="classespectre_1_1_traffic_generator_manager_1ae96bf40e87baf67b98c77e937e40f6ef"></a>

### `pause`


```cpp
void espectre::TrafficGeneratorManager::pause()
```

 

Suspend sends without destroying the worker.

   

<a id="classespectre_1_1_traffic_generator_manager_1ac36d125fc2307d4f6122a9146ebb82e4"></a>

### `resume`


```cpp
void espectre::TrafficGeneratorManager::resume()
```

   

<a id="classespectre_1_1_traffic_generator_manager_1a829a2dbcac0ab4de35c0cd92e0681116"></a>

### `is_paused`


```cpp
bool espectre::TrafficGeneratorManager::is_paused() const
```

   

<a id="classespectre_1_1_traffic_generator_manager_1a94c6aa4e46b66482054d438b157938bd"></a>

### `target_rate_pps`


```cpp
uint32_t espectre::TrafficGeneratorManager::target_rate_pps() const
```

   

<a id="classespectre_1_1_traffic_generator_manager_1af37515bc464d44eac94d82db9b8e23c6"></a>

### `current_rate_pps`


```cpp
uint32_t espectre::TrafficGeneratorManager::current_rate_pps() const
```

 

Send rate used by the worker, in packets per second.

   

<a id="classespectre_1_1_traffic_generator_manager_1a05a24eb916d7ef9b4bb71999b08c8da4"></a>

### `send_success_count`


```cpp
uint32_t espectre::TrafficGeneratorManager::send_success_count() const override
```

 

Number of successful sends in the current session.

   

<a id="classespectre_1_1_traffic_generator_manager_1a234d3ce12e136fa717fb88979287c78e"></a>

### `send_error_count`


```cpp
uint32_t espectre::TrafficGeneratorManager::send_error_count() const
```

 

Number of failed sends in the current session.

   

<a id="classespectre_1_1_traffic_generator_manager_1ace20abf21cf500964cc91747c7423830"></a>

### `icmp_identifier`


```cpp
uint16_t espectre::TrafficGeneratorManager::icmp_identifier() const override
```

 

ICMP identifier used to recognize this generator's ping replies.

   


<a id="structespectre_1_1_udp_datagram_peer"></a>

## espectre::UdpDatagramPeer



```cpp
#include <runtime/udp_datagram_socket.h>
```



```cpp
struct espectre::UdpDatagramPeer
```

  

<a id="structespectre_1_1_udp_datagram_peer_1a8ad9fa7d60974939dd76d1a1eedc4c2d"></a>

### `ipv4_addr`


```cpp
uint32_t espectre::UdpDatagramPeer::ipv4_addr {0U}
```

   

<a id="structespectre_1_1_udp_datagram_peer_1aed7273d785b3417c4c2bdaa70bccc9be"></a>

### `port`


```cpp
uint16_t espectre::UdpDatagramPeer::port {0U}
```

   


<a id="classespectre_1_1_wi_fi_lifecycle_manager"></a>

## espectre::WiFiLifecycleManager



```cpp
#include <runtime/esp_idf/wifi_lifecycle.h>
```



```cpp
class espectre::WiFiLifecycleManager
```

 

WiFi Lifecycle Manager.

  

Manages WiFi connection events and coordinates service lifecycle. Handles startup sequence: CSI → Traffic Generator → Band Calibration Applies station TX rate policy before connected callbacks, independently of whether sensing uses an internal generator or external traffic.

 

The STA-start handler applies the short radio policy synchronously, before association. Connect/disconnect callbacks run from [process\_pending\_events()](#classespectre_1_1_wi_fi_lifecycle_manager_1adc7ad4c05118e53e0767d4123f374517), which the runtime must call from its loop task. This keeps service startup and log formatting off the small default event loop task (sys\_evt) stack.

 

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1a812e0a4f46c766d812658185aa933761"></a>

### `register_handlers`


```cpp
esp_err_t espectre::WiFiLifecycleManager::register_handlers(wifi_connected_callback_t connected_cb, wifi_disconnected_callback_t disconnected_cb, WifiBandPolicy band_policy=WifiBandPolicy::BAND_2G)
```

 

Register WiFi event handlers.

  

**Parameters**

- `connected_cb`: Callback when WiFi obtains or retains an IPv4 configuration; receives the address, netmask, and gateway after GOT\_IP or reassociation
- `disconnected_cb`: Callback when WiFi disconnects
- `band_policy`: Station band policy used while applying connection settings

 

**Returns:** ESP\_OK on success. If the default station already has an IPv4 address, its current state is queued for [process\_pending\_events()](#classespectre_1_1_wi_fi_lifecycle_manager_1adc7ad4c05118e53e0767d4123f374517).

  

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1ae130fbbcc4833a424e4ad4488143c338"></a>

### `unregister_handlers`


```cpp
void espectre::WiFiLifecycleManager::unregister_handlers()
```

 

Unregister WiFi event handlers.

   

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1adc7ad4c05118e53e0767d4123f374517"></a>

### `process_pending_events`


```cpp
esp_err_t espectre::WiFiLifecycleManager::process_pending_events()
```

 

Invoke the registered callbacks for events recorded by the handlers.

  

Must be called periodically from the runtime loop task. Events are processed in the same order in which the ESP event loop recorded them.

  

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1a961879e62832d9e5c459ea44454fce7f"></a>

### `refresh_csi_receive_path`


```cpp
esp_err_t espectre::WiFiLifecycleManager::refresh_csi_receive_path(wifi_csi_rx_refresh_callback_t callback)
```

 

Run the asynchronous station scan required to refresh the CSI receive path after reassociation.

  

Promiscuous mode is kept disabled throughout. The completion callback runs from [process\_pending\_events()](#classespectre_1_1_wi_fi_lifecycle_manager_1adc7ad4c05118e53e0767d4123f374517).

  

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1a1fe9bba1e6dd8c26acf37503fc3e80cc"></a>

### `cancel_csi_receive_path_refresh`


```cpp
void espectre::WiFiLifecycleManager::cancel_csi_receive_path_refresh()
```

 

Cancel an in-flight CSI receive-path refresh.

  

Late scan completion events are invalidated and cannot invoke the canceled callback.

  


<a id="classespectre_1_1_wi_fi_lifecycle_manager_1a731bac4db6341b9069145f34197c4044"></a>

### `apply_started_csi_policy`


```cpp
static esp_err_t espectre::WiFiLifecycleManager::apply_started_csi_policy(WifiBandPolicy band_policy=WifiBandPolicy::BAND_2G)
```

 

Apply the short CSI radio policy that must run after WIFI\_EVENT\_STA\_START and before association.

  

Safe to call more than once; later calls are no-ops once protocol, bandwidth, and power-save already match.

  

<a id="classespectre_1_1_wi_fi_lifecycle_manager_1a9dc55a7bc08ab9e6c4a0dd9c315c52e7"></a>

### `reinitialize_stopped_station_driver`


```cpp
static esp_err_t espectre::WiFiLifecycleManager::reinitialize_stopped_station_driver(wifi_storage_t storage=WIFI_STORAGE_RAM)
```

 

Reinitialize an already-stopped station driver and restore the invariants required by every CSI frontend.

  

The caller remains responsible for applying its station configuration and starting the driver.

  


<a id="classespectre_1_1_wifi_bssid_pin_service"></a>

## espectre::WifiBssidPinService



```cpp
#include <runtime/esp_idf/wifi_bssid_pin_service.h>
```



```cpp
class espectre::WifiBssidPinService
```

  

<a id="classespectre_1_1_wifi_bssid_pin_service_1a4401cef436ec422e0f47bedc102832a0"></a>

### `setup`


```cpp
esp_err_t espectre::WifiBssidPinService::setup(WifiBssidPinServiceConfig config)
```

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1a22c79734f4160237420aeb468627ca1b"></a>

### `request_update`


```cpp
bool espectre::WifiBssidPinService::request_update(const std::string &bssid, std::string *message, bool force=false)
```

 

Stage a pin update.

  

An empty BSSID clears the current override.

  

<a id="classespectre_1_1_wifi_bssid_pin_service_1aa335fdf5103c23d6baad549e4279ea37"></a>

### `notify_station_changed`


```cpp
void espectre::WifiBssidPinService::notify_station_changed()
```

 

Schedule a station snapshot refresh after a Wi-Fi or IP event.

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1a9ffdc9e9947edb8d41fd79f60c3afddd"></a>

### `loop`


```cpp
void espectre::WifiBssidPinService::loop()
```

 

Advance verification, rollback, and boot-time enforcement.

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1af64af02c4ef7cd53cd586b0d6f1969b1"></a>

### `apply_state`


```cpp
WifiBssidPinApplyState espectre::WifiBssidPinService::apply_state() const
```

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1acc0f42e341b2b5eee23c4eafebc50527"></a>

### `apply_message`


```cpp
const std::string & espectre::WifiBssidPinService::apply_message() const
```

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1accd04bb7d2f92f873918389af209e283"></a>

### `stored_ssid`


```cpp
const std::string & espectre::WifiBssidPinService::stored_ssid() const
```

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1a73cf4b9405976db503875edf9fac3280"></a>

### `stored_bssid`


```cpp
const std::string & espectre::WifiBssidPinService::stored_bssid() const
```

   

<a id="classespectre_1_1_wifi_bssid_pin_service_1aa97db1ae127786e2db9204a8ba0bdbc3"></a>

### `apply_pending`


```cpp
bool espectre::WifiBssidPinService::apply_pending() const
```

   


<a id="structespectre_1_1_wifi_bssid_pin_service_config"></a>

## espectre::WifiBssidPinServiceConfig



```cpp
#include <runtime/esp_idf/wifi_bssid_pin_service.h>
```



```cpp
struct espectre::WifiBssidPinServiceConfig
```

  

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1a43cf641913174835573ac08ef3b4d420"></a>

### `ApplyCallback`


```cpp
using espectre::WifiBssidPinServiceConfig::ApplyCallback = std::function<bool(const std::string &bssid,
                                          std::string *message,
                                          bool *station_transition_started)>
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1a307fa876d73c4361b58844f74a319044"></a>

### `StationStateGetter`


```cpp
using espectre::WifiBssidPinServiceConfig::StationStateGetter = std::function<WifiBssidPinStationState()>
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1aa9165f343c1ff8b0386a6aac8649ff84"></a>

### `ChangeCallback`


```cpp
using espectre::WifiBssidPinServiceConfig::ChangeCallback = std::function<void()>
```

   


<a id="structespectre_1_1_wifi_bssid_pin_service_config_1a3a678d1e92866b879c0a6fed14c0a0d1"></a>

### `apply_callback`


```cpp
ApplyCallback espectre::WifiBssidPinServiceConfig::apply_callback
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1a7dcbfda84aa709b87ab638c4c9b11257"></a>

### `station_state_getter`


```cpp
StationStateGetter espectre::WifiBssidPinServiceConfig::station_state_getter
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1ab6a059f017598440ed5f032098163e05"></a>

### `prepare_callback`


```cpp
ChangeCallback espectre::WifiBssidPinServiceConfig::prepare_callback
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1afecd3ee11a65e73e94ba868fe1849696"></a>

### `resume_callback`


```cpp
ChangeCallback espectre::WifiBssidPinServiceConfig::resume_callback
```

   

<a id="structespectre_1_1_wifi_bssid_pin_service_config_1a997a6e6e9b0d3f9ae139b8b14c1f2383"></a>

### `candidate_timeout_ms`


```cpp
uint32_t espectre::WifiBssidPinServiceConfig::candidate_timeout_ms {60000U}
```

   


<a id="structespectre_1_1_wifi_bssid_pin_station_state"></a>

## espectre::WifiBssidPinStationState



```cpp
#include <runtime/esp_idf/wifi_bssid_pin_service.h>
```



```cpp
struct espectre::WifiBssidPinStationState
```

  

<a id="structespectre_1_1_wifi_bssid_pin_station_state_1a77a4ce1f6e06efd30575a0522e4c0b14"></a>

### `configured`


```cpp
bool espectre::WifiBssidPinStationState::configured {false}
```

   

<a id="structespectre_1_1_wifi_bssid_pin_station_state_1a6dcf90c72c8d65cd7bcafef65ea5111f"></a>

### `connected`


```cpp
bool espectre::WifiBssidPinStationState::connected {false}
```

   

<a id="structespectre_1_1_wifi_bssid_pin_station_state_1ab3cb0d1e67769e8b613f2e33ea0991ad"></a>

### `has_ipv4`


```cpp
bool espectre::WifiBssidPinStationState::has_ipv4 {false}
```

   

<a id="structespectre_1_1_wifi_bssid_pin_station_state_1ab9820051700cf3b76fa5deff4234bab5"></a>

### `ssid`


```cpp
std::string espectre::WifiBssidPinStationState::ssid
```

   

<a id="structespectre_1_1_wifi_bssid_pin_station_state_1a6a7257e881fe796a509c6a9c6ed0ae67"></a>

### `bssid`


```cpp
std::string espectre::WifiBssidPinStationState::bssid
```

   


<a id="structespectre_1_1_wifi_provisioning_defaults"></a>

## espectre::WifiProvisioningDefaults



```cpp
#include <runtime/esp_idf/wifi_provisioning_service.h>
```



```cpp
struct espectre::WifiProvisioningDefaults
```

  

<a id="structespectre_1_1_wifi_provisioning_defaults_1a3a22055cc0538d86ff249966a20b1e92"></a>

### `ssid`


```cpp
const char* espectre::WifiProvisioningDefaults::ssid {nullptr}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1a707b4a5359b3c35e8dc9d7e80480148b"></a>

### `password`


```cpp
const char* espectre::WifiProvisioningDefaults::password {nullptr}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1a83ebf67e6dad57074c647376bb5ae8e8"></a>

### `bssid`


```cpp
const char* espectre::WifiProvisioningDefaults::bssid {nullptr}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1a35539b167d170151e209d5143a358384"></a>

### `channel`


```cpp
uint8_t espectre::WifiProvisioningDefaults::channel {0U}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1ae3233820bf084e6f88f7bf85dad3ea8f"></a>

### `max_retry`


```cpp
int espectre::WifiProvisioningDefaults::max_retry {8}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1aa1abbc62d0564095be5d628db8f093ad"></a>

### `manage_csi_lifecycle`


```cpp
bool espectre::WifiProvisioningDefaults::manage_csi_lifecycle {false}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1ab55754dfbbfe2c004275d70cd749f735"></a>

### `band_policy`


```cpp
WifiBandPolicy espectre::WifiProvisioningDefaults::band_policy {WifiBandPolicy::BAND_2G}
```

   

<a id="structespectre_1_1_wifi_provisioning_defaults_1aa473c6cdb212af5a5ae41b8bcdd4458d"></a>

### `candidate_timeout_ms`


```cpp
uint32_t espectre::WifiProvisioningDefaults::candidate_timeout_ms {30000U}
```

 

Per-association verification window for a staged candidate.

   


<a id="classespectre_1_1_wifi_provisioning_service"></a>

## espectre::WifiProvisioningService



```cpp
#include <runtime/esp_idf/wifi_provisioning_service.h>
```



```cpp
class espectre::WifiProvisioningService
```

  

<a id="classespectre_1_1_wifi_provisioning_service_1a783569a1db3ddc367f220380b3d394e0"></a>

### `ChangeCallback`


```cpp
using espectre::WifiProvisioningService::ChangeCallback = std::function<void()>
```

   


<a id="classespectre_1_1_wifi_provisioning_service_1a00ae7a5deaa2fbf70206a118bd63e32f"></a>

### `WifiProvisioningService`


```cpp
explicit espectre::WifiProvisioningService::WifiProvisioningService(StandaloneWifiService *wifi_manager)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a3974e07bf87f9714e0733a0b0ac30477"></a>

### `set_change_callback`


```cpp
void espectre::WifiProvisioningService::set_change_callback(ChangeCallback callback)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a74cc326ce0bdeb9da7ed6fa8e3c63237"></a>

### `set_reconfigure_callbacks`


```cpp
void espectre::WifiProvisioningService::set_reconfigure_callbacks(ChangeCallback prepare_callback, ChangeCallback resume_callback)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a19f93cc32488b559cfc50d8bf4798c2d"></a>

### `set_scan_callbacks`


```cpp
void espectre::WifiProvisioningService::set_scan_callbacks(ChangeCallback prepare_callback, ChangeCallback resume_callback)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1aa9ed3ddf8930c9c917e849dde72718c9"></a>

### `set_apply_completed_callback`


```cpp
void espectre::WifiProvisioningService::set_apply_completed_callback(ChangeCallback callback)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a83780a13c9467f636d6df89e02b7d327"></a>

### `load_or_set_defaults`


```cpp
esp_err_t espectre::WifiProvisioningService::load_or_set_defaults(const WifiProvisioningDefaults &defaults)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a16a9ec64e656c3de1c1db41742892481"></a>

### `setup_station`


```cpp
esp_err_t espectre::WifiProvisioningService::setup_station(const WifiProvisioningDefaults &defaults, standalone_wifi_callback_t connected_cb={}, standalone_wifi_callback_t disconnected_cb={})
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a1dbc037cfb93993188c2b7db33183a1a"></a>

### `handle_command`


```cpp
bool espectre::WifiProvisioningService::handle_command(const std::string &command, std::string *message)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1aba5fb367940e5c866a4ae62ed0753dd2"></a>

### `request_access_point_scan`


```cpp
bool espectre::WifiProvisioningService::request_access_point_scan(std::string *message)
```

 

Start an asynchronous scan; results are limited to the provisioned SSID.

   

<a id="classespectre_1_1_wifi_provisioning_service_1a56081293fee4af1ea5c849d0ce43b43d"></a>

### `begin_serial_provisioning`


```cpp
bool espectre::WifiProvisioningService::begin_serial_provisioning(const std::string &ssid, const std::string &password, std::string *message)
```

 

Stage credentials received through the standard Improv Serial RPC.

   

<a id="classespectre_1_1_wifi_provisioning_service_1a8b8c00c288e12539a262cf41d4760c72"></a>

### `loop`


```cpp
void espectre::WifiProvisioningService::loop()
```

 

Advance candidate verification and bounded rollback after Wi-Fi events.

   

<a id="classespectre_1_1_wifi_provisioning_service_1a79c35f784213d4c5ec03db18158e2aec"></a>

### `apply_live`


```cpp
bool espectre::WifiProvisioningService::apply_live(std::string *message)
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a966219c8a620bb247e791797f6685c0d"></a>

### `config`


```cpp
const StoredWifiConfig & espectre::WifiProvisioningService::config() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1aa4bdfeaf9f64a161badbfad96051caf5"></a>

### `password_set`


```cpp
bool espectre::WifiProvisioningService::password_set() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1abf46e703d2106f21c5583050a3d8a66b"></a>

### `last_load_result`


```cpp
esp_err_t espectre::WifiProvisioningService::last_load_result() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1aa2477794505d74aedc6e2869800d48a7"></a>

### `apply_state`


```cpp
WifiProvisioningApplyState espectre::WifiProvisioningService::apply_state() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a3fd2939db9ab7ad2430888b02517894e"></a>

### `apply_message`


```cpp
const std::string & espectre::WifiProvisioningService::apply_message() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a2bfc4c97846f8b70f24d3ed25bc25a8c"></a>

### `apply_pending`


```cpp
bool espectre::WifiProvisioningService::apply_pending() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a7d349ff6069f83f6f732092975e94a46"></a>

### `scan_pending`


```cpp
bool espectre::WifiProvisioningService::scan_pending() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1a32582a8a2a634e845bf09eca86f55522"></a>

### `access_points`


```cpp
const std::vector< StandaloneWifiAccessPoint > & espectre::WifiProvisioningService::access_points() const
```

   

<a id="classespectre_1_1_wifi_provisioning_service_1acfc4a3b903d45ff9e465dfaed1991b88"></a>

### `scan_message`


```cpp
const std::string & espectre::WifiProvisioningService::scan_message() const
```

   


<a id="classespectre_1_1detail_1_1_pending_event_lock"></a>

## espectre::detail::PendingEventLock



```cpp
#include <runtime/pending_event.h>
```



```cpp
class espectre::detail::PendingEventLock
```

  

<a id="classespectre_1_1detail_1_1_pending_event_lock_1a9eb49c9d794fb2eeefc06280c2615bfa"></a>

### `lock`


```cpp
void espectre::detail::PendingEventLock::lock()
```

   

<a id="classespectre_1_1detail_1_1_pending_event_lock_1a0e36600a25f78a577863faf6cdbee145"></a>

### `unlock`


```cpp
void espectre::detail::PendingEventLock::unlock()
```

   


<a id="structespectre__diagnostic__field__t"></a>

## espectre\_diagnostic\_field\_t



```cpp
#include <runtime/diagnostic_fields.h>
```



```cpp
struct espectre_diagnostic_field_t
```

  

<a id="structespectre__diagnostic__field__t_1a408388c99ede059fe9ba5d59144b843f"></a>

### `name`


```cpp
const char* espectre_diagnostic_field_t::name
```

   

<a id="structespectre__diagnostic__field__t_1a72e7dedd3d33f32ac6c053ac2f68022f"></a>

### `type`


```cpp
const char* espectre_diagnostic_field_t::type
```

   

<a id="structespectre__diagnostic__field__t_1abe5eaa83e5e4261fbffdec2ee05d346b"></a>

### `unit`


```cpp
const char* espectre_diagnostic_field_t::unit
```

   

<a id="structespectre__diagnostic__field__t_1a96265d791a592d8cb009930e8f495761"></a>

### `profiles`


```cpp
unsigned espectre_diagnostic_field_t::profiles
```

   


<a id="base__detector_8h"></a>

## base\_detector.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <algorithm>
```



```cpp
#include <detector_types.h>
```



```cpp
#include <detector_limits.h>
```



```cpp
#include <filters.h>
```



```cpp
#include <utils.h>
```

  [`espectre::BaseDetector`](#classespectre_1_1_base_detector)

[`espectre`](#namespaceespectre)



<a id="csi__capture__profile_8h"></a>

## csi\_capture\_profile.h



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)



<a id="csi__format_8h"></a>

## csi\_format.h



```cpp
#include <array>
```



```cpp
#include <cmath>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <cstring>
```



```cpp
#include <csi_types.h>
```



```cpp
#include <utils.h>
```

  [`espectre`](#namespaceespectre)

[`espectre::detail`](#namespaceespectre_1_1detail)



<a id="csi__raw__record_8h"></a>

## csi\_raw\_record.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```

  [`espectre::RawCsiRecordHeaderV7`](#structespectre_1_1_raw_csi_record_header_v7)

[`espectre::RawCsiRecordHeaderV8`](#structespectre_1_1_raw_csi_record_header_v8)

[`espectre`](#namespaceespectre)



<a id="csi__traffic__service_8h"></a>

## csi\_traffic\_service.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <csi_traffic_types.h>
```



```cpp
#include <runtime_interface.h>
```



```cpp
#include <udp_datagram_socket.h>
```

  [`espectre::CsiTrafficServiceConfig`](#structespectre_1_1_csi_traffic_service_config)

[`espectre::ICsiTrafficGenerator`](#classespectre_1_1_i_csi_traffic_generator)

[`espectre::ICsiTrafficIngress`](#classespectre_1_1_i_csi_traffic_ingress)

[`espectre::CsiTrafficService`](#classespectre_1_1_csi_traffic_service)

[`espectre`](#namespaceespectre)



<a id="csi__traffic__types_8h"></a>

## csi\_traffic\_types.h

  [`espectre`](#namespaceespectre)



<a id="csi__types_8h"></a>

## csi\_types.h



```cpp
#include <array>
```



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)



<a id="detector__limits_8h"></a>

## detector\_limits.h



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)



<a id="detector__types_8h"></a>

## detector\_types.h

  [`espectre`](#namespaceespectre)



<a id="device__config__store_8h"></a>

## device\_config\_store.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <esp_err.h>
```



```cpp
#include <espectre_protocol.h>
```



```cpp
#include <runtime_interface.h>
```

  [`espectre::StoredWifiConfig`](#structespectre_1_1_stored_wifi_config)

[`espectre`](#namespaceespectre)



<a id="device__identity_8h"></a>

## device\_identity.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```

  [`espectre`](#namespaceespectre)



<a id="diagnostic__fields_8h"></a>

## diagnostic\_fields.h

 

C-compatible metadata for the canonical device diagnostic catalog.

  

Profiles are bitmasks: Native=1, bridge=2, and Micro=4. Dotted field names select leaves while protocol responses retain their nested objects.

 [`espectre_diagnostic_field_t`](#structespectre__diagnostic__field__t)



<a id="diagnostic__fields_8h_1aab4accacf85c5d9df1fe8881d3e90aa1"></a>

### `ESPECTRE_DIAGNOSTIC_FIELD_COUNT`


```cpp
#define ESPECTRE_DIAGNOSTIC_FIELD_COUNT (sizeof(espectre_diagnostic_fields) / sizeof(espectre_diagnostic_fields[0]))
```

   


<a id="diagnostic__fields_8h_1a08e8682b5949c9c4654abaabbf7bc6bc"></a>

### `espectre_diagnostic_fields`


```cpp
const espectre_diagnostic_field_t espectre_diagnostic_fields[][]
```

 

Canonical diagnostic fields; filter by profile before exposing a catalog.

   


<a id="direct__http__protocol_8h"></a>

## direct\_http\_protocol.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <espectre_protocol.h>
```

  [`espectre::DirectRequest`](#structespectre_1_1_direct_request)

[`espectre`](#namespaceespectre)



<a id="direct__http__service_8h"></a>

## direct\_http\_service.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <direct_http_protocol.h>
```



```cpp
#include <raw_csi.h>
```

  [`espectre::DirectHttpServiceConfig`](#structespectre_1_1_direct_http_service_config)

[`espectre::DirectHttpServiceDiagnostics`](#structespectre_1_1_direct_http_service_diagnostics)

[`espectre::IDirectHttpService`](#classespectre_1_1_i_direct_http_service)

[`espectre::IDirectHttpService::DeferredRequestResult`](#structespectre_1_1_i_direct_http_service_1_1_deferred_request_result)

[`espectre`](#namespaceespectre)



<a id="direct__http__service__esp__idf_8h"></a>

## direct\_http\_service\_esp\_idf.h



```cpp
#include <array>
```



```cpp
#include <atomic>
```



```cpp
#include <deque>
```



```cpp
#include <memory>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <esp_http_server.h>
```



```cpp
#include <freertos/FreeRTOS.h>
```



```cpp
#include <freertos/semphr.h>
```



```cpp
#include <freertos/task.h>
```



```cpp
#include <csi_types.h>
```



```cpp
#include <direct_http_service.h>
```



```cpp
#include <pending_event.h>
```

  [`espectre::EspIdfDirectHttpService`](#classespectre_1_1_esp_idf_direct_http_service)

[`espectre`](#namespaceespectre)



<a id="direct__wifi__snapshot__esp__idf_8h"></a>

## direct\_wifi\_snapshot\_esp\_idf.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```

  [`espectre::DirectWifiSnapshot`](#structespectre_1_1_direct_wifi_snapshot)

[`espectre`](#namespaceespectre)



<a id="espectre__banner_8h"></a>

## espectre\_banner.h

  [`espectre`](#namespaceespectre)



<a id="espectre__core__sdk_8h"></a>

## espectre\_core\_sdk.h



```cpp
#include <runtime/espectre_sdk_version.h>
```



```cpp
#include <core/espectre_log.h>
```



```cpp
#include <core/base_detector.h>
```



```cpp
#include <core/csi_format.h>
```



```cpp
#include <core/high_accuracy_detector.h>
```



```cpp
#include <core/lightweight_detector.h>
```



```cpp
#include <core/temporal_csi_sampler.h>
```

 

Core-only detector API for custom CSI capture integrations.

  

Prefer [`espectre_sdk.h`](#espectre__sdk_8h) and `RuntimeFrontendController` when ESPectre should own CSI capture, temporal admission, calibration, and event delivery. Include this facade only when the embedding firmware already implements those parts.

 

<a id="espectre__log_8h"></a>

## espectre\_log.h



```cpp
#include <cstdarg>
```



```cpp
#include <cstdint>
```

  [`espectre::LogSink`](#structespectre_1_1_log_sink)

[`espectre`](#namespaceespectre)



<a id="espectre__log_8h_1a2452a301ac5b137469ae614b74ee149c"></a>

### `ESPECTRE_LOG_AT_LEVEL`


```cpp
#define ESPECTRE_LOG_AT_LEVEL(level, tag, format, ...) do {                                                                                            \
  const char *const espectre_log_tag__ = (tag);                                                 \
  if (::espectre::log_enabled((level), espectre_log_tag__)) {                                   \
    ::espectre::detail::log_printf((level), espectre_log_tag__, __LINE__, (format),             \
                                   ##__VA_ARGS__);                                               \
  }                                                                                             \
} while (false)
```

   

<a id="espectre__log_8h_1ab36e1f3068305cde3db4c480d2fa875d"></a>

### `ESPECTRE_LOGE`


```cpp
#define ESPECTRE_LOGE(tag, format, ...) ESPECTRE_LOG_AT_LEVEL(::espectre::LogLevel::ERROR, tag, format, ##__VA_ARGS__)
```

   

<a id="espectre__log_8h_1a68a060eeeeafdb7b959a76e2333e58a8"></a>

### `ESPECTRE_LOGW`


```cpp
#define ESPECTRE_LOGW(tag, format, ...) ESPECTRE_LOG_AT_LEVEL(::espectre::LogLevel::WARNING, tag, format, ##__VA_ARGS__)
```

   

<a id="espectre__log_8h_1a7d3ba0708ef9dd2a162c694d70648dd6"></a>

### `ESPECTRE_LOGI`


```cpp
#define ESPECTRE_LOGI(tag, format, ...) ESPECTRE_LOG_AT_LEVEL(::espectre::LogLevel::INFO, tag, format, ##__VA_ARGS__)
```

   

<a id="espectre__log_8h_1acd3d41a27469c25aa5a01f0f28859b10"></a>

### `ESPECTRE_LOGD`


```cpp
#define ESPECTRE_LOGD(tag, format, ...) ESPECTRE_LOG_AT_LEVEL(::espectre::LogLevel::DEBUG, tag, format, ##__VA_ARGS__)
```

   

<a id="espectre__log_8h_1a2f6d5220e8d4a419bec05dbaaebfcc25"></a>

### `ESPECTRE_LOGV`


```cpp
#define ESPECTRE_LOGV(tag, format, ...) ESPECTRE_LOG_AT_LEVEL(::espectre::LogLevel::VERBOSE, tag, format, ##__VA_ARGS__)
```

   


<a id="espectre__mqtt__sdk_8h"></a>

## espectre\_mqtt\_sdk.h



```cpp
#include <espectre_sdk.h>
```



```cpp
#include <runtime/esp_idf/mqtt_transport_esp_idf.h>
```

 

Opt-in ESP-IDF implementation of the public MQTT transport contract.

  

Requires ESP-IDF's mqtt component and ESPECTRE\_RUNTIME\_ESP\_IDF\_MQTT\_SOURCES (or CONFIG\_ESPECTRE\_SDK\_ENABLE\_MQTT). The integrating firmware owns the transport object and drives its lifecycle. Other services do not require this facade or the MQTT stack.

 

<a id="espectre__protocol_8h"></a>

## espectre\_protocol.h



```cpp
#include <array>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <runtime_snapshot.h>
```



```cpp
#include <protocol_json.h>
```

 

Wire types and payload builders for the ESPectre Protocol.

  

The protocol is the contract between a device and whatever consumes it: MQTT topics, Direct HTTP messages, JSON payloads, and frontend extensions. It is specified in `docs/API.md`; this header is the C++ view of that specification.

 

Use it whenever your integration should stay interoperable with the shipped clients — the CLI, Home Assistant discovery, and the web portal all speak it. The builders take a `RuntimeSnapshot` and return a serialized payload, so your transport only moves bytes and never formats them.

 

The parsers never throw: they validate and report failure through an out parameter. They do not all roll back cleanly on rejection, so parse into a copy of your live configuration and commit it only on success, which is what the shipped frontends do.

 [`espectre::EspectreApiRoute`](#structespectre_1_1_espectre_api_route)

[`espectre::EspectreApiEventDescriptor`](#structespectre_1_1_espectre_api_event_descriptor)

[`espectre::EspectreExtensionRoute`](#structespectre_1_1_espectre_extension_route)

[`espectre::EspectreProtocolExtension`](#structespectre_1_1_espectre_protocol_extension)

[`espectre::EspectreCapabilityProfile`](#structespectre_1_1_espectre_capability_profile)

[`espectre::EspectreDeviceConfig`](#structespectre_1_1_espectre_device_config)

[`espectre::EspectreNetworkInfo`](#structespectre_1_1_espectre_network_info)

[`espectre::EspectreDeviceInfo`](#structespectre_1_1_espectre_device_info)

[`espectre::EspectreCommand`](#structespectre_1_1_espectre_command)

[`espectre`](#namespaceespectre)



<a id="espectre__sdk_8h"></a>

## espectre\_sdk.h



```cpp
#include <runtime/espectre_sdk_version.h>
```



```cpp
#include <core/espectre_log.h>
```



```cpp
#include <runtime/csi_capture_profile.h>
```



```cpp
#include <runtime/runtime_capabilities.h>
```



```cpp
#include <runtime/runtime_config_utils.h>
```



```cpp
#include <runtime/runtime_diagnostics.h>
```



```cpp
#include <runtime/diagnostic_fields.h>
```



```cpp
#include <runtime/runtime_events.h>
```



```cpp
#include <runtime/runtime_interface.h>
```



```cpp
#include <runtime/raw_csi.h>
```



```cpp
#include <runtime/runtime_sensing_schema.h>
```



```cpp
#include <runtime/runtime_snapshot.h>
```



```cpp
#include <runtime/espectre_protocol.h>
```



```cpp
#include <runtime/protocol_json.h>
```



```cpp
#include <runtime/direct_http_service.h>
```



```cpp
#include <runtime/mqtt_transport.h>
```



```cpp
#include <runtime/esp_idf/device_identity.h>
```



```cpp
#include <runtime/esp_idf/runtime_frontend_controller.h>
```



```cpp
#include <runtime/esp_idf/runtime_sensing_kconfig.h>
```

 

The public ESPectre integration surface, in one include.

  

ESPectre turns ordinary Wi-Fi traffic into a motion signal: it captures Channel State Information from the radio, extracts features, and reports a debounced motion state. This header is the supported entry point for firmware that embeds the sensing engine in its own application.

 

```cpp
#include "espectre_sdk.h"

class ProductFrontend : public espectre::IRuntimeListener {
 public:
  bool setup() {
    espectre::RuntimeConfig config;  // documented defaults, ready to use
    runtime_.set_config(config);
    return runtime_.setup(this);
  }

  void loop() { runtime_.loop(); }

  void on_motion_state_changed(const espectre::RuntimeSnapshot &snapshot) override {
    if (!snapshot.ready_to_publish) return;
    publish(snapshot.motion_state == espectre::MotionState::MOTION);
  }

 private:
  espectre::RuntimeFrontendController runtime_;
};
```

 

<a id="espectre__sdk_8h_1sdk_paths"></a>

### Two integration paths



- **Full runtime (recommended).** Your firmware owns boot, provisioning, networking, OTA, and the product surface. ESPectre owns Wi-Fi CSI capture, calibration, detection, and eventing behind [`espectre::RuntimeFrontendController`](#classespectre_1_1_runtime_frontend_controller) and [`espectre::IRuntimeListener`](#classespectre_1_1_i_runtime_listener). Requires ESP-IDF &gt;= 5.5.5 and &lt; 5.6.0.

- **Core-only.** Your firmware already captures CSI. Include [`espectre_core_sdk.h`](#espectre__core__sdk_8h) and drive [`espectre::LightweightDetector`](#classespectre_1_1_lightweight_detector) or [`espectre::HighAccuracyDetector`](#classespectre_1_1_high_accuracy_detector) directly. `runtime/esp_idf/csi_pipeline.cpp` is the reference for normalization, evaluation cadence, and hit filtering.

 

<a id="espectre__sdk_8h_1sdk_threading"></a>

### Threading contract



The control surface is single-owner. Internal bounded mailboxes protect callback-to-loop handoff, but they do not make control calls thread-safe.



- Run `setup()`, `loop()`, and `shutdown()` on one task. These are the calls that build and tear down runtime state, and they are not safe to race.

- Every `IRuntimeListener` callback is delivered on the caller's task: from `loop()` for sensing events, or inline on the task that invoked a control method. Work raised in the Wi-Fi CSI callback is deferred through an internal mailbox first, so no listener callback runs in interrupt or Wi-Fi driver context.

- Keep callbacks bounded and non-blocking. Slow work delays `loop()` and can fill the bounded CSI mailbox, dropping incoming frames. Queue network I/O, NVS writes, and other blocking work for another task.

- Call `set_*_runtime()` only from the owner task. Queue commands received by network callbacks and apply them from that task's loop.

- Do not drive the controller from inside `on_runtime_fault()` beyond `shutdown()`.

- Raw CSI packet callbacks are the deliberate exception to listener delivery: they run synchronously in Wi-Fi capture context. Keep them bounded, non-blocking, and allocation-free; see `raw_csi_packet_callback_t`.

 

<a id="espectre__sdk_8h_1sdk_versioning"></a>

### Versioning



[`ESPECTRE_SDK_VERSION_STRING`](#espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74) and [`ESPECTRE_SDK_VERSION_AT_LEAST()`](#espectre__sdk__version_8h_1a84f438434c7a7b020e175e84ae3ca6e8) identify the SDK sources you compiled against. See [`runtime/espectre_sdk_version.h`](#espectre__sdk__version_8h) for how that differs from your firmware version.

 

<a id="espectre__sdk_8h_1sdk_stability"></a>

### Stability tiers



Everything reachable from this header is the stable runtime surface and follows the SDK version contract. The opt-in [`espectre_core_sdk.h`](#espectre__core__sdk_8h) facade is the lower-level detector extension. The optional services and MQTT facades expose supported ESP-IDF integration contracts. Headers included only as implementation dependencies can change in any release. See [Versioning](#sdk_integration_1integration_versioning) for the exact guarantees.

 

<a id="espectre__sdk_8h_1sdk_licensing"></a>

### Licensing



ESPectre is dual-licensed: GPLv3, or a separately offered commercial license for proprietary firmware. See `LICENSING.md`.

 

<a id="espectre__sdk__version_8h"></a>

## espectre\_sdk\_version.h

 

Compile-time identity of the ESPectre SDK sources you compiled against.

  

This is the version of the *SDK*, not of your firmware. The two are deliberately separate:

 

- [`ESPECTRE_SDK_VERSION_STRING`](#espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74) is baked in at compile time and identifies the ESPectre sources in your build. Use it in diagnostics, bug reports, and to guard code against SDK releases.

- The *application* version is supplied to the runtime by the frontend or integrator. In an integration it is your product's version, not ESPectre's.

 

Published SDK bundles stamp their identity into this header. Integrators can supply all four version macros at compile time to override the package. The SDK does not inspect Git, environment variables, or firmware metadata. Missing or incomplete metadata defaults to 0.0.0, meaning an unknown SDK version. Its numeric macros are zero, so checks for newer releases are false.

 [`espectre`](#namespaceespectre)



<a id="espectre__sdk__version_8h_1a1c56ebb77dae087ea795df71afe1b36a"></a>

### `ESPECTRE_SDK_VERSION_MAJOR`


```cpp
#define ESPECTRE_SDK_VERSION_MAJOR 3
```

   

<a id="espectre__sdk__version_8h_1ab49f9a44dcd3be82d3b3e742d9334c23"></a>

### `ESPECTRE_SDK_VERSION_MINOR`


```cpp
#define ESPECTRE_SDK_VERSION_MINOR 0
```

   

<a id="espectre__sdk__version_8h_1a74f3ae0b42f726bf3302abae42655339"></a>

### `ESPECTRE_SDK_VERSION_PATCH`


```cpp
#define ESPECTRE_SDK_VERSION_PATCH 0
```

   

<a id="espectre__sdk__version_8h_1a63ca6448380d44c069980a49a9584c74"></a>

### `ESPECTRE_SDK_VERSION_STRING`


```cpp
#define ESPECTRE_SDK_VERSION_STRING "3.0.0-rc2-7-ga75f4d1.develop"
```

   

<a id="espectre__sdk__version_8h_1addabd247bcb8243d35a37657c029571b"></a>

### `ESPECTRE_SDK_VERSION_NUMBER`


```cpp
#define ESPECTRE_SDK_VERSION_NUMBER ((ESPECTRE_SDK_VERSION_MAJOR * 10000) + (ESPECTRE_SDK_VERSION_MINOR * 100) + ESPECTRE_SDK_VERSION_PATCH)
```

 

Legacy packed numeric identity for the SDK version, as `MMmmpp`.

  

Example: `3.0.0` becomes `30000`. Retained for compatibility and compact telemetry; do not use it for ordering because components are not limited to two digits. Use [`ESPECTRE_SDK_VERSION_AT_LEAST()`](#espectre__sdk__version_8h_1a84f438434c7a7b020e175e84ae3ca6e8) for feature guards.

  

<a id="espectre__sdk__version_8h_1a84f438434c7a7b020e175e84ae3ca6e8"></a>

### `ESPECTRE_SDK_VERSION_AT_LEAST`


```cpp
#define ESPECTRE_SDK_VERSION_AT_LEAST(major, minor, patch) ((ESPECTRE_SDK_VERSION_MAJOR > (major)) ||                               \
 (ESPECTRE_SDK_VERSION_MAJOR == (major) &&                              \
  (ESPECTRE_SDK_VERSION_MINOR > (minor) ||                              \
   (ESPECTRE_SDK_VERSION_MINOR == (minor) &&                            \
    ESPECTRE_SDK_VERSION_PATCH >= (patch)))))
```

 

Compile-time feature guard.

  

Use it to keep one integration compiling against several SDK releases: 

```cpp
#if ESPECTRE_SDK_VERSION_AT_LEAST(3, 1, 0)
  controller.set_motion_hits_runtime(3, 5);
#endif
```

  


<a id="espectre__services__sdk_8h"></a>

## espectre\_services\_sdk.h



```cpp
#include <espectre_sdk.h>
```



```cpp
#include <runtime/esp_idf/device_config_store.h>
```



```cpp
#include <runtime/esp_idf/direct_http_service_esp_idf.h>
```



```cpp
#include <runtime/esp_idf/direct_wifi_snapshot_esp_idf.h>
```



```cpp
#include <runtime/esp_idf/frontend_bootstrap_helpers.h>
```



```cpp
#include <runtime/esp_idf/frontend_ha_mqtt_helpers.h>
```



```cpp
#include <runtime/esp_idf/frontend_mqtt_helpers.h>
```



```cpp
#include <runtime/esp_idf/mdns_bootstrap_responder.h>
```



```cpp
#include <runtime/esp_idf/mdns_discovery_service.h>
```



```cpp
#include <runtime/esp_idf/nvs_helpers.h>
```



```cpp
#include <runtime/esp_idf/peer_discovery_service_esp_idf.h>
```



```cpp
#include <runtime/esp_idf/raw_csi_session_controller.h>
```



```cpp
#include <runtime/esp_idf/runtime_direct_http_bridge.h>
```



```cpp
#include <runtime/esp_idf/standalone_wifi_service.h>
```



```cpp
#include <runtime/esp_idf/task_scheduling_config.h>
```



```cpp
#include <runtime/esp_idf/traffic_generator_manager.h>
```



```cpp
#include <runtime/esp_idf/wifi_band_helpers.h>
```



```cpp
#include <runtime/esp_idf/wifi_bssid_pin_service.h>
```



```cpp
#include <runtime/esp_idf/wifi_provisioning_service.h>
```



```cpp
#include <runtime/esp_idf/wifi_tx_rate.h>
```



```cpp
#include <runtime/espectre_banner.h>
```



```cpp
#include <runtime/frontend_command_engine.h>
```



```cpp
#include <runtime/peer_discovery.h>
```



```cpp
#include <runtime/pending_event.h>
```



```cpp
#include <runtime/pending_queue.h>
```



```cpp
#include <runtime/runtime_event_mailbox.h>
```



```cpp
#include <runtime/runtime_time.h>
```

 

Optional services for firmware integrating the ESPectre runtime.

  

Includes the sensing SDK and the supported command, transport, discovery, provisioning, and bootstrap services. Compile only the capability source groups that your firmware uses; including this facade does not enable them. Requires the ESP-IDF platform headers and declared component dependencies. Firmware retains ownership of networking, service lifetime, and task policy. Concrete service objects retain their existing caller-owned allocation model.

 

<a id="filter__config_8h"></a>

## filter\_config.h



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)



<a id="frontend__bootstrap__helpers_8h"></a>

## frontend\_bootstrap\_helpers.h



```cpp
#include <cstdint>
```



```cpp
#include <device_identity.h>
```



```cpp
#include <esp_err.h>
```



```cpp
#include <espectre_protocol.h>
```



```cpp
#include <standalone_wifi_service.h>
```



```cpp
#include <wifi_provisioning_service.h>
```

  [`espectre::FrontendDeviceConfigDefaults`](#structespectre_1_1_frontend_device_config_defaults)

[`espectre::FrontendWifiStationOptions`](#structespectre_1_1_frontend_wifi_station_options)

[`espectre`](#namespaceespectre)



<a id="frontend__command__engine_8h"></a>

## frontend\_command\_engine.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <espectre_protocol.h>
```



```cpp
#include <runtime_config_utils.h>
```

  [`espectre::DeviceConfigCommandResult`](#structespectre_1_1_device_config_command_result)

[`espectre::FrontendCommandContext`](#structespectre_1_1_frontend_command_context)

[`espectre::FrontendCommandResult`](#structespectre_1_1_frontend_command_result)

[`espectre::FrontendCommandEngine`](#classespectre_1_1_frontend_command_engine)

[`espectre`](#namespaceespectre)



<a id="frontend__ha__mqtt__helpers_8h"></a>

## frontend\_ha\_mqtt\_helpers.h



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <espectre_protocol.h>
```

  [`espectre::FrontendHaDiagnosticSensor`](#structespectre_1_1_frontend_ha_diagnostic_sensor)

[`espectre::FrontendHaMqttSettings`](#structespectre_1_1_frontend_ha_mqtt_settings)

[`espectre::FrontendHaDiscoveryMessage`](#structespectre_1_1_frontend_ha_discovery_message)

[`espectre`](#namespaceespectre)



<a id="frontend__mqtt__helpers_8h"></a>

## frontend\_mqtt\_helpers.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <frontend_command_engine.h>
```



```cpp
#include <mqtt_transport.h>
```

  [`espectre`](#namespaceespectre)



<a id="high__accuracy__detector_8h"></a>

## high\_accuracy\_detector.h



```cpp
#include <base_detector.h>
```



```cpp
#include <csi_format.h>
```



```cpp
#include <csi_features.h>
```



```cpp
#include <filtered_turbulence_ring.h>
```



```cpp
#include <l1_delta_tracker.h>
```



```cpp
#include <ml_feature_trackers.h>
```



```cpp
#include <cstdint>
```



```cpp
#include <cstddef>
```

  [`espectre::HighAccuracyDetector`](#classespectre_1_1_high_accuracy_detector)

[`espectre`](#namespaceespectre)



<a id="lightweight__detector_8h"></a>

## lightweight\_detector.h



```cpp
#include <base_detector.h>
```



```cpp
#include <csi_format.h>
```



```cpp
#include <csi_features.h>
```



```cpp
#include <filtered_turbulence_ring.h>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <memory>
```

  [`espectre::LightweightDetector`](#classespectre_1_1_lightweight_detector)

[`espectre`](#namespaceespectre)



<a id="mdns__bootstrap__responder_8h"></a>

## mdns\_bootstrap\_responder.h



```cpp
#include <array>
```



```cpp
#include <atomic>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```

  [`espectre::MdnsBootstrapResponder`](#classespectre_1_1_mdns_bootstrap_responder)

[`espectre`](#namespaceespectre)



<a id="mdns__discovery__service_8h"></a>

## mdns\_discovery\_service.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <utility>
```



```cpp
#include <vector>
```

  [`espectre::MdnsDiscoveryServiceConfig`](#structespectre_1_1_mdns_discovery_service_config)

[`espectre::MdnsDiscoveryService`](#classespectre_1_1_mdns_discovery_service)

[`espectre`](#namespaceespectre)



<a id="mqtt__payload__assembler_8h"></a>

## mqtt\_payload\_assembler.h



```cpp
#include <array>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstring>
```



```cpp
#include <string_view>
```



```cpp
#include <espectre_protocol.h>
```

  [`espectre::MqttPayloadAssembler`](#classespectre_1_1_mqtt_payload_assembler)

[`espectre`](#namespaceespectre)



<a id="mqtt__transport_8h"></a>

## mqtt\_transport.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <espectre_protocol.h>
```

  [`espectre::MqttTransportDiagnostics`](#structespectre_1_1_mqtt_transport_diagnostics)

[`espectre::IMqttTransport`](#classespectre_1_1_i_mqtt_transport)

[`espectre`](#namespaceespectre)



<a id="mqtt__transport__esp__idf_8h"></a>

## mqtt\_transport\_esp\_idf.h



```cpp
#include <array>
```



```cpp
#include <atomic>
```



```cpp
#include <deque>
```



```cpp
#include <memory>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <mqtt_transport.h>
```



```cpp
#include <mqtt_payload_assembler.h>
```



```cpp
#include <pending_event.h>
```



```cpp
#include <pending_queue.h>
```



```cpp
#include <mqtt_client.h>
```

  [`espectre::EspIdfMqttTransport`](#classespectre_1_1_esp_idf_mqtt_transport)

[`espectre`](#namespaceespectre)



<a id="nvs__helpers_8h"></a>

## nvs\_helpers.h



```cpp
#include <esp_err.h>
```

  [`espectre`](#namespaceespectre)



<a id="peer__discovery_8h"></a>

## peer\_discovery.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```

  [`espectre::PeerDiscoveryCandidate`](#structespectre_1_1_peer_discovery_candidate)

[`espectre::PeerDiscoverySnapshot`](#structespectre_1_1_peer_discovery_snapshot)

[`espectre::IPeerDiscoveryService`](#classespectre_1_1_i_peer_discovery_service)

[`espectre`](#namespaceespectre)



<a id="peer__discovery__service__esp__idf_8h"></a>

## peer\_discovery\_service\_esp\_idf.h



```cpp
#include <peer_discovery.h>
```

  [`espectre::EspIdfPeerDiscoveryService`](#classespectre_1_1_esp_idf_peer_discovery_service)

[`espectre`](#namespaceespectre)



<a id="peer__discovery__service__esp__idf_8h_1a117010e231eeb226e391046f9eb7d2b5"></a>

### `mdns_result_t`


```cpp
typedef struct mdns_result_s mdns_result_t
```

   

<a id="peer__discovery__service__esp__idf_8h_1a8815240672c5880e798ca6655309c589"></a>

### `mdns_search_once_t`


```cpp
typedef struct mdns_search_once_s mdns_search_once_t
```

   


<a id="pending__event_8h"></a>

## pending\_event.h



```cpp
#include <cstddef>
```



```cpp
#include <mutex>
```



```cpp
#include <freertos/FreeRTOS.h>
```



```cpp
#include <freertos/portmacro.h>
```



```cpp
#include <tuple>
```



```cpp
#include <utility>
```

  [`espectre::detail::PendingEventLock`](#classespectre_1_1detail_1_1_pending_event_lock)

[`espectre::PendingEvent`](#classespectre_1_1_pending_event)

[`espectre`](#namespaceespectre)

[`espectre::detail`](#namespaceespectre_1_1detail)



<a id="pending__queue_8h"></a>

## pending\_queue.h



```cpp
#include <array>
```



```cpp
#include <cstddef>
```



```cpp
#include <mutex>
```



```cpp
#include <type_traits>
```



```cpp
#include <pending_event.h>
```

  [`espectre::PendingQueue`](#classespectre_1_1_pending_queue)

[`espectre`](#namespaceespectre)



<a id="protocol__json_8h"></a>

## protocol\_json.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <utility>
```



```cpp
#include <vector>
```

  [`espectre::JsonObjectField`](#structespectre_1_1_json_object_field)

[`espectre`](#namespaceespectre)



<a id="raw__csi_8h"></a>

## raw\_csi.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <csi_raw_record.h>
```

  [`espectre::RawCsiPacketView`](#structespectre_1_1_raw_csi_packet_view)

[`espectre::RawCsiHttpFramePrefix`](#structespectre_1_1_raw_csi_http_frame_prefix)

[`espectre::RawCsiSessionConfig`](#structespectre_1_1_raw_csi_session_config)

[`espectre::RawCsiSessionDiagnostics`](#structespectre_1_1_raw_csi_session_diagnostics)

[`espectre`](#namespaceespectre)



<a id="raw__csi__session__controller_8h"></a>

## raw\_csi\_session\_controller.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <direct_http_service.h>
```



```cpp
#include <frontend_command_engine.h>
```



```cpp
#include <runtime_frontend_controller.h>
```

  [`espectre::RawCsiSessionController`](#classespectre_1_1_raw_csi_session_controller)

[`espectre`](#namespaceespectre)



<a id="runtime__capabilities_8h"></a>

## runtime\_capabilities.h

  [`espectre::RuntimeCapabilities`](#structespectre_1_1_runtime_capabilities)

[`espectre`](#namespaceespectre)



<a id="runtime__config__utils_8h"></a>

## runtime\_config\_utils.h



```cpp
#include <runtime_interface.h>
```

  [`espectre`](#namespaceespectre)



<a id="runtime__diagnostics_8h"></a>

## runtime\_diagnostics.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <runtime_interface.h>
```



```cpp
#include <runtime_snapshot.h>
```

  [`espectre::RuntimeDiagnosticsSample`](#structespectre_1_1_runtime_diagnostics_sample)

[`espectre::RuntimeDiagnosticsSampler`](#classespectre_1_1_runtime_diagnostics_sampler)

[`espectre`](#namespaceespectre)



<a id="runtime__direct__http__bridge_8h"></a>

## runtime\_direct\_http\_bridge.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <direct_http_service.h>
```



```cpp
#include <direct_wifi_snapshot_esp_idf.h>
```



```cpp
#include <frontend_command_engine.h>
```



```cpp
#include <peer_discovery.h>
```



```cpp
#include <raw_csi_session_controller.h>
```



```cpp
#include <runtime_diagnostics.h>
```



```cpp
#include <runtime_event_mailbox.h>
```



```cpp
#include <runtime_frontend_controller.h>
```



```cpp
#include <atomic>
```

  [`espectre::RuntimeDirectHttpBridgeConfig`](#structespectre_1_1_runtime_direct_http_bridge_config)

[`espectre::RuntimeDirectHttpBridge`](#classespectre_1_1_runtime_direct_http_bridge)

[`espectre`](#namespaceespectre)



<a id="runtime__event__mailbox_8h"></a>

## runtime\_event\_mailbox.h



```cpp
#include <array>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <mutex>
```



```cpp
#include <type_traits>
```



```cpp
#include <freertos/FreeRTOS.h>
```



```cpp
#include <freertos/portmacro.h>
```



```cpp
#include <runtime_snapshot.h>
```

  [`espectre::RuntimeEventMailbox`](#classespectre_1_1_runtime_event_mailbox)

[`espectre`](#namespaceespectre)



<a id="runtime__events_8h"></a>

## runtime\_events.h



```cpp
#include <cstdint>
```



```cpp
#include <runtime_snapshot.h>
```

  [`espectre::IRuntimeListener`](#classespectre_1_1_i_runtime_listener)

[`espectre`](#namespaceespectre)



<a id="runtime__frontend__controller_8h"></a>

## runtime\_frontend\_controller.h



```cpp
#include <memory>
```



```cpp
#include <runtime_capabilities.h>
```



```cpp
#include <runtime_events.h>
```



```cpp
#include <runtime_interface.h>
```



```cpp
#include <runtime_snapshot.h>
```

  [`espectre::RuntimeFrontendController`](#classespectre_1_1_runtime_frontend_controller)

[`espectre`](#namespaceespectre)



<a id="runtime__interface_8h"></a>

## runtime\_interface.h



```cpp
#include <cstdint>
```



```cpp
#include <string>
```



```cpp
#include <runtime_capabilities.h>
```



```cpp
#include <runtime_events.h>
```



```cpp
#include <runtime_snapshot.h>
```



```cpp
#include <runtime_sensing_schema.h>
```



```cpp
#include <csi_traffic_types.h>
```



```cpp
#include <raw_csi.h>
```

 

Runtime configuration and the backend contract behind it.

  

Most integrations do not implement `IEspectreRuntime`; they configure a `RuntimeConfig`, hand it to `RuntimeFrontendController`, and let the controller pick the backend. Implement the interface only when you are replacing the ESP-IDF backend, for example in a simulator or a host harness.

 [`espectre::RuntimeConfig`](#structespectre_1_1_runtime_config)

[`espectre::IEspectreRuntime`](#classespectre_1_1_i_espectre_runtime)

[`espectre`](#namespaceespectre)



<a id="runtime__sensing__kconfig_8h"></a>

## runtime\_sensing\_kconfig.h



```cpp
#include <runtime_interface.h>
```

  [`espectre`](#namespaceespectre)



<a id="runtime__sensing__schema_8h"></a>

## runtime\_sensing\_schema.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <detector_limits.h>
```



```cpp
#include <detector_types.h>
```



```cpp
#include <csi_traffic_types.h>
```



```cpp
#include <filter_config.h>
```

 

The schema behind `RuntimeConfig`: enums, defaults, and valid ranges.

  

This is the single source of truth for what a sensing configuration may contain. Every tunable is declared as a `RUNTIME_<FIELD>_DEFAULT` plus, where a range applies, `_MIN` and `_MAX`. Read them instead of hardcoding limits, so a UI, a provisioning flow, or a config parser stays correct across SDK releases.

 

The `static_assert` block at the end holds these values in lockstep with the detector and filter constants they mirror, so a drift between the runtime schema and `core/` fails the build rather than the device.

 [`espectre`](#namespaceespectre)



<a id="runtime__snapshot_8h"></a>

## runtime\_snapshot.h



```cpp
#include <cstdint>
```



```cpp
#include <csi_capture_profile.h>
```



```cpp
#include <csi_types.h>
```



```cpp
#include <detector_types.h>
```



```cpp
#include <runtime_sensing_schema.h>
```

  [`espectre::RuntimeDiagnosticsSnapshot`](#structespectre_1_1_runtime_diagnostics_snapshot)

[`espectre::RuntimeSnapshot`](#structespectre_1_1_runtime_snapshot)

[`espectre`](#namespaceespectre)



<a id="runtime__time_8h"></a>

## runtime\_time.h



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)



<a id="standalone__wifi__service_8h"></a>

## standalone\_wifi\_service.h



```cpp
#include <atomic>
```



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <vector>
```



```cpp
#include <esp_err.h>
```



```cpp
#include <esp_event.h>
```



```cpp
#include <pending_queue.h>
```



```cpp
#include <wifi_lifecycle.h>
```

  [`espectre::StandaloneWifiAccessPoint`](#structespectre_1_1_standalone_wifi_access_point)

[`espectre::StandaloneWifiConfig`](#structespectre_1_1_standalone_wifi_config)

[`espectre::StandaloneWifiInfo`](#structespectre_1_1_standalone_wifi_info)

[`espectre::StandaloneWifiService`](#classespectre_1_1_standalone_wifi_service)

[`espectre`](#namespaceespectre)



<a id="task__scheduling__config_8h"></a>

## task\_scheduling\_config.h



```cpp
#include <cstdint>
```

  [`espectre`](#namespaceespectre)

[`espectre::task_scheduling`](#namespaceespectre_1_1task__scheduling)



<a id="task__scheduling__config_8h_1a1c07ae2423b6566d454316bfd9a8dcfa"></a>

### `CONFIG_ESPECTRE_DIRECT_HTTPD_TASK_PRIORITY`


```cpp
#define CONFIG_ESPECTRE_DIRECT_HTTPD_TASK_PRIORITY 1
```

   

<a id="task__scheduling__config_8h_1ab21ce3fdcc4837c2a0aecb8b3b58ca04"></a>

### `CONFIG_ESPECTRE_DIRECT_WORKER_TASK_PRIORITY`


```cpp
#define CONFIG_ESPECTRE_DIRECT_WORKER_TASK_PRIORITY 2
```

   

<a id="task__scheduling__config_8h_1ac541f938b4a9aee9eb3e7edc08296acd"></a>

### `CONFIG_ESPECTRE_RAW_WORKER_TASK_PRIORITY`


```cpp
#define CONFIG_ESPECTRE_RAW_WORKER_TASK_PRIORITY 3
```

   

<a id="task__scheduling__config_8h_1a89bc52af94882fc610139f6ac25a80c8"></a>

### `CONFIG_ESPECTRE_TRAFFIC_TASK_PRIORITY`


```cpp
#define CONFIG_ESPECTRE_TRAFFIC_TASK_PRIORITY 1
```

   

<a id="task__scheduling__config_8h_1a65ef855cbf111fd59288804c825dac19"></a>

### `CONFIG_ESPECTRE_NATIVE_LOOP_TASK_PRIORITY`


```cpp
#define CONFIG_ESPECTRE_NATIVE_LOOP_TASK_PRIORITY 5
```

   


<a id="temporal__csi__sampler_8h"></a>

## temporal\_csi\_sampler.h



```cpp
#include <cstdint>
```



```cpp
#include <memory>
```

  [`espectre::TemporalCsiSampler`](#classespectre_1_1_temporal_csi_sampler)

[`espectre`](#namespaceespectre)



<a id="traffic__generator__manager_8h"></a>

## traffic\_generator\_manager.h



```cpp
#include <atomic>
```



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```



```cpp
#include <sys/types.h>
```



```cpp
#include <freertos/FreeRTOS.h>
```



```cpp
#include <freertos/task.h>
```



```cpp
#include <csi_traffic_service.h>
```

 

ESP-IDF managed traffic for firmware that owns its CSI capture path.

  

Link ESPECTRE\_RUNTIME\_ESP\_IDF\_TRAFFIC\_SOURCES and its ESP-IDF dependencies. The firmware owns the object and calls stop() before destroying it or tearing down Wi-Fi. Call lifecycle and control methods from one owner task.

 [`espectre::TrafficGeneratorManager`](#classespectre_1_1_traffic_generator_manager)

[`espectre`](#namespaceespectre)



<a id="udp__datagram__socket_8h"></a>

## udp\_datagram\_socket.h



```cpp
#include <cstddef>
```



```cpp
#include <cstdint>
```

  [`espectre::UdpDatagramPeer`](#structespectre_1_1_udp_datagram_peer)

[`espectre::IUdpDatagramSocket`](#classespectre_1_1_i_udp_datagram_socket)

[`espectre`](#namespaceespectre)



<a id="wifi__band__helpers_8h"></a>

## wifi\_band\_helpers.h



```cpp
#include <sdkconfig.h>
```



```cpp
#include <runtime_interface.h>
```

  [`espectre`](#namespaceespectre)



<a id="wifi__band__helpers_8h_1ae6a8d194706e2fb61b9b2eca0485388e"></a>

### `ESPECTRE_WIFI_DUAL_BAND`


```cpp
#define ESPECTRE_WIFI_DUAL_BAND 0
```

   


<a id="wifi__bssid__pin__service_8h"></a>

## wifi\_bssid\_pin\_service.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <esp_err.h>
```

  [`espectre::WifiBssidPinStationState`](#structespectre_1_1_wifi_bssid_pin_station_state)

[`espectre::WifiBssidPinServiceConfig`](#structespectre_1_1_wifi_bssid_pin_service_config)

[`espectre::WifiBssidPinService`](#classespectre_1_1_wifi_bssid_pin_service)

[`espectre`](#namespaceespectre)



<a id="wifi__lifecycle_8h"></a>

## wifi\_lifecycle.h



```cpp
#include <atomic>
```



```cpp
#include <cstdint>
```



```cpp
#include <esp_event.h>
```



```cpp
#include <esp_err.h>
```



```cpp
#include <esp_netif.h>
```



```cpp
#include <esp_wifi.h>
```



```cpp
#include <functional>
```



```cpp
#include <pending_queue.h>
```



```cpp
#include <runtime_interface.h>
```

  [`espectre::WiFiLifecycleManager`](#classespectre_1_1_wi_fi_lifecycle_manager)

[`espectre`](#namespaceespectre)



<a id="wifi__provisioning__service_8h"></a>

## wifi\_provisioning\_service.h



```cpp
#include <cstdint>
```



```cpp
#include <functional>
```



```cpp
#include <string>
```



```cpp
#include <device_config_store.h>
```



```cpp
#include <esp_err.h>
```



```cpp
#include <standalone_wifi_service.h>
```

  [`espectre::WifiProvisioningDefaults`](#structespectre_1_1_wifi_provisioning_defaults)

[`espectre::WifiProvisioningService`](#classespectre_1_1_wifi_provisioning_service)

[`espectre`](#namespaceespectre)



<a id="wifi__tx__rate_8h"></a>

## wifi\_tx\_rate.h



```cpp
#include <sdkconfig.h>
```



```cpp
#include <esp_wifi.h>
```



```cpp
#include <espectre_log.h>
```



```cpp
#include <string_view>
```



```cpp
#include <esp_private/wifi.h>
```

 

Shared ESP-IDF station and raw-frame transmit-rate policy.

  

Apply the station policy after association, including reassociation, before starting CSI. The CONFIG\_ESPECTRE\_WIFI\_TX\_RATE\_MBPS build setting selects Auto, OFDM 6 Mbps, or HT20 MCS0 with long GI. Driver errors reach the caller.

 [`espectre`](#namespaceespectre)



<a id="wifi__tx__rate_8h_1a4ab79b73a3924c057a08e1aaef07f748"></a>

### `CONFIG_ESPECTRE_WIFI_TX_RATE_MBPS`


```cpp
#define CONFIG_ESPECTRE_WIFI_TX_RATE_MBPS "0"
```

Links

Maintainer

  • Francesco Pace <francesco.pace@espectre.dev>
To add this component to your project, run:

idf.py add-dependency "francescopace/espectre^3.0.0-rc2-7-ga75f4d1.develop"

download archive

Stats

  • Archive size
    Archive size ~ 476.59 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

francescopace/espectre version: 3.0.0-rc2-7-ga75f4d1.develop
|