一副 TWS 耳机,为什么既要用经典蓝牙,又要用 BLE?

0 阅读5分钟

做 TWS 耳机时,经常会同时看到经典蓝牙和 BLE。

手机已经通过蓝牙连接耳机,可以播放音乐、接打电话,为什么配套 App 还要再连接一次 BLE?我刚开始接触时,也没有认真区分这两部分,只知道它们都叫蓝牙。

后来做 App 交互功能多了,我才慢慢理解:在目前常见的 TWS 产品里,它们处理的事情并不一样。经典蓝牙主要负责音乐、通话和媒体控制,BLE 更像一条给 App 使用的数据通道。

一、经典蓝牙主要负责耳机的基本功能

平时用耳机听歌、调节音量和接打电话,主要涉及经典蓝牙中的几个 Profile:

Profile在耳机中的主要作用
A2DP传输音乐音频
AVRCP播放、暂停、切歌和音量控制
HFP来电、接听、挂断等通话控制

通话时的语音通常还会通过 SCO/eSCO 链路传输。

这些功能决定了一副耳机能不能正常听歌和通话。以我目前接触到的应用开发来说,平时主要处理 SDK 上报的 A2DP、AVRCP 和 HFP 事件,再根据当前状态执行对应的产品逻辑。

二、BLE 主要负责耳机与 App 交互

配套 App 需要做的事情和播放音乐不太一样。它传输的通常不是连续音频,而是一些控制命令和状态数据。

我做过的项目里,BLE 主要用于这些功能:

  • 修改 EQ;
  • 切换 ANC 模式;
  • 读取耳机电量;
  • OTA 升级;
  • 查找耳机。

例如用户在 App 上切换 ANC,App 会通过 BLE 把命令发给耳机;耳机执行以后,还可能需要把最新状态返回给 App。读取电量也是类似的过程,只是数据方向和触发时机可能不同。

我接触过 GATT 的 Service、Characteristic、读写和通知,不过实际开发时,大部分数据收发还是通过 SDK 封装好的接口完成。刚开始看这些名词时,我觉得它们比较抽象。结合 TWS 耳机的功能,可以先这样理解:

  • Service 是一组相关功能的集合,例如电量服务或设备控制服务;
  • Characteristic 是服务下面具体的数据或控制接口,例如左耳电量或 ANC 模式;
  • ReadWriteNotify 是这些接口支持的不同操作方式。

可以先看下面这个例子:

耳机 GATT
├── 电量服务 Service
│   ├── 左耳电量 Characteristic
│   │   ├── Read:App 主动查询
│   │   └── Notify:耳机主动上报变化
│   ├── 右耳电量 Characteristic
│   └── 充电盒电量 Characteristic
│
└── 控制服务 Service
    ├── ANC 模式 Characteristic
    │   ├── Write:App 发送切换命令
    │   ├── Read:App 查询当前模式
    │   └── Notify:耳机通知模式变化
    └── 音量 Characteristic

例如,App 想让耳机打开 ANC,通常会找到“控制服务”下面的“ANC 模式 Characteristic”,然后向它执行 Write 操作。耳机收到命令后切换模式,如果项目支持状态通知,还可以通过 Notify 把最新模式告诉 App。

App 想查看左耳电量时,可以对“左耳电量 Characteristic”执行 Read;如果 App 订阅了 Notify,耳机电量发生变化后,也可以主动把新电量通知给 App。

因此,Characteristic 可以先理解为 Service 下面的具体数据项或功能接口。它到底支持 Read、Write 还是 Notify,要看项目定义,不能把所有功能都套成同一种方式。

三、两种连接可以同时存在,但状态要分开看

一部手机可以通过经典蓝牙连接耳机,同时再通过 BLE 与耳机建立数据连接。它们都使用蓝牙,但连接过程和业务状态并不是同一个东西。

可以把常见的关系简单理解为:

手机
├─ 经典蓝牙
│  ├─ A2DP:音乐
│  ├─ AVRCP:播放控制和音量
│  └─ HFP:通话
│
└─ BLE
   └─ GATT:EQ、ANC、电量、OTA、查找耳机等 App 功能

因此,经典蓝牙连接成功,不代表 BLE 一定已经连接;App 连上 BLE,也不能说明 A2DP 或 HFP 已经可用。

我实际遇到过经典蓝牙已经连接,但 App 扫描不到 BLE 的情况。遇到这种问题,如果只看到手机系统里显示“已连接”,很容易误以为整个蓝牙都没有问题。

后来再看这类现象,我会先把两条路径拆开:经典蓝牙是否连接是一件事,BLE 是否正在广播、App 是否能够扫描并建立连接是另一件事。至于具体原因,还需要结合当时的广播状态、App 扫描条件、连接记录和日志继续确认,不能只根据一个现象下结论。

四、应用开发时为什么要分清它们

区分经典蓝牙和 BLE,不只是为了记住几个名词,更直接的作用是避免排查错方向。

音乐没有声音时,我会先关注 A2DP 状态、音频流事件和应用侧音频资源;App 控制不了 ANC 时,则应该先检查 BLE 连接、命令收发和状态返回。两种现象都可能被描述成“蓝牙连接有问题”,但需要检查的地方并不一样。

应用代码里也不能只保留一个笼统的“蓝牙已连接”状态。至少需要知道当前说的是经典蓝牙、某个 Profile,还是 BLE 数据连接,否则不同业务很容易互相影响。

五、补充说明

这篇整理的是我目前接触较多的传统 TWS 产品:经典蓝牙负责音乐和通话,BLE 负责配套 App 的数据交互。

现在蓝牙还有 LE Audio,可以在低功耗蓝牙上承载音频。它和这里提到的 BLE App 控制不是一回事,涉及的协议和产品支持情况也更多,这篇先不展开。

对我目前的工作来说,先分清经典蓝牙和 BLE 各自在产品中负责什么,再去看 A2DP、HFP、GATT 和具体业务流程,会更容易把代码和实际功能对应起来。