# SF32LB52 HFP HF 连接 Windows 问题分析

## 1. 项目目标

目标是让 SF32LB52 作为经典蓝牙 HFP HF（Hands-Free Unit），将板载麦克风采集的音频通过蓝牙发送给 Windows 电脑或手机，作为电脑/手机的麦克风输入。

## 2. 当前总体结论

当前问题已经分为两个阶段：

1. **ACL 建立后的 SDP/RFCOMM 建链时序问题**：通过 ACL 建立后等待约 1 秒再主动发起 HFP 连接，**已经解决**。
2. **RFCOMM 建立后的 HFP AT 初始化问题**：板子可以发送 `AT+BRSF=671`，但 Windows 不返回 `+BRSF/OK`，约 60 秒后主动断开。

目前最主要的疑点是：**SF32LB52 使用的 RFCOMM 帧构造/封装格式与 Windows 能正常处理的设备不同**。发送时序差异已经通过普通耳机验证为次要因素。

---

## 3. 手机连接：当前已经正常

手机连接是已经验证通过的基线：

- 手机可以识别并连接 SF32LB52；
- HFP 建链可以继续进行；
- 手机可以听到板子发送的音频；
- 板载麦克风音频链路可以工作；
- 手机基线工程的音频路径没有被 Windows 调试修改破坏。

因此，SF32LB52 的基本 HFP HF 功能并非完全失效，问题主要体现在 Windows 对 RFCOMM/HFP 初始化流程的兼容性上。

---

## 4. Windows 连接流程中已经确认正常的部分

Windows 抓包已经确认以下阶段可以成功：

```text
设备发现/配对
    ↓
ACL 建立
    ↓
SDP 查询
    ↓
RFCOMM 通道建立
    ↓
板子发送 AT+BRSF=671
    ↓
Windows 没有回复 +BRSF/OK
    ↓
约 60 秒后 RFCOMM/ACL 断开
```

因此当前不能再描述为“Windows 卡在 SDP”。准确描述应为：

> ACL、SDP 和 RFCOMM 建链已经成功，失败发生在 RFCOMM 建立后的 HFP AT 协议初始化阶段。

---

## 5. 第一阶段问题：ACL 后等待 1 秒

最初连接 Windows 时，流程停在 SDP，RFCOMM 没有建立成功。后来在 ACL 连接成功后增加约 1 秒延时，再主动发起 HFP 连接：

```text
ACL_CONNECTED
    ↓ 等待 1 秒
bt_interface_conn_ext(..., BT_PROFILE_HFP)
    ↓
SDP 成功
    ↓
RFCOMM 成功
```

这个修改确实解决了第一个问题：**Windows 端 SDP/RFCOMM 建链时序不稳定**。

但是，这个 1 秒延时发生在 ACL 建立之后，不能控制 RFCOMM 建立完成后到 HFP 库发送 `AT+BRSF` 之间的时间。

---

## 6. 第二阶段问题：HFP AT 初始化失败

板子发送：

```text
AT+BRSF=671\r
```

Windows 没有返回正常的：

```text
+BRSF:3943\r\n\r\nOK\r\n
```

Windows 只发送了一个 RFCOMM 控制/流控类帧：

```text
09 FF 01 1A 5C
```

之后等待约 60 秒，最终主动发送 RFCOMM DISC 并断开连接。

这说明 Windows 蓝牙底层收到了板子的 RFCOMM 数据，但没有继续将其交给正常的 HFP AT 状态机处理。

---

## 7. 三类正常设备对比

已经抓取并分析了三类能够正常作为 Windows HFP 设备工作的设备：

- 倍思蓝牙耳机；
- 第二副普通蓝牙耳机；
- 第三副蓝牙录音设备。

三类设备均能让 Windows 回复：

```text
+BRSF:3943\r\n\r\nOK\r\n
```

随后继续完成：

```text
AT+BAC
AT+CIND=?
AT+CIND?
AT+CMER
```

这证明 Windows 可以支持普通经典蓝牙 HFP 设备，并不是完全拒绝非系统耳机设备。

---

## 8. AT+BRSF=671 原始帧对比

下面的十六进制数据是 Windows BTHPORT ETL 中记录的完整封装片段。它包含 HCI/L2CAP/RFCOMM 相关封装，不能把每一个字节都简单当成 RFCOMM 字段，但可以用于设备间对比。

### 8.1 倍思耳机

```text
002115001100430011EF180041542B425253463D3637310DBF
```

ASCII 数据部分：

```text
41 54 2B 42 52 53 46 3D 36 37 31 0D
 A  T  +  B  R  S  F  =  6  7  1 \r
```

### 8.2 第二副蓝牙耳机

```text
002115001100440011EF180041542B425253463D3637310DBF
```

与倍思相比，主要是连接地址/DLCI相关字段不同，但承载 HFP 数据的核心格式相同。

### 8.3 第三副蓝牙录音设备

第三副发送的是 `AT+BRSF=255`，不是 `671`：

```text
002114001000410009EF1941542B425253463D3235350D40
```

ASCII 数据部分：

```text
AT+BRSF=255\r
```

虽然能力值不同，但 Windows 同样返回 `+BRSF:3943` 和 `OK`，并继续完成 HFP 初始化。

### 8.4 SF32LB52 板子

```text
00211500110042000BFF191241542B425253463D3637310D86
```

ASCII 数据部分同样是：

```text
AT+BRSF=671\r
```

但前后的 RFCOMM 封装区域与三类正常设备不同。

---

## 9. 重点标记：帧的不同区域

以下是简化后的区域标记。由于 ETL 片段包含 HCI/L2CAP 外层封装，字段名称需要以 RFCOMM 协议解码或 SDK 官方定义为准。

