#pragma once #include #include #include "domain.h" /* 私有纯策略,由 connectivity 模块在 s_provisioning_lock 内调用。 * 不持有 BLE 的运行状态副本:ACTIVE 仅表示协调器正在执行这一轮配网。 * 无定时器/后台任务;Wi-Fi worker 轮询 due 后才执行有副作用的启动。 */ typedef enum { CP_PROVISIONING_IDLE = 0, CP_PROVISIONING_STARTING, CP_PROVISIONING_ACTIVE, CP_PROVISIONING_STOPPING, CP_PROVISIONING_WAIT_IDENTITY, CP_PROVISIONING_BACKOFF, CP_PROVISIONING_BLOCKED, } cp_provisioning_phase_t; typedef struct { cp_provisioning_phase_t phase; unsigned retry_count; uint32_t failed_at_ms; uint32_t retry_delay_ms; bool retry_requested; bool recovery_attempted; bool runtime_quiesced; /* 协调器尚欠一次成功的有界 teardown;不是 BLE ready 状态的镜像。 */ bool cleanup_required; } cp_provisioning_policy_t; static inline bool cp_provisioning_policy_due(cp_provisioning_policy_t *policy, uint32_t now_ms) { if (policy->phase == CP_PROVISIONING_STARTING || policy->phase == CP_PROVISIONING_ACTIVE || policy->phase == CP_PROVISIONING_STOPPING) { return false; } if (policy->retry_requested) { /* 配置通知只重新开放普通尝试,不重置“已恢复重启”锁存。 */ policy->retry_requested = false; policy->phase = CP_PROVISIONING_IDLE; policy->retry_count = 0; } return policy->phase == CP_PROVISIONING_IDLE || (policy->phase == CP_PROVISIONING_BACKOFF && (uint32_t)(now_ms - policy->failed_at_ms) >= policy->retry_delay_ms); } static inline void cp_provisioning_policy_failed(cp_provisioning_policy_t *policy, domain_wifi_provisioning_start_status_t status, uint32_t now_ms) { static const uint32_t retry_delays_ms[] = {1000, 3000, 10000}; policy->retry_delay_ms = 0; if (status == DOMAIN_WIFI_PROVISIONING_START_IDENTITY_REQUIRED) { policy->phase = CP_PROVISIONING_WAIT_IDENTITY; } else if (status == DOMAIN_WIFI_PROVISIONING_START_TRANSIENT && policy->retry_count < sizeof(retry_delays_ms) / sizeof(retry_delays_ms[0])) { policy->retry_delay_ms = retry_delays_ms[policy->retry_count++]; policy->failed_at_ms = now_ms; policy->phase = CP_PROVISIONING_BACKOFF; } else { policy->phase = CP_PROVISIONING_BLOCKED; } } static inline bool cp_provisioning_policy_claim_recovery(cp_provisioning_policy_t *policy, domain_wifi_provisioning_start_status_t status) { if (status != DOMAIN_WIFI_PROVISIONING_START_NO_MEMORY || policy->recovery_attempted) { return false; } /* 当前启动先锁存,再写 RTC 请求。恢复启动消费请求时再次锁存;失败不可清零。 */ policy->recovery_attempted = true; return true; }