排查无法收到蓝牙设备语音流的问题时,发现仅仅阅读 SDK 源代码很难定位到问题根源,主要是不了解整个通信过程。 所以阅读了一下 STM32WB 的官方专题文档,确实收获不少。
文档地址
https://www.stmcu.com.cn/Article/ArticleCat/cat_code/mkt_info/art_id/2121
报警推送
opus 服务下有两个 notify 特性:
- Audio 特性。用于对讲
- Ctrl 特性。用于发送控制数据。这个可以作为报警信息接收使用。
之前没仔细看,以为两个特性 id 一致,实际上不一样。正好区分了音频和控制功能。
手机 App 和蓝牙设备在对讲中的角色
- App 扮演的 BVLCentral 的角色,即 Central Unit (Master)
- 蓝牙设备扮演 Peripheral Unit (Slave)
指示灯对应的不同状态
- 广播/发现状态:绿色LED闪烁
- 连接状态:蓝色LED缓慢闪烁
- 语音流状态:蓝色LED正常闪烁
- 接收状态:蓝色LED稳定点亮(不闪烁)
- 全双工状态:蓝色LED快速闪烁(双方设备)
应用流程图
这个流程图绝对的良心,太细致了。看一遍好多现有的疑惑都解开了。
- 建立连接之后,服务与特性的发现是双向的。即,手机 app 也有一套对应的服务和特性。否则不可能实现全双工。
- Enable Notification 的过程。建立连接后,首先由蓝牙设备发起 Enable Notification Request (注意,需要按下板子上的按钮,即 Start Streaming),然后由 app 向蓝牙设备发起 Enable Notification。然后由蓝牙设备向 app 发送 Notification,即语音。此时,蓝牙设备的状态 status 变为 streaming,app 的状态变为 receiving。文档中说明也很易懂,"从设备通过按钮,请求打开特性通知,主设备打开通知,从设备发送语音流,此时状态为语音流状态。"
- APP 上点击开始录音按钮,后面的逻辑是,由 app 向蓝牙设备发送 Enable Notification Request, 然后蓝牙设备向 app 发送 Enable Notification (实际上是就是修改 CCCD 的值)。此时,双方状态 status 均变为 Full Duplex。
到这里,我大概明白了为何我的手机上默认收不到蓝牙设备发送来的语音,需要点一下板子上的按钮才能收到。实际上就是触发了 app 修改 cccd 值的操作。
而另一个 android 11 手机上一直正常,猜测是其安装的 app 版本低,跟我手机上的 app 版本不一致,其可以主动修改 cccd 值,而不需要按按钮发起。
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式