docs: 补充核心分层中文注释
This commit is contained in:
@@ -15,6 +15,24 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Domain 层调用与所有权概览 / Domain call flow and ownership overview
|
||||
*
|
||||
* domain 是业务语义的唯一所有者:方向、校准、电池等级、配网协议、表情映射、
|
||||
* 用户资料、运势和 OTA 响应解析均在此定义。它只通过 platform facade 使用硬件原语,
|
||||
* 不把 platform 类型暴露给 control_plane。
|
||||
* Domain is the single owner of business semantics and consumes hardware only
|
||||
* through the platform facade without leaking platform types upward.
|
||||
*
|
||||
* control_plane -> domain facade -> domain service/adapter -> platform facade
|
||||
*
|
||||
* store/service 状态以 domain 内部快照或下层持久化为事实来源;回调携带的临时数据
|
||||
* 只在调用期间有效。阻塞接口的 timeout 包含锁等待和下层操作的完整调用方预算。
|
||||
* Stores and service snapshots are SSOTs. Callback payloads are temporary, and
|
||||
* blocking timeouts cover lock acquisition plus all lower-layer work.
|
||||
*/
|
||||
|
||||
/* 方向轴与校准策略属于 domain 语义,GPIO/步进相位等硬件细节不得进入这些结构。 */
|
||||
typedef struct {
|
||||
float initial_angle;
|
||||
int rotate_speed_us;
|
||||
@@ -29,6 +47,7 @@ typedef struct {
|
||||
int settle_delay_ms;
|
||||
} domain_direction_calibration_t;
|
||||
|
||||
/* 电池原始采样由 platform 提供,domain 负责充电、等级、有效性和抑制语义。 */
|
||||
typedef enum {
|
||||
DOMAIN_BATTERY_CHARGE_UNKNOWN = 0,
|
||||
DOMAIN_BATTERY_CHARGE_NOT_CHARGING,
|
||||
@@ -58,22 +77,22 @@ typedef struct {
|
||||
int64_t last_valid_sample_time_ms;
|
||||
} domain_battery_status_t;
|
||||
|
||||
/** Initialize the battery measurement domain. Idempotent and thread-safe. */
|
||||
/** 幂等且线程安全地初始化电池领域。 / Initialize the battery domain idempotently and thread-safely. */
|
||||
esp_err_t domain_battery_init(void);
|
||||
|
||||
/** Acquire and process one battery sample without applying product policy. */
|
||||
/** 获取并处理一次电池采样,不执行产品策略。 / Process one battery sample without product policy. */
|
||||
esp_err_t domain_battery_sample(void);
|
||||
|
||||
/** Copy the latest battery SSOT snapshot into `out_status`. */
|
||||
/** 复制最新电池 SSOT 快照。 / Copy the latest battery SSOT snapshot into `out_status`. */
|
||||
esp_err_t domain_battery_get_status(domain_battery_status_t *out_status);
|
||||
|
||||
/** Enter the configured board deep-sleep state; a successful call does not return. */
|
||||
/** 进入板级深睡,成功时不返回。 / Enter configured deep sleep; success does not return. */
|
||||
esp_err_t domain_battery_prepare_shutdown(void);
|
||||
|
||||
/** Return true when the current boot resumed through a deep-sleep wake source. */
|
||||
/** 当前启动来自深睡唤醒源时返回 true。 / Return true after a deep-sleep wake. */
|
||||
bool domain_battery_woke_from_deep_sleep(void);
|
||||
|
||||
/** Release low-power GPIO holds after accepting a deep-sleep wake. */
|
||||
/** 接受唤醒后释放低功耗 GPIO 保持。 / Release low-power GPIO holds after wake. */
|
||||
void domain_battery_complete_wakeup(void);
|
||||
|
||||
typedef enum {
|
||||
@@ -84,6 +103,7 @@ typedef enum {
|
||||
DOMAIN_WIFI_PROMPT_WIFI_CONFIG,
|
||||
} domain_wifi_prompt_id_t;
|
||||
|
||||
/* Wi-Fi 行为钩子使用 domain 提示语义,具体音频文件映射留在适配实现中。 */
|
||||
typedef struct {
|
||||
void (*set_keep_awake)(bool keep_awake);
|
||||
esp_err_t (*play_prompt)(domain_wifi_prompt_id_t prompt);
|
||||
@@ -98,6 +118,7 @@ typedef enum {
|
||||
DOMAIN_MULTIMODAL_TRANSPORT_EVENT_BINARY_MESSAGE,
|
||||
} domain_multimodal_transport_event_type_t;
|
||||
|
||||
/* 回调 payload 仅在回调期间有效;跨任务保存前必须复制。 */
|
||||
typedef struct {
|
||||
domain_multimodal_transport_event_type_t type;
|
||||
const uint8_t *data;
|
||||
@@ -202,6 +223,7 @@ typedef enum {
|
||||
DOMAIN_EXPRESSION_TRIGGER_FACTORY_LCD_TEST,
|
||||
} domain_expression_trigger_t;
|
||||
|
||||
/* 表情请求表达业务意图;资源目录、帧序列和图标位置由 domain 适配器映射。 */
|
||||
typedef struct {
|
||||
domain_expression_id_t id;
|
||||
domain_expression_trigger_t trigger;
|
||||
@@ -228,20 +250,22 @@ float domain_get_current_angle(void);
|
||||
void domain_set_current_angle(float angle);
|
||||
int domain_get_rotate_speed_us(void);
|
||||
/**
|
||||
* @brief Rotate to an absolute direction angle.
|
||||
* @brief 旋转到绝对方向角。 / Rotate to an absolute direction angle.
|
||||
*
|
||||
* 非正 timeout 使用 domain 默认值;预算覆盖状态锁获取和电机运动全过程。
|
||||
* `timeout_ms <= 0` uses the default domain timeout. The timeout is the total
|
||||
* caller-visible budget, including state-lock acquisition and motor movement.
|
||||
*/
|
||||
esp_err_t domain_rotate_to_angle_with_timeout(float target_angle, int timeout_ms);
|
||||
esp_err_t domain_apply_rotation_delta(float delta);
|
||||
/** Release stepper holding current; the next movement re-energizes automatically. */
|
||||
/** 释放电机保持电流,下次运动自动重新励磁。 / Release hold; next movement re-energizes. */
|
||||
esp_err_t domain_direction_release_motor_hold(int timeout_ms);
|
||||
void domain_set_calibration(const domain_direction_calibration_t *config);
|
||||
bool domain_get_calibration(domain_direction_calibration_t *out_config);
|
||||
/**
|
||||
* @brief Run direction calibration.
|
||||
* @brief 执行方向校准。 / Run direction calibration.
|
||||
*
|
||||
* 非正 timeout 使用默认校准预算,包含锁等待、分步运动、开关稳定等待和释放扫描。
|
||||
* `timeout_ms <= 0` uses the default calibration timeout. The timeout is the
|
||||
* total caller-visible budget, including state-lock acquisition, movement
|
||||
* steps, switch settle delays, and release sweep.
|
||||
@@ -254,8 +278,9 @@ esp_err_t domain_runtime_multimodal_transport_start(
|
||||
domain_multimodal_transport_event_callback_t cb,
|
||||
void *user_data);
|
||||
/**
|
||||
* @brief Stop the multimodal transport with bounded teardown.
|
||||
* @brief 有界停止多模态传输。 / Stop multimodal transport 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.
|
||||
*/
|
||||
@@ -272,7 +297,7 @@ esp_err_t domain_runtime_multimodal_audio_start_uplink(
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Stop multimodal uplink capture/stream with bounded teardown.
|
||||
* @brief 有界停止多模态上行采集和流发送。 / Stop uplink capture/stream 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.
|
||||
@@ -280,11 +305,12 @@ esp_err_t domain_runtime_multimodal_audio_start_uplink(
|
||||
esp_err_t domain_runtime_multimodal_audio_stop_uplink(int timeout_ms);
|
||||
bool domain_runtime_multimodal_audio_is_uplink_running(void);
|
||||
bool domain_runtime_multimodal_audio_is_initialized(void);
|
||||
/** Gate speaker output while preserving the microphone capture path. */
|
||||
/** 保留麦克风采集,仅控制扬声器输出。 / Gate speaker output while preserving capture. */
|
||||
esp_err_t domain_runtime_multimodal_audio_set_speaker_output_enabled(bool enabled);
|
||||
/**
|
||||
* @brief Start local MultiNet detection for the Chinese phrase "喵掌柜".
|
||||
* @brief 启动“喵掌柜”本地 MultiNet 检测。 / Start local MultiNet detection for "喵掌柜".
|
||||
*
|
||||
* 回调运行在 domain 推理任务中,必须有界且不可阻塞;相同回调的重复启动幂等。
|
||||
* The callback runs in the domain inference task and must be bounded and
|
||||
* non-blocking. Repeated start with the same callback is idempotent.
|
||||
*/
|
||||
@@ -326,8 +352,10 @@ typedef enum {
|
||||
} domain_runtime_auth_record_t;
|
||||
|
||||
/**
|
||||
* @brief Domain-owned device-auth persistence port, backed by platform blobs.
|
||||
* @brief domain 拥有、由 platform blob 支撑的设备认证持久化端口。
|
||||
* Domain-owned device-auth persistence port backed by platform blobs.
|
||||
*
|
||||
* domain 只拥有记录槽、存储键映射和旧版迁移边界;调用方拥有序列化 schema。
|
||||
* The domain facade owns only the auth record slots, storage key mapping, and
|
||||
* legacy migration boundary. Callers own the serialized record schema and pass
|
||||
* opaque bytes. `load_record` returns `ESP_ERR_NOT_FOUND` when no record exists
|
||||
@@ -342,10 +370,11 @@ esp_err_t domain_runtime_auth_store_save_record(domain_runtime_auth_record_t rec
|
||||
size_t len);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Daily fortune: user birth profile + server-computed daily result. */
|
||||
/* Owned by the domain layer; see docs/adr/0002-daily-fortune-contracts.md. */
|
||||
/* 每日运势:用户出生资料 + 服务端计算结果。 / Daily fortune profile + result. */
|
||||
/* 契约属于 domain;详见 docs/adr/0002-daily-fortune-contracts.md。 */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* 固定容量使资料可直接序列化进 NVS;长度包含结尾 NUL,修改需考虑旧记录兼容。 */
|
||||
#define DOMAIN_BIRTH_PLACE_MAX_LEN 64
|
||||
#define DOMAIN_BIRTH_RESIDENCE_MAX_LEN 64
|
||||
#define DOMAIN_BIRTH_MBTI_MAX_LEN 8
|
||||
@@ -364,6 +393,7 @@ typedef struct {
|
||||
bool valid;
|
||||
} domain_birth_profile_t;
|
||||
|
||||
/* 运势字段容量同时约束服务端 JSON 校验和持久化结构布局。 */
|
||||
#define DOMAIN_FORTUNE_BAZI_MAX_LEN 64
|
||||
#define DOMAIN_FORTUNE_ELEMENT_MAX_LEN 8
|
||||
#define DOMAIN_FORTUNE_DIRECTION_MAX_LEN 16
|
||||
@@ -382,8 +412,9 @@ typedef struct {
|
||||
typedef void (*domain_birth_profile_observer_t)(const domain_birth_profile_t *profile, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Persist / query the user birth profile (NVS-backed via the platform store).
|
||||
* @brief 持久化或查询用户出生资料。 / Persist or query the user birth profile.
|
||||
*
|
||||
* set 校验并持久化后在锁外通知观察者;get 在无有效记录时返回 false。存储是 SSOT。
|
||||
* `set` requires a valid profile, persists it, then notifies the registered
|
||||
* observer with a snapshot (invoked outside any lock). `get` returns false when
|
||||
* no valid profile has been stored. Storage is the single source of truth; no
|
||||
@@ -393,21 +424,25 @@ esp_err_t domain_birth_profile_store_set(const domain_birth_profile_t *profile);
|
||||
bool domain_birth_profile_store_get(domain_birth_profile_t *out_profile);
|
||||
|
||||
/**
|
||||
* @brief Persist / query the most recent daily fortune result.
|
||||
* @brief 持久化或查询最近一次每日运势。 / Persist or query the latest daily fortune result.
|
||||
*/
|
||||
esp_err_t domain_fortune_result_store_set(const domain_fortune_result_t *result);
|
||||
bool domain_fortune_result_store_get(domain_fortune_result_t *out_result);
|
||||
esp_err_t domain_fortune_result_store_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Register the single observer notified when a new birth profile is
|
||||
* stored (e.g. submitted over the LAN configuration page). Pass NULL to clear it. The
|
||||
* callback must be lightweight (it runs in the caller's context).
|
||||
* @brief 注册出生资料更新的唯一观察者。 / Register the single birth-profile observer.
|
||||
*
|
||||
* 新资料持久化后在调用方上下文通知,例如 LAN 配置页面提交;传 NULL 清除。
|
||||
* The callback runs in the caller's context after persistence and must be lightweight.
|
||||
*/
|
||||
void domain_runtime_register_birth_profile_observer(domain_birth_profile_observer_t cb, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Wall-clock time synchronization, bridged to the platform SNTP
|
||||
* @brief 桥接到 platform SNTP 的墙上时钟同步。 / Wall-clock synchronization.
|
||||
*
|
||||
* set_timezone 仅设置本地时间转换;start 幂等启动 SNTP 并应用时区;网络就绪后调用。
|
||||
* Bridged to the platform SNTP
|
||||
* primitive. `set_timezone` applies local-time conversion without
|
||||
* network access. `start` is idempotent and also applies the process
|
||||
* time zone (`posix_tz`, e.g. "CST-8"); `is_synced` reports whether the
|
||||
@@ -417,6 +452,7 @@ esp_err_t domain_runtime_time_set_timezone(const char *posix_tz);
|
||||
esp_err_t domain_runtime_time_sync_start(const char *sntp_server, const char *posix_tz);
|
||||
bool domain_runtime_time_is_synced(void);
|
||||
|
||||
/* mDNS 主机名按值复制到服务状态,容量包含结尾 NUL。 */
|
||||
#define DOMAIN_USER_CONFIG_HOSTNAME_MAX_LEN 32
|
||||
|
||||
typedef struct {
|
||||
@@ -431,8 +467,9 @@ typedef struct {
|
||||
} domain_user_config_server_state_t;
|
||||
|
||||
/**
|
||||
* @brief Start the domain-owned user profile and fortune web application.
|
||||
* @brief 启动 domain 拥有的资料与运势 Web 应用。 / Start the domain-owned user web app.
|
||||
*
|
||||
* platform 只提供有界 HTTP 传输;路由、JSON、校验和页面属于 domain;重复启动幂等。
|
||||
* The platform supplies only the bounded raw HTTP transport. This domain
|
||||
* service owns the routes, JSON semantics, validation, and embedded page.
|
||||
* Start is idempotent while the service is starting or running.
|
||||
@@ -441,7 +478,7 @@ esp_err_t domain_user_config_server_start(
|
||||
const domain_user_config_server_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Stop the user configuration server with bounded teardown.
|
||||
* @brief 有界停止用户配置服务。 / Stop the user configuration server with bounded teardown.
|
||||
*
|
||||
* `timeout_ms < 0` is invalid, zero requests asynchronous stop, and positive
|
||||
* values wait up to the bound before the platform applies deterministic
|
||||
@@ -452,8 +489,9 @@ esp_err_t domain_user_config_server_get_state(
|
||||
domain_user_config_server_state_t *out_state);
|
||||
|
||||
/**
|
||||
* @brief POST domain JSON data through the lower-layer HTTPS transport adapter.
|
||||
* @brief 通过下层 HTTPS 适配器 POST domain JSON。 / POST domain JSON via HTTPS adapter.
|
||||
*
|
||||
* 可选设备 ID 和 bearer token 被映射为请求头;响应写入调用方缓冲并以 NUL 结尾。
|
||||
* Optional `device_id` is sent as X-Device-Id and optional `bearer_token` is
|
||||
* sent as Authorization: Bearer <token>. The response body is written to the
|
||||
* caller-owned buffer and NUL-terminated on success. A completed HTTP exchange
|
||||
@@ -475,6 +513,7 @@ esp_err_t domain_runtime_post_json(const char *url,
|
||||
size_t *out_response_body_len,
|
||||
int *out_status);
|
||||
|
||||
/* OTA 固定容量是响应校验和任务间快照复制边界;SHA-256 为64位十六进制。 */
|
||||
#define DOMAIN_OTA_VERSION_MAX_LEN 32
|
||||
#define DOMAIN_OTA_URL_MAX_LEN 2048
|
||||
#define DOMAIN_OTA_SHA256_HEX_LEN 64
|
||||
@@ -534,7 +573,7 @@ esp_err_t domain_runtime_ota_get_memory_headroom(domain_ota_memory_headroom_t *o
|
||||
void domain_runtime_restart(void);
|
||||
|
||||
/**
|
||||
* @brief Console (UART) line-transport primitives, bridged to the platform.
|
||||
* @brief 桥接到 platform 的串口行传输原语。 / Console line transport bridged to platform.
|
||||
*
|
||||
* `read_bytes` returns bytes read (0 on timeout, <0 on error). A zero timeout
|
||||
* polls once; negative timeouts are invalid and return <0. Used by the factory
|
||||
@@ -551,6 +590,7 @@ void domain_runtime_wifi_portal_set_behavior_hooks(const domain_wifi_behavior_ho
|
||||
esp_err_t domain_runtime_wifi_portal_init_defaults(const char *seed_ssid, const char *seed_password);
|
||||
bool domain_runtime_wifi_portal_has_saved_credentials(void);
|
||||
|
||||
/* SSID 容量包含 NUL;最多保存10个候选,返回顺序即后续连接优先级。 */
|
||||
#define DOMAIN_WIFI_SSID_MAX_LEN 33
|
||||
#define DOMAIN_WIFI_SAVED_NETWORK_MAX_COUNT 10
|
||||
|
||||
@@ -559,7 +599,7 @@ typedef struct {
|
||||
char ssids[DOMAIN_WIFI_SAVED_NETWORK_MAX_COUNT][DOMAIN_WIFI_SSID_MAX_LEN];
|
||||
} domain_wifi_saved_networks_t;
|
||||
|
||||
/** Copy saved SSIDs in persistent priority order. Passwords are not exposed. */
|
||||
/** 按持久化优先级复制 SSID,不暴露密码。 / Copy saved SSIDs in priority order. */
|
||||
esp_err_t domain_runtime_wifi_portal_get_saved_networks(
|
||||
domain_wifi_saved_networks_t *out_networks);
|
||||
bool domain_runtime_wifi_portal_sta_is_connected(void);
|
||||
@@ -567,7 +607,9 @@ esp_err_t domain_runtime_wifi_portal_start_config_ap(const char *ssid_prefix);
|
||||
bool domain_runtime_wifi_connect_error_keeps_credentials(esp_err_t err);
|
||||
|
||||
/**
|
||||
* @brief Connect STA using stored credentials with explicit timeout.
|
||||
* @brief 以明确超时使用已存凭据连接 STA。 / Connect STA using stored credentials.
|
||||
*
|
||||
* 非正超时使用默认值;STA 已连接时幂等返回 `ESP_OK`;超时或连接错误会明确返回失败。
|
||||
*
|
||||
* Semantics:
|
||||
* - `timeout_ms <= 0`: use default timeout.
|
||||
@@ -576,7 +618,9 @@ bool domain_runtime_wifi_connect_error_keeps_credentials(esp_err_t err);
|
||||
*/
|
||||
esp_err_t domain_runtime_wifi_portal_connect_sta(int timeout_ms);
|
||||
/**
|
||||
* @brief Validate candidate credentials before replacing persisted Wi-Fi state.
|
||||
* @brief 替换持久化状态前先验证候选凭据。 / Validate credentials before persistence.
|
||||
*
|
||||
* 有界连接试验失败时保留原凭据;只有试验成功才提交新凭据。
|
||||
*
|
||||
* The previous credentials remain available when the bounded connection trial
|
||||
* fails. A successful trial commits only the new credentials.
|
||||
@@ -587,12 +631,13 @@ esp_err_t domain_runtime_wifi_portal_connect_sta_with_credentials(
|
||||
int timeout_ms);
|
||||
esp_err_t domain_runtime_wifi_portal_reconnect_sta(int timeout_ms);
|
||||
esp_err_t domain_runtime_wifi_portal_stop_sta(void);
|
||||
/** Apply standby Wi-Fi power save, or restore the configured active policy. */
|
||||
/** 应用待机 Wi-Fi 省电或恢复活动策略。 / Apply standby Wi-Fi power save or restore policy. */
|
||||
esp_err_t domain_runtime_wifi_portal_set_light_standby(bool standby);
|
||||
bool domain_runtime_is_network_connect_error(esp_err_t err);
|
||||
esp_err_t domain_runtime_wifi_portal_save_credentials(const char *ssid, const char *password);
|
||||
esp_err_t domain_runtime_wifi_portal_clear_saved_credentials(void);
|
||||
|
||||
/* 小程序配网容量包含 NUL,并对应 BLE 写入 payload 的校验边界。 */
|
||||
#define DOMAIN_WIFI_PROVISIONING_SSID_MAX_LEN DOMAIN_WIFI_SSID_MAX_LEN
|
||||
#define DOMAIN_WIFI_PROVISIONING_PASSWORD_MAX_LEN 65
|
||||
|
||||
@@ -627,7 +672,7 @@ typedef enum {
|
||||
DOMAIN_WIFI_PROVISIONING_STATUS_FAIL_CONNECT,
|
||||
} domain_wifi_provisioning_status_t;
|
||||
|
||||
/** Start the fixed TalkingQ mini-program BLE provisioning protocol. */
|
||||
/** 启动固定 TalkingQ 小程序 BLE 配网协议。 / Start the TalkingQ BLE provisioning protocol. */
|
||||
esp_err_t domain_runtime_mini_program_provisioning_start(
|
||||
domain_wifi_provisioning_event_callback_t callback,
|
||||
void *user_data);
|
||||
@@ -636,24 +681,28 @@ esp_err_t domain_runtime_mini_program_provisioning_notify(
|
||||
esp_err_t domain_runtime_mini_program_provisioning_stop(int timeout_ms);
|
||||
|
||||
esp_err_t domain_runtime_init_lcd_device(void);
|
||||
/** Set LCD backlight PWM brightness from 0 to 100 percent. */
|
||||
/** 设置0到100%的 LCD PWM 背光。 / Set LCD PWM backlight from 0 to 100 percent. */
|
||||
esp_err_t domain_runtime_set_lcd_backlight_brightness(uint8_t brightness_percent);
|
||||
void domain_runtime_start_lcd_render_loop(void);
|
||||
/**
|
||||
* @brief Stop LCD render loop with bounded teardown.
|
||||
* @brief 有界停止 LCD 渲染循环。 / 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 domain_runtime_stop_lcd_render_loop(int timeout_ms);
|
||||
|
||||
/** Map the domain battery snapshot to persistent LCD status overlays. */
|
||||
/** 将电池快照映射为持久 LCD 状态层。 / Map battery snapshot to persistent LCD overlays. */
|
||||
esp_err_t domain_runtime_update_battery_overlay(const domain_battery_status_t *status);
|
||||
|
||||
esp_err_t domain_runtime_request_expression(const domain_expression_request_t *request);
|
||||
|
||||
/**
|
||||
* @brief Preload assets for an expression without changing the active display.
|
||||
* @brief 预热表情资源而不改变当前显示。 / Preload expression assets without display changes.
|
||||
*
|
||||
* 用于即将播放的资源型表情。请求会被复制,LCD 渲染任务在帧间执行预热,调用方等待结果;
|
||||
* 不支持或非资源型表情返回明确错误。
|
||||
*
|
||||
* Intended for asset-backed expressions that are likely to play soon. The
|
||||
* request is copied, the LCD render task performs the preload between display
|
||||
@@ -663,9 +712,14 @@ esp_err_t domain_runtime_request_expression(const domain_expression_request_t *r
|
||||
esp_err_t domain_runtime_preheat_expression(const domain_expression_request_t *request);
|
||||
|
||||
/**
|
||||
* @brief Request an expression and block until its finite asset sequence
|
||||
* @brief 请求表情并阻塞到有限资源序列结束或超时。 /
|
||||
* Request an expression and block until its finite asset sequence
|
||||
* completes, or @p timeout_ms elapses.
|
||||
*
|
||||
* 用于财富旋转开场等有限演示。入队失败返回底层错误;播放未在预算内结束返回
|
||||
* `ESP_ERR_TIMEOUT`(调用方可自行继续);LCD 未运行返回 `ESP_ERR_INVALID_STATE`。
|
||||
* `repeat_count == 0` 表示无限循环,因此本接口最终必然超时。
|
||||
*
|
||||
* Intended for finite presentations such as the wealth spin intro. Returns the
|
||||
* underlying request error if queuing fails, ESP_ERR_TIMEOUT if playback does
|
||||
* not finish within the timeout (the caller may proceed anyway), or
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "domain.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
/*
|
||||
* domain 私有协作接口:目录、角度数学、校准存储和 platform 适配器只供本组件实现
|
||||
* 使用。上层不得包含此文件;所有跨层契约必须经 domain.h 暴露。
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name_cn;
|
||||
const char *name_en;
|
||||
@@ -29,6 +33,7 @@ void domain_calibration_store_set(const domain_direction_calibration_t *config);
|
||||
bool domain_calibration_store_get(domain_direction_calibration_t *out_config);
|
||||
|
||||
bool domain_direction_lock_state(int timeout_ms);
|
||||
/* 状态锁保护角度/初始化快照,物理运动由 direction service 的另一互斥锁串行化。 */
|
||||
void domain_direction_unlock_state(void);
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
#if CONFIG_TQ_BATTERY_ENABLE
|
||||
|
||||
/*
|
||||
* 电量等级使用迟滞阈值并连续确认3次,避免临界点抖动。单次电压跳变超过300mV时,
|
||||
* 必须在100mV窗口内再次出现才接受;滤波采用旧值80%、新值20%。这些规则只生成
|
||||
* domain 状态,不决定关机、提示或 LCD 策略。
|
||||
*/
|
||||
#if CONFIG_TQ_BATTERY_LOW_EXIT_PERCENT <= CONFIG_TQ_BATTERY_LOW_ENTER_PERCENT
|
||||
#error "Battery low recovery threshold must exceed the entry threshold"
|
||||
#endif
|
||||
@@ -110,6 +115,7 @@ static domain_battery_charge_state_t map_charge_state(
|
||||
|
||||
static uint8_t voltage_to_percentage(int voltage_mv)
|
||||
{
|
||||
/* 在实测放电曲线相邻点之间线性插值,而不是用单一线性电压公式。 */
|
||||
if (voltage_mv <= s_discharge_curve[0].voltage_mv) {
|
||||
return s_discharge_curve[0].percentage;
|
||||
}
|
||||
@@ -131,6 +137,7 @@ static uint8_t voltage_to_percentage(int voltage_mv)
|
||||
|
||||
static bool accept_voltage_step(int voltage_mv)
|
||||
{
|
||||
/* 大跳变需要连续候选确认,用于过滤电机/扬声器负载造成的瞬时压降。 */
|
||||
if (!s_filter_initialized || abs(voltage_mv - s_filtered_mv) <= BATTERY_MAX_ACCEPTED_STEP_MV) {
|
||||
s_jump_candidate_count = 0U;
|
||||
return true;
|
||||
@@ -230,6 +237,7 @@ esp_err_t domain_battery_init(void)
|
||||
|
||||
esp_err_t domain_battery_sample(void)
|
||||
{
|
||||
/* platform 样本无效或高负载抑制时保留最后有效状态,只更新质量和失败计数。 */
|
||||
esp_err_t err = domain_battery_init();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
static const char *TAG = "domain_cal";
|
||||
|
||||
/*
|
||||
* 20秒是完整校准预算,单步最多1.5秒。扫描不超过330度;命中限位后分最多90度
|
||||
* 的块回到180度机械中心,再把逻辑角设为0。所有阶段共享同一绝对截止时间。
|
||||
*/
|
||||
#define DOMAIN_CALIBRATION_TIMEOUT_MS 20000
|
||||
#define DOMAIN_CALIBRATION_STEP_TIMEOUT_MS 1500
|
||||
#define DOMAIN_TURNTABLE_LIMIT_SEARCH_MAX_DEG 330.0f
|
||||
@@ -96,6 +100,7 @@ static bool calibration_settle(const domain_direction_calibration_t *calibration
|
||||
|
||||
static esp_err_t calibration_rotate_and_track(float delta, int rotate_speed_us, int timeout_ms)
|
||||
{
|
||||
/* 只有物理运动成功才同步更新 domain 角度,避免软件/机械位置分叉。 */
|
||||
if (timeout_ms <= 0) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
@@ -139,6 +144,7 @@ static esp_err_t calibration_return_from_limit(float search_direction,
|
||||
|
||||
esp_err_t domain_calibrate_with_timeout(const domain_direction_calibration_t *config, int timeout_ms)
|
||||
{
|
||||
/* 完整扫描期间持有 rotation mutex,普通方向命令不能插入校准序列。 */
|
||||
int effective_timeout_ms = timeout_ms > 0 ? timeout_ms : DOMAIN_CALIBRATION_TIMEOUT_MS;
|
||||
TickType_t timeout_ticks = pdMS_TO_TICKS(effective_timeout_ms);
|
||||
if (timeout_ticks == 0) {
|
||||
|
||||
@@ -14,6 +14,7 @@ static domain_direction_calibration_t s_calibration = {0};
|
||||
static bool s_calibration_configured = false;
|
||||
static portMUX_TYPE s_calibration_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
/* 校准配置是受自旋锁保护的内存 SSOT;读写按值复制,不暴露内部指针。 */
|
||||
void domain_calibration_store_set(const domain_direction_calibration_t *config)
|
||||
{
|
||||
portENTER_CRITICAL(&s_calibration_lock);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "domain_internal.h"
|
||||
|
||||
/* 角度统一归一化到 (-180, 180],为目录匹配和最短旋转提供唯一表示。 */
|
||||
float domain_angle_normalize(float angle)
|
||||
{
|
||||
while (angle > 180.0f) {
|
||||
@@ -19,6 +20,7 @@ float domain_angle_normalize(float angle)
|
||||
|
||||
float domain_angle_shortest_rotation(float current, float target)
|
||||
{
|
||||
/* 结果限制到 [-180, 180],正负号决定方向,避免不必要的整圈运动。 */
|
||||
float diff = target - current;
|
||||
|
||||
while (diff > 180.0f) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 方向目录是名称、别名和标准角度的唯一事实来源;解析不修改当前转盘状态。 */
|
||||
static const domain_direction_entry_t s_default_directions[] = {
|
||||
{"南", "S", 0.0f},
|
||||
{"西南", "SW", 45.0f},
|
||||
@@ -61,6 +62,7 @@ static void trimmed_span(const char *input, const char **start_out, size_t *len_
|
||||
|
||||
static bool equals_trimmed(const char *input, const char *token, bool case_insensitive)
|
||||
{
|
||||
/* 忽略输入首尾空白;英文别名大小写不敏感,中文按 UTF-8 字节精确比较。 */
|
||||
const char *start = NULL;
|
||||
size_t len = 0;
|
||||
size_t token_len = 0;
|
||||
@@ -140,6 +142,7 @@ bool domain_direction_catalog_find_by_name(const char *input, size_t *out_index)
|
||||
|
||||
bool domain_direction_catalog_find_by_angle(float angle, size_t *out_index)
|
||||
{
|
||||
/* 先归一化角度,再在浮点容差内匹配目录标准方向。 */
|
||||
for (size_t i = 0; i < domain_direction_catalog_count(); i++) {
|
||||
const domain_direction_entry_t *entry = domain_direction_catalog_get(i);
|
||||
if (entry == NULL) {
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
|
||||
static const char *TAG = "domain";
|
||||
|
||||
/*
|
||||
* 默认速度和超时是一次方向动作的产品基线;校准扫描以5度步进、最多330度搜索,
|
||||
* 避免机械结构在找不到限位时持续整圈运动。修改需同步验证电机和限位开关。
|
||||
*/
|
||||
#define DOMAIN_DEFAULT_ROTATE_SPEED_US 1500
|
||||
#define DOMAIN_ROTATE_TIMEOUT_MS 8000
|
||||
#define DOMAIN_STATE_LOCK_TIMEOUT_MS 2000
|
||||
@@ -26,6 +30,7 @@ static const char *TAG = "domain";
|
||||
#define DOMAIN_DEFAULT_CALIBRATION_SETTLE_DELAY_MS 10
|
||||
|
||||
static float s_current_angle = 0.0f;
|
||||
/* 状态锁保护快照,rotation mutex 串行化整个物理运动;下层电机调用不持有状态锁。 */
|
||||
static int s_rotate_speed_us = DOMAIN_DEFAULT_ROTATE_SPEED_US;
|
||||
static bool s_initialized;
|
||||
static SemaphoreHandle_t s_state_mutex;
|
||||
@@ -169,6 +174,7 @@ void domain_direction_unlock_state(void)
|
||||
esp_err_t domain_init(const domain_direction_axis_config_t *config,
|
||||
const domain_direction_calibration_t *calibration)
|
||||
{
|
||||
/* platform 初始化成功后才发布 initialized,避免查询者看到半初始化配置。 */
|
||||
esp_err_t runtime_err = domain_runtime_platform_init();
|
||||
if (runtime_err != ESP_OK) {
|
||||
return runtime_err;
|
||||
@@ -301,6 +307,7 @@ int domain_get_rotate_speed_us(void)
|
||||
|
||||
esp_err_t domain_rotate_to_angle_with_timeout(float target_angle, int timeout_ms)
|
||||
{
|
||||
/* 计算最短角差并使用剩余总预算驱动电机;成功后才更新角度 SSOT。 */
|
||||
TickType_t start_tick = xTaskGetTickCount();
|
||||
int effective_timeout_ms = timeout_ms > 0 ? timeout_ms : DOMAIN_ROTATE_TIMEOUT_MS;
|
||||
|
||||
@@ -365,6 +372,7 @@ esp_err_t domain_rotate_to_angle_with_timeout(float target_angle, int timeout_ms
|
||||
|
||||
esp_err_t domain_apply_rotation_delta(float delta)
|
||||
{
|
||||
/* 相对运动仍走同一互斥路径,完成后把累计角度归一化。 */
|
||||
if (!domain_direction_lock_state(DOMAIN_STATE_LOCK_TIMEOUT_MS)) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
|
||||
static const char *TAG = "domain_fortune_store";
|
||||
|
||||
/* NVS namespace + keys (<=15 chars). The platform layer owns the raw storage;
|
||||
* the domain serializes its typed records as opaque struct blobs. */
|
||||
/* NVS 命名空间/键不超过15字符。platform 只存原始 blob,domain 拥有结构 schema。 */
|
||||
#define DOMAIN_FORTUNE_NVS_NAMESPACE "fortune"
|
||||
#define DOMAIN_FORTUNE_KEY_PROFILE "profile"
|
||||
#define DOMAIN_FORTUNE_KEY_RESULT "result"
|
||||
@@ -33,6 +32,7 @@ static bool s_fortune_result_loaded;
|
||||
static bool s_fortune_result_valid;
|
||||
static portMUX_TYPE s_fortune_result_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
/* 内存快照采用惰性加载;loaded 与 valid 分开,避免每次查询重复访问 NVS。 */
|
||||
static bool domain_birth_profile_is_valid(const domain_birth_profile_t *profile)
|
||||
{
|
||||
return profile != NULL &&
|
||||
@@ -67,6 +67,7 @@ void domain_runtime_register_birth_profile_observer(domain_birth_profile_observe
|
||||
|
||||
esp_err_t domain_birth_profile_store_set(const domain_birth_profile_t *profile)
|
||||
{
|
||||
/* 先完成持久化,再发布内存快照和锁外观察者通知,确保通知代表已落盘状态。 */
|
||||
if (!domain_birth_profile_is_valid(profile)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -105,6 +106,7 @@ esp_err_t domain_birth_profile_store_set(const domain_birth_profile_t *profile)
|
||||
|
||||
bool domain_birth_profile_store_get(domain_birth_profile_t *out_profile)
|
||||
{
|
||||
/* 首次查询从 NVS 加载,缺失或旧记录无效时缓存“无有效资料”结果。 */
|
||||
if (out_profile == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
static const char *TAG = "domain_user_web";
|
||||
static const char *kFortuneTimezone = "Asia/Shanghai";
|
||||
|
||||
/*
|
||||
* 本服务拥有路由、JSON schema、日期校验和嵌入页面;platform 只提供有界 HTTP
|
||||
* request/response 缓冲。handler 不保存 request body 指针,返回前完成全部解析。
|
||||
*/
|
||||
extern const uint8_t user_config_html_start[]
|
||||
asm("_binary_user_config_html_start");
|
||||
extern const uint8_t user_config_html_end[]
|
||||
@@ -30,6 +34,7 @@ static bool is_leap_year(int year)
|
||||
|
||||
static bool is_valid_date(int year, int month, int day)
|
||||
{
|
||||
/* 接受1900-2100年并执行完整闰年/月份天数校验,拒绝只满足数值范围的无效日期。 */
|
||||
static const uint8_t days_per_month[] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
|
||||
};
|
||||
@@ -200,6 +205,7 @@ static bool parse_profile(const uint8_t *body,
|
||||
domain_birth_profile_t *out_profile,
|
||||
const char **out_error)
|
||||
{
|
||||
/* 所有必填字段先解析到局部快照,完整校验通过后才交给 store,避免部分更新。 */
|
||||
if (body == NULL || body_len == 0U) {
|
||||
*out_error = "Request body is empty";
|
||||
return false;
|
||||
@@ -333,6 +339,7 @@ static esp_err_t user_config_http_handler(
|
||||
platform_lan_http_response_t *response,
|
||||
void *user_data)
|
||||
{
|
||||
/* 路由匹配与 method 检查集中在此处,未知路径和错误方法返回明确 HTTP 状态。 */
|
||||
(void)user_data;
|
||||
|
||||
if (strcmp(request->path, "/") == 0) {
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include "platform.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/*
|
||||
* 本地命令链路:platform PCM observer -> 有界 PCM 队列 -> domain MultiNet 推理任务
|
||||
* -> generation 标记的检测事件。观察者从不阻塞采集;队列满时计数并丢帧。
|
||||
*/
|
||||
#ifndef CONFIG_TQ_LOCAL_COMMAND_TASK_STACK_BYTES
|
||||
#define CONFIG_TQ_LOCAL_COMMAND_TASK_STACK_BYTES 8192
|
||||
#endif
|
||||
@@ -47,6 +51,10 @@
|
||||
#define DOMAIN_LOCAL_COMMAND_MODEL_NAME "mn7_cn"
|
||||
#define DOMAIN_LOCAL_COMMAND_TEXT "喵掌柜"
|
||||
#define DOMAIN_LOCAL_COMMAND_GRAPH_TEXT "miao zhang gui"
|
||||
/*
|
||||
* 8帧队列吸收短期调度抖动;每帧最多512样本。控制/锁等待有界,统计每2秒汇总,
|
||||
* 任务事件位区分请求停止、已停止、运行和暂停,避免只靠 task handle 猜测状态。
|
||||
*/
|
||||
#define DOMAIN_LOCAL_COMMAND_PCM_QUEUE_LEN 8U
|
||||
#define DOMAIN_LOCAL_COMMAND_PCM_MAX_SAMPLES 512U
|
||||
#define DOMAIN_LOCAL_COMMAND_QUEUE_WAIT_MS 100U
|
||||
@@ -203,6 +211,7 @@ static void local_command_pcm_observer(const int16_t *pcm,
|
||||
uint32_t sample_rate_hz,
|
||||
void *user_data)
|
||||
{
|
||||
/* 只复制可容纳的数据并立即返回;推理、日志和回调都留给 domain 任务。 */
|
||||
(void)user_data;
|
||||
bool admitted = false;
|
||||
portENTER_CRITICAL(&s_pcm_ingress_lock);
|
||||
@@ -425,6 +434,7 @@ static bool local_command_apply_control(size_t *fill_samples)
|
||||
|
||||
static void local_command_publish_detection(float probability)
|
||||
{
|
||||
/* confidence 转为万分比整数,generation 防止暂停/恢复前的迟到结果被误用。 */
|
||||
domain_local_command_event_callback_t callback = NULL;
|
||||
void *callback_user_data = NULL;
|
||||
domain_local_command_event_t event = {
|
||||
@@ -692,6 +702,7 @@ esp_err_t domain_runtime_local_command_start(
|
||||
domain_local_command_event_callback_t callback,
|
||||
void *user_data)
|
||||
{
|
||||
/* 模型、队列、静态任务栈全部准备成功后才注册 PCM observer 并发布 started。 */
|
||||
if (callback == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "platform.h"
|
||||
|
||||
/*
|
||||
* 设备信息使用固定缓冲构造 JSON;写特征分片必须在3秒内完成,否则清空旧片段,
|
||||
* 防止两次手机写入拼接。名称前缀和 UUID 属于固定 TalkingQ 小程序协议。
|
||||
*/
|
||||
#define DOMAIN_PROVISIONING_ID_MAX_LEN 64
|
||||
#define DOMAIN_PROVISIONING_SERIAL_MAX_LEN 64
|
||||
#define DOMAIN_PROVISIONING_VERSION_MAX_LEN 32
|
||||
@@ -63,6 +67,7 @@ static const platform_ble_uuid128_t s_device_info_uuid = {
|
||||
static void domain_provisioning_dispatch_event(
|
||||
const domain_wifi_provisioning_event_t *event)
|
||||
{
|
||||
/* 回调对在锁内取快照、锁外调用,允许上层在事件中停止或重启配网。 */
|
||||
domain_wifi_provisioning_event_callback_t callback;
|
||||
void *user_data;
|
||||
|
||||
@@ -91,6 +96,7 @@ domain_provisioning_append_write_fragment(const uint8_t *data,
|
||||
size_t data_len,
|
||||
size_t *out_buffered_len)
|
||||
{
|
||||
/* 以完整 JSON 结束符判断写入完成;越界、超时或格式异常会重置整个缓冲。 */
|
||||
if (data == NULL || data_len == 0U) {
|
||||
return DOMAIN_PROVISIONING_WRITE_INVALID;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "platform.h"
|
||||
|
||||
/*
|
||||
* 4KB 响应上限约束版本查询 JSON;36字符 nonce 提供请求唯一性;内部认证值包含
|
||||
* 时间戳/nonce/HMAC 编码。系统时间早于合理 epoch 时拒绝生成时效认证。
|
||||
*/
|
||||
#define DOMAIN_OTA_RESPONSE_CAPACITY 4096
|
||||
#define DOMAIN_OTA_NONCE_LEN 36
|
||||
#define DOMAIN_OTA_AUTH_VALUE_MAX_LEN 128
|
||||
@@ -117,6 +121,7 @@ static esp_err_t domain_ota_build_internal_auth(const char *url,
|
||||
char *signature,
|
||||
size_t signature_len)
|
||||
{
|
||||
/* 签名输入绑定 HTTP 路径、时间戳和随机 nonce,避免认证值跨接口或重放复用。 */
|
||||
time_t now = time(NULL);
|
||||
if ((int64_t)now < DOMAIN_OTA_MIN_VALID_EPOCH) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@@ -216,6 +221,7 @@ static esp_err_t domain_ota_build_report_payload(const domain_ota_report_request
|
||||
static esp_err_t domain_ota_parse_report_response(const char *body,
|
||||
domain_ota_report_response_t *response)
|
||||
{
|
||||
/* 完整验证业务码、版本、URL、SHA-256、大小和强制/确认标志后才发布固件快照。 */
|
||||
cJSON *root = cJSON_Parse(body);
|
||||
if (root == NULL) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
@@ -427,6 +433,7 @@ esp_err_t domain_runtime_ota_install(const domain_ota_firmware_t *firmware,
|
||||
domain_ota_cancel_callback_t cancel_cb,
|
||||
void *user_data)
|
||||
{
|
||||
/* domain 将十六进制哈希转为32字节并桥接进度/取消回调,下载写入仍由 platform 拥有。 */
|
||||
if (firmware == NULL || strncmp(firmware->url, "https://", 8) != 0 ||
|
||||
firmware->size_bytes == 0U || timeout_ms <= 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
/*
|
||||
* Domain 运行时适配器:把领域层端口翻译成 platform 调用,并把平台事件映射回领域语义。
|
||||
* 本文件不应引入重试、状态机或产品策略;这些属于 control_plane。静态回调及 hook 是注册
|
||||
* 信息的唯一副本,分发时先在临界区内取得快照,再在锁外调用,防止回调重入造成死锁。
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifndef CONFIG_MULTIMODAL_PTT_BUTTON_GPIO
|
||||
@@ -138,8 +144,12 @@ static const char *const s_wealth_direction_asset_dirs[] = {
|
||||
#define DOMAIN_WUXING_REVEAL_FRAME_MS 100U
|
||||
#define DOMAIN_WUXING_HOLD_FRAME_MS 500U
|
||||
|
||||
/* 动画节奏属于领域呈现契约:短帧展示运动过程,较长末帧让用户有时间辨认最终结果。 */
|
||||
|
||||
#define DOMAIN_AUTH_KEY_STORE_NAMESPACE "auth_key"
|
||||
#define DOMAIN_AUTH_STATE_STORE_NAMESPACE "auth"
|
||||
|
||||
/* 认证密钥与认证状态分命名空间保存,便于独立轮换密钥而不破坏注册进度。 */
|
||||
#define DOMAIN_AUTH_KEY_STORE_BLOB_KEY "keymat"
|
||||
#define DOMAIN_AUTH_STATE_STORE_BLOB_KEY "state"
|
||||
#define DOMAIN_AUTH_LEGACY_KEY_PRIV_KEY "sk"
|
||||
@@ -304,6 +314,7 @@ static const domain_expression_catalog_entry_t s_expression_catalog[] = {
|
||||
|
||||
static void snapshot_domain_wifi_behavior_hooks(domain_wifi_behavior_hooks_t *out_hooks)
|
||||
{
|
||||
/* 只在临界区复制函数指针和上下文;实际 hook 在锁外调用,允许 hook 反向更新注册。 */
|
||||
if (out_hooks == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -392,6 +403,7 @@ static void dispatch_domain_transport_event(domain_multimodal_transport_event_ty
|
||||
const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
/* data 只在本次 platform 回调期间有效;domain 不缓存,跨任务保留由上层自行复制。 */
|
||||
domain_multimodal_transport_event_callback_t cb = NULL;
|
||||
void *cb_user_data = NULL;
|
||||
snapshot_domain_transport_callback(&cb, &cb_user_data);
|
||||
@@ -576,6 +588,7 @@ esp_err_t domain_runtime_post_json(const char *url,
|
||||
size_t *out_response_body_len,
|
||||
int *out_status)
|
||||
{
|
||||
/* 本适配只映射 header/缓冲区所有权,不解释业务 HTTP 状态,也不在 domain 内隐式重试。 */
|
||||
if (out_response_body_len != NULL) {
|
||||
*out_response_body_len = 0U;
|
||||
}
|
||||
@@ -1116,6 +1129,7 @@ static esp_err_t load_legacy_auth_record(domain_runtime_auth_record_t record,
|
||||
size_t out_len,
|
||||
size_t *out_len_actual)
|
||||
{
|
||||
/* 旧键只用于一次兼容读取;成功后由新格式保存路径接管,迁移不会改变调用方序列化 schema。 */
|
||||
switch (record) {
|
||||
case DOMAIN_RUNTIME_AUTH_RECORD_KEY_MATERIAL:
|
||||
return load_legacy_auth_key_material(out, out_len, out_len_actual);
|
||||
@@ -1180,6 +1194,7 @@ esp_err_t domain_runtime_auth_store_save_record(domain_runtime_auth_record_t rec
|
||||
const void *data,
|
||||
size_t len)
|
||||
{
|
||||
/* platform blob 写入成功才更新持久状态;输入缓冲区始终由调用方拥有。 */
|
||||
if (data == NULL || len == 0U) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -1430,6 +1445,7 @@ static esp_err_t domain_resolve_expression_platform_request(
|
||||
const domain_expression_request_t *request,
|
||||
platform_lcd_presentation_request_t *out_platform_request)
|
||||
{
|
||||
/* 这是领域表情 ID 到平台资源序列的唯一映射,避免 control_plane 拼接资源目录和帧参数。 */
|
||||
if (request == NULL || out_platform_request == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -1621,6 +1637,7 @@ esp_err_t domain_runtime_preheat_expression(const domain_expression_request_t *r
|
||||
esp_err_t domain_runtime_request_expression_blocking(const domain_expression_request_t *request,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
/* 仅有限序列适合等待完成;底层仍拥有渲染任务,调用方只是等待该请求的完成通知。 */
|
||||
/* Snapshot the playback completion counter before queuing so the wait stays
|
||||
* robust to the asynchronous request not having started yet. */
|
||||
uint32_t since_count = platform_lcd_presentation_completion_count();
|
||||
|
||||
Reference in New Issue
Block a user