Rdzleo 8111515277 修复 Pendant 衍生项目无痛移植问题
实机验证通过后,按 Kapi 无屏底座路线补齐 Pendant RTC 吊坠项目的迁移修复。

1. BLE 配网与资源隔离
- sdkconfig.defaults 开启 BT 优先 PSRAM 分配,并将 LWIP socket 上限提升到 20
- sdkconfig.defaults.esp32s3 允许 BSS/NOINIT 放入 PSRAM,释放内部 SRAM 给 BLE/WiFi/RTC
- 配网模式 codec 使用 StartOutputOnly(),跳过麦克风 RX DMA 和 ES7210 输入链路
- ResetWifiConfiguration() 改为独立 wifi_reset task,避免在 iot_button/esp_timer 回调中阻塞延时
- WifiBoard 增加 IsWifiConfigMode(),供启动阶段判断是否走配网资源隔离路径

2. 音频底噪与 DMA 残留修复
- AudioCodec 增加 StartOutputOnly(),支持仅启动扬声器输出
- RTC 音频通道打开后灌入 200ms silence PCM,覆盖 I2S DMA 残留数据
- 软退出进入待命前重启 codec output 并再次灌静音,减少待命音/欢迎语前杂音
- box_audio_codec 在无硬件回采时使用 channel_mask=0,避免 I2S slot mask 被错误污染

3. 软件 loopback AEC
- 引入 esp_aec 底层同步 API,使用 DAC 输出复制构建 ref ring
- 上行 mic PCM 与延迟 ref 做同步消回声,适配无屏无硬件回采的 Pendant 形态
- AEC 采用 lazy init,减少启动阶段对 WiFi/BLE 内部 SRAM 的压力
- ref 静音时直接 passthrough,避免 AI 静音后误压制用户语音
- 在 player_pipeline_write 和 codec->OutputData 两条下行路径都追加 ref hook

4. RTC 连接稳定性与软退出
- VolcRtcProtocol 增加 LeaveRoom(bool notify_closed),支持 stop 房间但保留 rtc_handle
- hibernate 路径使用 LeaveRoom(false),避免关闭回调顺手关掉 codec output 导致待命音无声
- LeaveRoom/ForceRebuildEngine 重置 downlink_is_pcm_ 和首包标志,避免本地 Opus 音效被当 PCM 播成杂音
- OpenAudioChannel 连续失败 3 次后 ForceRebuildEngine,清理 RTC SDK 内部异常状态
- 加入 DIAG-RTC socket/heap/PSRAM/RSSI 日志,便于定位 ICE socket 和内存问题

5. Dialog watchdog 与 BOOT 唤醒
- Dialog watchdog 到期不再写 reboot_dlg_idle 后 esp_restart
- 新增 EnterIdleHibernate():软退房、清空残留音频队列、关闭麦克风、播放待命音后静默
- 新增 WakeFromHibernate():BOOT 唤醒后复用 RTC engine 并通过 ToggleChatState() 重连 RTC
- BOOT 单击优先判断 IsHibernating(),异步唤醒,避免走普通按键状态机
- hibernate 期间禁止 PowerSaveTimer 进入 Light Sleep,保护 I2C/codec 总线

6. 文档与衍生项目沉淀
- 更新石头光源属性检测方案文档
- 将 Pendant 实测通过的软退出、AEC、BLE 配网隔离经验同步到衍生项目移植规则
2026-05-29 13:36:36 +08:00

