蓝牙HFP协议概述
HFP(Hands-Free Profile),蓝牙电话协议,可以让蓝牙设备通过协议定义好的 AT command 控制电话,如接听、挂断、拒接、语音拨号等。每个功能都有特定的 AT command 和 response.
HFP 底层是 RFCOMM 协议,并且具有双角色(AG 和 HF),Audio Gateway (AG)就是手机,Hands-Free unit (HF)就是蓝牙耳机
HF连接建立
需要现有用于HF的RFCOMM通道,而且还要进行一些AT命令交互,这些命令交互成功之后,才叫HFP SLC(Service Level Connection)建立
-
充当 HF 角色首先要发送 AT+BRSF=<HF supported features>,
AG 会回复+BRSF=<AG supported features>
BRSF (Bluetooth Retrieve Supported Features),此命令就是用于 HF 和 AG
互相告知对方支持的特性,彼此记录下来对方支持的 feature,这样要使用某一
个功能,双方都知道彼此是否支持,HF&AG 的 support feature 都是一个 32bit的数, 1-11位代表具体功能是否支持,12-32保留 -
如果 HF 和 AG 都支持 BRSF 中的 Codec negotiation,那么 HF 发送:
AT+BAC=<HF available codecs>
整个 BAC 的概念是可用的编码(Bluetooth Available Codecs),这个命令是 HF 告知 AG,自己支持的 codec,CVSD 就是 NBS(窄带通话,8KHz)的编解码方式,mSBC 就是 WBS(宽带电话,16KHz)的编解码方式,CVSD必须支持,msbc可选支持 -
发送 AT+CIND=?问询支持的 indicators
(包括 service/call/callsetup/callheld/signal/roam/battchg)的 index
AT+CIND=?是问询 AG 有多少 indicators,并且自己解析每个 indicators 的 index
发送 AT+CIND?问询各个 indicators 的 status∂
发送 AT+CMER enable 各个 indicators,发送这个后,如果某一个 indicator
有变化,那么 AG 就可以发送+CIEV 来告知
AT+CMER 是 Standard event reporting activation/deactivation AT command.
说白了就是使能/失能 indicator,一共有两种格式
AT+CMER=3,0,0,1 activates “indicator events reporting”.
AT+CMER=3,0,0,0 deactivates “indicator events reporting”.
使能之后,AG 可以发送+CIEV 命令来汇报各个 indicator 的变化
我们前面也提到到+CIEV,终于说到了,我们来看下+CIEV AT command
+CIEV:Standard “indicator events reporting” unsolicited result code.
格式为:+CIEV: ,,举例来说(此部分要根据 AT+CIND=?问询到的
index 来解析,每个 AG 可能 index 不同,所以代码中有解析 index 的动作,我
这个 index 是根据 2.1.3 小节的 index 来讲解)
如果后续 AG 发送过来 +CIEV:1,x 那么就是 service 有变化,值为 x,
如果 AG 发送过来+CIEV:5,x 那么就是 signal 有变化,值为 x
以上三个发送完毕后,如果 HF&AG 都支持三方通话,那么发送 AT+CHLD=?
此部分是 HF 问询 AG 三方通话的支持的特性都有哪些 -
如果 HF & AG 都支持 HF Indicators 的 feature,那么 HF 发送 AT+BIND=来告知 AG 支持那些 indicator,HFP 的 indicator
一共有两个,Enhanced Safety (0,1), Battery Level (0-100)
发送 AT+BIND=?问询 AG 支持哪些 indicator
发送 AT+BIND?问询 AG 哪些 indicator 是 enable 的
发送 AT+BIEV 来使能某一个 indicator
断开HFP的链接就是断开rfcomm上hfp的通道
AT+CMER 是全局 Active/deactive ,AT+BIA,那这个命令的作用
就是 active/deactive 某一个 indicator,整个 AT+BIA 的命令如下:
举例:假设有 7 个 indicator,index 是根据 AT+CIND=?得到,使能全局是
AT+BIA=1,1,1,1,1,1,1
失能全部 AT+BIA=0,0,0,0,0,0,0
如果要失能第 3 个,可以写成这样 AT+BIA=1,1,0,1,1,1,1
也可以写成这样 AT+BIA=1,1,0,后续参数自动忽略,采用默认
Audio Connection handling
Audio connection handing 分为 3 个部分介绍:
Audio Connection set up:Audio 的建立,也就是 SCO 的建立
Audio Connection release:Audio 的释放,也就是 SCO 的释放
Codec Connection set up:Codec 的建立,也就是协商 NBS/WBS 的过程
AG端发起连接时
HF 端的 btsnoop 流程是:
1) 收到 controller 发送的 connect request(type 是 sco)的 event
2) HF host 发送 accept sco connect request 的 command 给 controller
3) 收到 controller 发送 sco connection complete 的 event 给 host
HF端发起连接时
先发送AT+BCC命令,收到OK回复,然后AG端就会发起连接
Codec connection 的建立也很简单,在 SLC 建立得而时候如果发送过 AT+BAC,
那么 AG 会发送+BCS 选择 codec id,HF 回复 AT+BCS 回复相同的 codec id,然后
AG 回复 OK.个人理解,这个所谓的codec connection,其实用的还是SLC链路,就是在上面发特定的AT命令的过程而已;不过话又说回来,SLC其实也是发一堆AT命令的过程
Accept an incoming voice call
支持 in band ring 的 AG 在 incoming call 的时候,会先建立 audio connection(SCO),然后在 RING AT command 之后传过来声音,也就是手机铃声,直到被接听或者挂断,或者其他原因中断incoming call 为止,而 no in band ring 是在 call active 的时候才会建立 SCO,所以此时候 HF 要在 incoming call 的时候自己做一个铃声。
通过上图可以看出,在+CIEV callsetup=incoming 的后面就建立了(E)SCO 的连线,然后后面会有 AG 给 HF 的 RING command 以及可选的 CLIP 命令,直到 HF 发送 ATA 的 AT command 接听,call 状态进去 active
下面我们就来看下以上 in band ring 和 no in band ring 的差别:
支持 In band ring 的 AG 首先会建立 SCO,然后每次发送 RING command 给 HF 后,
都会发送 ring tone(铃声)给 HF,而 no in band ring AG 只会间隔发送 RING
command 给 HF,等到接听后才会建立 SCO.
还记得我们播打电话的“嘟“的声音吗?对于 Remote
(这是并不是指 AG,是指给 AG 打电话的人)嘟的响一声,那么 HF 就会响应的
收到一个 RING 的指令
如果是在AG端接听或者挂断的话,AG端只会通过+CIEV更新callsetup和call
HF 通过 ATA来接听电话,AT+CHUP 来拒绝来电,ATD来呼出电话,比如ATD10086
ATD>nnn…;就是拨打特定键盘存储的号码,比如我们设置的 1 为 10086,那么我们发送 ATD>1;就会自动拨打 10086
AT+BLDN拨打最后一次号码的功能,也就是末号重播功能
三方通话