254 lines
9.0 KiB
C
254 lines
9.0 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include "esp_err.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef enum {
|
|
CONTROL_PLANE_DIRECTION_CMD_UNKNOWN = 0,
|
|
CONTROL_PLANE_DIRECTION_CMD_HELP,
|
|
CONTROL_PLANE_DIRECTION_CMD_POSITION,
|
|
CONTROL_PLANE_DIRECTION_CMD_DIRECTION,
|
|
CONTROL_PLANE_DIRECTION_CMD_CALIBRATE
|
|
} control_plane_direction_command_t;
|
|
|
|
typedef enum {
|
|
CONTROL_PLANE_MODEL_COMMAND_UNKNOWN = 0,
|
|
CONTROL_PLANE_MODEL_COMMAND_DIRECTION,
|
|
CONTROL_PLANE_MODEL_COMMAND_CALIBRATE,
|
|
CONTROL_PLANE_MODEL_COMMAND_CHOUQIAN
|
|
} control_plane_model_command_type_t;
|
|
|
|
typedef void (*control_plane_model_command_callback_t)(
|
|
control_plane_model_command_type_t command_type,
|
|
const char *value,
|
|
size_t value_index,
|
|
bool value_index_valid,
|
|
void *user_data);
|
|
|
|
typedef enum {
|
|
CONTROL_PLANE_MULTIMODAL_RESPOND_TYPE_TRANSCRIPT = 0,
|
|
CONTROL_PLANE_MULTIMODAL_RESPOND_TYPE_PROMPT,
|
|
} control_plane_multimodal_respond_type_t;
|
|
|
|
typedef struct {
|
|
control_plane_multimodal_respond_type_t type;
|
|
const char *text;
|
|
/*
|
|
* Optional JSON object serialized as payload.parameters for
|
|
* RequestToRespond. Use this for documented fields such as images and
|
|
* biz_params. NULL or empty means no parameters object is sent.
|
|
*/
|
|
const char *parameters_json;
|
|
} control_plane_multimodal_respond_request_t;
|
|
|
|
typedef struct {
|
|
/*
|
|
* JSON object serialized as payload.parameters for UpdateInfo. Expected
|
|
* fields follow docs/websocket.md: images, client_info, and biz_params.
|
|
*/
|
|
const char *parameters_json;
|
|
} control_plane_multimodal_update_info_request_t;
|
|
|
|
esp_err_t control_plane_init(void);
|
|
|
|
/**
|
|
* @brief Prepare platform-backed persistent storage before runtime workers start.
|
|
*
|
|
* This is idempotent and has no Wi-Fi or actuator side effects. It exists so the
|
|
* composition layer can start non-blocking workers before connectivity bootstrap
|
|
* without racing NVS-backed stores.
|
|
*/
|
|
esp_err_t control_plane_prepare_runtime_storage(void);
|
|
|
|
/**
|
|
* @brief Parse one direction command without side effects.
|
|
*
|
|
* Initialization contract:
|
|
* - `control_plane_init()` must be called explicitly first.
|
|
* - No implicit lazy initialization is performed by query/parse APIs.
|
|
* - Returns `CONTROL_PLANE_DIRECTION_CMD_UNKNOWN` when uninitialized.
|
|
*/
|
|
control_plane_direction_command_t control_plane_parse_direction_command(const char *input,
|
|
size_t *out_direction_index);
|
|
esp_err_t control_plane_rotate_to_angle(float target_angle);
|
|
esp_err_t control_plane_rotate_to_direction(size_t direction_index);
|
|
|
|
/**
|
|
* @brief Parse and execute one direction command line.
|
|
*
|
|
* Execution policy:
|
|
* - `DIRECTION`: perform rotation to parsed target direction.
|
|
* - `CALIBRATE`: run calibration with default timeout policy.
|
|
* - `HELP`/`POSITION`/`UNKNOWN`: parse only, no actuator side effects.
|
|
*
|
|
* Returns:
|
|
* - `ESP_OK` for non-action commands or successful action commands.
|
|
* - Error from action executor for failing `DIRECTION`/`CALIBRATE`.
|
|
*/
|
|
esp_err_t control_plane_execute_direction_command(const char *input,
|
|
control_plane_direction_command_t *out_command,
|
|
size_t *out_direction_index);
|
|
|
|
/**
|
|
* @brief Run calibration with explicit timeout budget.
|
|
*
|
|
* Semantics:
|
|
* - `timeout_ms <= 0`: use internal default timeout.
|
|
* - Returns `ESP_ERR_TIMEOUT` when calibration cannot finish in time.
|
|
* - If calibration switch is already active at entry, implementation may
|
|
* perform a bounded release-and-rehome sequence before setting the
|
|
* calibrated angle.
|
|
*/
|
|
esp_err_t control_plane_calibrate_with_timeout(int timeout_ms);
|
|
esp_err_t control_plane_calibrate(void);
|
|
|
|
/**
|
|
* @brief Bootstrap Wi-Fi connectivity for runtime.
|
|
*
|
|
* Semantics:
|
|
* - `connect_timeout_ms <= 0`: apply internal default timeout.
|
|
* - Operation is safe to call repeatedly; existing good state is reused when possible.
|
|
* - Returns `ESP_OK` when STA is connected or a fallback provisioning path is started.
|
|
* - On timeout/failure, function returns explicit error and does not continue hidden
|
|
* destructive retries after return.
|
|
*/
|
|
esp_err_t control_plane_bootstrap_connectivity(const char *seed_ssid,
|
|
const char *seed_password,
|
|
int connect_timeout_ms,
|
|
const char *config_ap_ssid_prefix);
|
|
bool control_plane_is_sta_connected(void);
|
|
|
|
/**
|
|
* @brief Execute the Plan A boot sound policy with bounded caller semantics.
|
|
*
|
|
* The current platform voice-prompt backend may return ESP_ERR_NOT_SUPPORTED;
|
|
* callers should log and continue boot in that case.
|
|
*/
|
|
esp_err_t control_plane_play_boot_sound(int timeout_ms);
|
|
|
|
/**
|
|
* @brief Start multimodal client runtime.
|
|
*
|
|
* Semantics:
|
|
* - Idempotent for repeated calls when runtime is already active.
|
|
* - Creates/starts required background tasks with bounded startup behavior.
|
|
* - Returns explicit error when startup cannot complete.
|
|
*/
|
|
esp_err_t control_plane_start_multimodal_client(void);
|
|
|
|
/**
|
|
* @brief Stop multimodal client runtime and owned background tasks.
|
|
*
|
|
* Semantics:
|
|
* - Idempotent and safe to call repeatedly.
|
|
* - Requests cooperative stop first, then applies bounded waits for worker teardown.
|
|
*/
|
|
void control_plane_stop_multimodal_client(void);
|
|
|
|
esp_err_t control_plane_register_model_command_callback(control_plane_model_command_callback_t cb,
|
|
void *user_data);
|
|
|
|
/**
|
|
* @brief Cancel an active push2talk speech input.
|
|
*
|
|
* Sends the protocol `CancelSpeech` directive for the active multimodal task
|
|
* and stops local uplink capture.
|
|
*/
|
|
esp_err_t control_plane_multimodal_cancel_speech(void);
|
|
|
|
/**
|
|
* @brief Ask the active multimodal session to respond to local text.
|
|
*
|
|
* Requires an active task in `DialogStateChanged(Listening)` state. The request
|
|
* is encoded as the documented `RequestToRespond` directive.
|
|
*/
|
|
esp_err_t control_plane_multimodal_request_to_respond(
|
|
const control_plane_multimodal_respond_request_t *request);
|
|
|
|
/**
|
|
* @brief Update per-session multimodal context.
|
|
*
|
|
* Encodes `request->parameters_json` as the documented UpdateInfo
|
|
* `payload.parameters` object.
|
|
*/
|
|
esp_err_t control_plane_multimodal_update_info(
|
|
const control_plane_multimodal_update_info_request_t *request);
|
|
|
|
/**
|
|
* @brief Start control-plane owned runtime workers.
|
|
*
|
|
* This includes model-command dispatch worker and connectivity-gated multimodal startup worker.
|
|
* Safe to call repeatedly.
|
|
*/
|
|
esp_err_t control_plane_start_runtime_workers(void);
|
|
void control_plane_stop_runtime_workers(void);
|
|
|
|
/**
|
|
* @brief Start the staged event observer runtime only.
|
|
*
|
|
* This starts the system event dispatcher and key input observer so module
|
|
* events can be verified through logs. It intentionally does not start LCD,
|
|
* Wi-Fi, WebSocket, fortune, LAN HTTP, motor, or audio business workers.
|
|
*/
|
|
esp_err_t control_plane_start_event_observer_runtime(void);
|
|
void control_plane_stop_event_observer_runtime(void);
|
|
|
|
/**
|
|
* @brief Daily fortune policy (control_plane-owned).
|
|
*
|
|
* The daily fortune worker is started by `control_plane_start_runtime_workers()`
|
|
* when `CONFIG_FORTUNE_ENABLE` is set. It waits for STA connectivity and SNTP
|
|
* time, fetches the favorable-color and wealth-direction result for the local
|
|
* date, persists it, applies the direction, and reschedules for local 00:00.
|
|
*
|
|
* `control_plane_fortune_refresh_now()` requests an immediate refetch+apply
|
|
* (e.g. after provisioning, or for manual testing). Returns
|
|
* `ESP_ERR_INVALID_STATE` when the worker is not running and
|
|
* `ESP_ERR_NOT_SUPPORTED` when the feature is disabled at build time.
|
|
*/
|
|
esp_err_t control_plane_fortune_refresh_now(void);
|
|
|
|
esp_err_t control_plane_init_lcd_device(void);
|
|
esp_err_t control_plane_start_lcd_render_worker(void);
|
|
void control_plane_start_lcd_render_loop(void);
|
|
esp_err_t control_plane_request_boot_expression(void);
|
|
/**
|
|
* @brief Stop LCD render loop with bounded teardown.
|
|
*
|
|
* `timeout_ms < 0` is invalid, zero requests asynchronous stop, and positive
|
|
* values wait up to the bound before lower layers apply deterministic fallback.
|
|
*/
|
|
esp_err_t control_plane_stop_lcd_render_loop(int timeout_ms);
|
|
|
|
/**
|
|
* @brief Start the factory provisioning serial CLI on the console UART.
|
|
*
|
|
* Spawns a control-plane-owned worker that reads `\r\n`-delimited commands and
|
|
* replies with `OK` / `ERROR <reason>` / JSON lines. Idempotent (a no-op if
|
|
* already running). Used for device identity provisioning and reading/signing
|
|
* device-auth key material during manufacturing.
|
|
*/
|
|
esp_err_t control_plane_factory_cli_start(void);
|
|
|
|
/**
|
|
* @brief Stop the factory CLI worker (cooperative request + bounded teardown).
|
|
*
|
|
* Idempotent and safe to call repeatedly.
|
|
*/
|
|
void control_plane_factory_cli_stop(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|