context_summary.md 4.4 KB

项目进度与历史踩坑总结

本文档为上一个长对话的上下文总结,旨在为开启新对话提供完整的背景信息和代码逻辑参考。

一、 已完成的开发与优化

1. 蓝牙断开自动回连机制改进

  • 需求背景: 大厂主流音箱的体验——手动断开后不再回连并进入可被发现模式;因距离过远等意外断开后,持续搜寻尝试回连 5 分钟。
  • 实现细节:
    • bt_gap_cbESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT 事件中,提取底层的 reason 断开原因。
    • 如果 reason0x13, 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: 尝试把速度拉满到 20000001500000,但在烧录时均出现 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 协议栈会自动去注册设备类型,把我们手动设置的音响图标强行覆盖重置了。
    • 最终方案:memsetesp_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 这一数值,或者编写更复杂的防抖/音量快照恢复逻辑。