### 正常耳机示例

```text
002115001100 [43/44] 00 11 [EF] [18 00] [AT+BRSF=671] [BF]
              │          │       │       │              │
              │          │       │       │              └─ 帧尾校验/FCS候选
              │          │       │       └─ 长度/可选字段候选
              │          │       └─ RFCOMM控制字段候选：EF
              │          └─ 地址/DLCI或连接上下文候选
              └─ HCI/L2CAP/RFCOMM外层相关区域
```

### 第三副示例

```text
002114001000 [41] 00 09 [EF] [19] [AT+BRSF=255] [40]
                         │     │                  │
                         │     │                  └─ 帧尾校验/FCS候选
                         │     └─ 长度/可选字段候选
                         └─ RFCOMM控制字段候选：EF
```

### SF32LB52 示例

```text
002115001100 [42] 00 0B [FF] [19 12] [AT+BRSF=671] [86]
                         │      │                 │
                         │      │                 └─ 帧尾校验/FCS候选
                         │      └─ 长度/信用流控/可选字段候选
                         └─ 与正常设备不同的RFCOMM控制字段：FF
```

### 关键差异

```text
正常设备：... EF 18 00 ... AT+BRSF ... BF
第三副设备：... EF 19    ... AT+BRSF ... 40
SF32LB52： ... FF 19 12 ... AT+BRSF ... 86
```

需要注意：最后一个字节很可能是 FCS，但 FCS 会随整帧内容变化，不能单独将 `BF`、`40` 或 `86` 认定为根因。真正可疑的是 `EF/FF` 以及它附近的长度、信用流控或可选字段。

---

## 10. RFCOMM 建立后到发送 BRSF 的时间对比

| 设备 | BRSF 内容 | RFCOMM 建立后到 BRSF 的大致时间 | Windows 后续结果 |
|:-:|--:|---:|--:|
| 倍思耳机 | `AT+BRSF=671` | 约 27.4 ms | 回复 `+BRSF:3943`、`OK` |
| 第二副耳机 | `AT+BRSF=671` | 约 11.3 ms | 回复 `+BRSF:3943`、`OK` |
| 第三副录音设备 | `AT+BRSF=255` | 约 2.4 ms | 回复 `+BRSF:3943`、`OK` |
| SF32LB52 | `AT+BRSF=671` | 约几毫秒 | 不回复 HFP AT，约 60 秒后断开 |

结论：

- 正常设备的延时并不固定，约 2.4～27.4 ms 都可以成功；
- 第三副设备发送得很快但仍然成功；
- 因此“板子发送太快”目前不是主要解释；
- 1 秒延时解决的是 ACL 到 SDP/RFCOMM 的建链时序，不是 RFCOMM 建立后的 BRSF 发送时序。

---

## 11. 当前最可靠的判断

```text
ACL：正常
SDP：正常（增加 ACL 后 1 秒延时后）
RFCOMM：正常建立
HFP HF：能够发送 AT+BRSF
Windows HFP AG：未对板子的 BRSF 返回 +BRSF/OK
```

当前主要怀疑：

1. RFCOMM UIH/控制字段构造不同；
2. RFCOMM 长度、信用流控或可选字段处理不同；
3. 帧尾 FCS 可能因此不同，但目前不能单独认定 FCS 错误；
4. 相关逻辑很可能位于 SDK 已编译的蓝牙静态库中。

发送时序差异仍可作为辅助验证方向，但根据第三副的抓包结果，优先级已经低于 RFCOMM 帧构造差异。

---

## 12. SDK 底层限制

关键逻辑很可能位于：

```text
C:\SiFli-SDK\v2.5\middleware\bluetooth\lib\lib_bt_gcc.a
```

`.a` 是已经编译好的静态库，应用层只能调用它暴露的接口，不能直接修改其中的 RFCOMM/HFP 帧构造逻辑。理论上可以进行反汇编或替换底层库，但风险和工作量较高，当前更现实的方案是向思澈官方申请：

- RFCOMM basic/UIH 与 credit-based 模式的配置接口；
- RFCOMM 帧构造相关源码或说明；
- RFCOMM 建立后延迟启动 HFP SLC 的接口；
- 兼容 Windows HFP 的新预编译蓝牙库。

---

## 13. 给官方的反馈重点

建议将以下信息一并提交给官方：

```text
正常耳机/录音设备：Windows 返回 +BRSF:3943 和 OK
SF32LB52：Windows 收到 AT+BRSF=671 后不返回 HFP AT 数据，约60秒后断开
```

原始帧对比：

```text
倍思：002115001100430011EF180041542B425253463D3637310DBF
第二副耳机：002115001100440011EF180041542B425253463D3637310DBF
第三副：002114001000410009EF1941542B425253463D3235350D40
SF32LB52：00211500110042000BFF191241542B425253463D3637310D86
```

请求官方重点确认：

> 请确认 HFP HF 库在 RFCOMM 建立后发送初始 AT 指令时的 UIH/控制字段、长度/信用流控字段及 FCS 构造方式。三类正常设备均采用 `EF` 类型封装并可被 Windows 正常处理，而 SF32LB52 使用 `FF` 类型封装，Windows 未返回 `+BRSF/OK`。

---

## 14. 结论

> SF32LB52 已经可以完成 Windows 的 ACL、SDP 和 RFCOMM 建链，手机端也已经验证音频功能正常；当前 Windows 连接失败主要发生在 RFCOMM 建立后的 HFP AT 初始化阶段，现有证据更支持 SDK 预编译蓝牙库生成的 RFCOMM 帧构造格式与 Windows HFP 驱动不兼容，而不是单纯的发送延时问题。