146 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef WIFI_BOARD_H
#define WIFI_BOARD_H
/**
* @file wifi_board.h
* @brief WiFi板级管理模块头文件
*
* 本文件定义了WiFi板级管理的相关接口包括WiFi连接管理、
* BLE蓝牙配网流程控制、网络状态监控等功能。
* 集成了蓝牙配网功能,提供完整的网络连接解决方案。
*/
#include "board.h"
#include "bluetooth_provisioning.h"
// #include "ble_service.h" // BLE JSON Service 暂不使用
#include <string>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// 前向声明
class Application;
/**
* @class WifiBoard
* @brief WiFi板级管理类
*
* 继承自Board基类负责管理ESP32的WiFi连接、BLE蓝牙配网流程和网络状态监控。
* 提供完整的网络连接解决方案,包括自动连接、配网模式切换、网络状态监控等功能。
*/
class WifiBoard : public Board {
protected:
bool wifi_config_mode_ = false; ///< WiFi配置模式标志true表示进入配网模式
bool ble_provisioning_active_ = false; ///< BLE配网激活状态标志
bool ble_provisioning_success_ = false; ///< BLE配网成功状态标志
TickType_t ble_start_time_ = 0; ///< BLE配网开始时间戳
static const TickType_t BLE_PROV_TIMEOUT_MS = 300000; ///< BLE配网超时时间5分钟
BluetoothProvisioning bluetooth_provisioning_; ///< BLE蓝牙配网实例对象
// BleJsonService ble_json_service_; ///< BLE JSON 配网服务实例(暂不使用)
/**
* @brief 构造函数
* 初始化WiFi板级管理对象读取配置参数
*/
WifiBoard();
/**
* @brief 进入WiFi配置模式
* 启动BLE蓝牙配网流程等待用户通过手机APP配置WiFi信息
*/
void EnterWifiConfigMode();
/**
* @brief 广播验证码
* @param code 验证码字符串
* @param application 应用程序实例引用
* 用于在配网过程中向用户显示验证码信息
*/
void BroadcastVerificationCode(const std::string& code, Application& application);
/**
* @brief 启动BLE蓝牙配网
* @return true 启动成功
* @return false 启动失败
* 初始化并启动BLE蓝牙配网服务等待手机连接
*/
bool StartBleProvisioning();
// // 使用 BLE JSON Service 进行配网(暂不使用)
// bool StartBleJsonProvisioning();
/**
* @brief 监控BLE配网进程
* 监控配网状态变化,处理超时和异常情况
*/
void MonitorBleProvisioning();
/**
* @brief BLE配网事件处理函数
* @param event 配网事件类型
* @param data 事件数据指针
* 处理BLE配网过程中的各种事件
*/
void OnBleProvisioningEvent(BluetoothProvisioningEvent event, void* data);
/**
* @brief BLE配网静态回调函数
* @param event 配网事件类型
* @param data 事件数据指针
* @param user_data 用户数据指针
* 静态回调函数用于处理BLE配网事件
*/
static void BleProvisioningCallback(BluetoothProvisioningEvent event, void* data, void* user_data);
/**
* @brief 清理现有蓝牙服务
* 在进入配网模式前清理application.cc中启动的蓝牙服务避免重复初始化
*/
void CleanupExistingBluetoothService();
/**
* @brief 清理现有WiFi服务
* 在进入配网模式前清理现有的WiFi服务为BLE重新初始化做准备
*/
void CleanupExistingWiFiService();
/**
* @brief 获取板级配置JSON字符串
* @return std::string 板级配置的JSON格式字符串
* 重写基类方法返回WiFi板级的配置信息
*/
virtual std::string GetBoardJson() override;
public:
/**
* @brief 获取板级类型
* @return std::string 返回"wifi"字符串
* 重写基类方法标识当前板级为WiFi类型
*/
virtual std::string GetBoardType() override;
/**
* @brief 启动网络连接
* 根据配置启动WiFi连接或BLE配网流程
* 重写基类方法实现WiFi网络的启动逻辑
*/
virtual void StartNetwork() override;
virtual Http* CreateHttp() override;
virtual WebSocket* CreateWebSocket() override;
virtual Mqtt* CreateMqtt() override;
virtual Udp* CreateUdp() override;
virtual const char* GetNetworkStateIcon() override;
virtual void SetPowerSaveMode(bool enabled) override;
virtual void ResetWifiConfiguration();
bool IsWifiConfigMode() const { return wifi_config_mode_; }
/**
* @brief 检查BLE配网是否激活
* @return true BLE配网正在进行中
* @return false BLE配网未激活
*/
bool IsBleProvisioningActive() const { return ble_provisioning_active_; }
};
#endif // WIFI_BOARD_H