# 项目进度与历史踩坑总结 本文档为上一个长对话的上下文总结,旨在为开启新对话提供完整的背景信息和代码逻辑参考。 ## 一、 已完成的开发与优化 ### 1. 蓝牙断开自动回连机制改进 * **需求背景:** 大厂主流音箱的体验——手动断开后不再回连并进入可被发现模式;因距离过远等意外断开后,持续搜寻尝试回连 5 分钟。 * **实现细节:** * 在 `bt_gap_cb` 的 `ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT` 事件中,提取底层的 `reason` 断开原因。 * 如果 `reason` 为 `0x13`, `0x14`, `0x15` (User Terminated / Local Host Terminated),视为手动断开,停止回连并开启广播 (`ESP_BT_GENERAL_DISCOVERABLE`)。 * 如果是 `0x08` (Link Timeout) 等异常断开,则启动一个后台 FreeRTOS 任务 `bt_reconnect_task`,每 5 秒尝试调用 `esp_a2d_sink_connect()` 一次,持续 5 分钟(60次)。 * **关键避坑(Wi-Fi 共存问题):** 为了防止蓝牙不断重连占用 2.4G 射频带宽导致 Wi-Fi 侧卡顿,在 `bt_reconnect_task` 中加入了判断:如果当前音频源正在播放 AirPlay (`playback_control_get_source() == PLAYBACK_SOURCE_AIRPLAY`),则立刻跳过当前的蓝牙回连动作,保证网络音频流畅。 ### 2. 烧录波特率极限优化 (CH340K) * **需求背景:** 缩短每次编译后 1.8M 固件漫长的烧录等待时间。 * **踩坑历程:** * **坑点1:** 在 `sdkconfig` 里改了速度没用,因为 Antigravity IDE (基于 VSCode 插件体系) 烧录时默认使用它自己配置表的 `460800`。**解决:** 必须在 `.vscode/settings.json` 里硬编码 `"idf.flashBaudRate": "xxx"`。 * **坑点2:** 尝试把速度拉满到 `2000000` 和 `1500000`,但在烧录时均出现 `A fatal error occurred: Unable to verify flash chip connection (No serial data received)`。原因是 CH340K 配合某些数据线、拓展坞或主板走线时,在高频下信号完整性崩溃。 * **最终方案:** 回退到黄金稳定速度 **`921600`**。虽然没有跑满极限,但比默认快了一倍,且绝不丢包翻车。 ### 3. iOS 电池小组件“大音响”图标复原 * **需求背景:** 重构底层代码后,苹果小组件里原本的音箱图标变成了通用的蓝牙图标,失去了高级感。 * **踩坑历程(蓝牙 CoD 玄学):** * **坑点1(C语言内存陷阱):** 声明 `esp_bt_cod_t cod;` 时未清零,导致结构体里的 `reserved_2` 字段带入了栈空间的随机垃圾值。iOS 收到后发现格式类型不对,直接拒认并降级为普通蓝牙图标。**解决:** 加上 `memset(&cod, 0, sizeof(cod));`。 * **坑点2(协议栈覆盖):** 最开始把 `esp_bt_gap_set_cod()` 写在了 A2DP 初始化的最前面。结果当代码执行到 `esp_a2d_sink_init()` 和 `esp_hf_client_init()` (HFP免提) 时,底层 Bluedroid 协议栈会自动去注册设备类型,把我们手动设置的音响图标**强行覆盖重置**了。 * **最终方案:** 将 `memset` 及 `esp_bt_gap_set_cod` 的设置代码,移动到 `bt_stack_evt_handler` 的**最后面**(也就是在所有音频协议彻底启动完毕之后),并设置 `major = 4`, `minor = 5`, `service = (1<<8) | (1<<5)` (Audio + Rendering)。图标成功找回。 --- ## 二、 待解决的核心问题(下一阶段任务) ### 🐛 Bug: 苹果设备的绝对音量 (Absolute Volume) 异常变动 * **现象:** 1. 每次系统重启连接后,音量自动变成 `77/127` (大约 60%)。 2. 手机正在播放时,如果来了一条通知(如微信),音量也会被强制拉到 `77` 且不一定能恢复。 * **原因分析:** * iOS 的底层保护机制。当通过 AVRCP 控制绝对音量时,为了防止通知声音过大,iOS 会下发鸭子听雷(Ducking)指令,将绝对音量强制设定到一个安全默认值(通常是 `0x4D` 即 77)。 * **后续计划(需要与用户确认并实施):** * **方案A(物理隔离):** 在 AVRCP 的注册事件中移除 `ESP_AVRC_RN_VOLUME_CHANGE` 支持,彻底切断手机与音箱硬件音量的绝对同步。两者音量独立控制,互不干涉。 * **方案B(打补丁拦截):** 保留按键同步功能。但是在 `esp_avrc_tg_cb` 的音量回调逻辑中,特殊拦截并忽略 iOS 恶意下发的 `77` 这一数值,或者编写更复杂的防抖/音量快照恢复逻辑。