蓝牙免提协议(HFP)
蓝牙免提协议(HFP)是用于手机与耳机/车机间通话控制的蓝牙协议。HFP定义了两种角色:音频网关(AG)通常是手机,免提终端(HF)通常是耳机/车机。协议通过RFCOMM通道交互AT命令实现通话控制,语音数据则通过SCO/eSCO链路传输。建立连接需先通过SDP服务发现,HFP最小SDP属性包括服务类ID、协议描述列表等。SLC(服务级连接)建立过程包括功能交换、编解码协商等步骤,需完成规定的AT
蓝牙免提协议(HFP)
本笔记为作者在学习蓝牙Host协议栈的一些心得体会,如有不对的地方,请包涵与谅解!
————by wsoz
蓝牙免提协议(HFP)
HFP(Hands-Free Profile)通俗理解就是蓝牙免提(电话)协议,主要用于手机与耳机/车机之间的通话控制与语音业务。
在协议角色上,手机通常是 AG(Audio Gateway),耳机或车机通常是 HF(Hands-Free)。双方通过 RFCOMM 通道交互标准 AT Command/Response,实现接听、挂断、拒接、语音拨号、音量同步等控制功能;而真正的通话音频数据走 SCO/eSCO 语音链路,不是通过 AT 命令传输。
协议定位
在蓝牙协议栈中,HFP的位置位于
┌─────────────────────────────────┐
│ 应用程序 (Application) │
├─────────────────────────────────┤
│ HFP (蓝牙免提协议) │ ← 应用层Profile
├─────────────────────────────────┤
│ RFCOMM (串口仿真层) │
├─────────────────────────────────┤
│ L2CAP (逻辑链路层) │
├─────────────────────────────────┤
│ HCI (主机控制接口) │
├─────────────────────────────────┤
│ Baseband (基带) │
└─────────────────────────────────┘

HFP的底层协议就是RFCOMM协议,然后该协议有两个角色:AG和HF。
-
AG(Audio Gateway):音频网关,通常是手机。负责接入蜂窝网络、维护通话状态,并向免提设备提供通话控制与音频网关能力。
-
HF(Hands-Free):免提终端,通常是蓝牙耳机或车机。通过AT命令控制通话(接听/挂断/拒接/重拨等),并通过SCO/eSCO承载语音数据。
SDP服务注册(HFP)
HFP在进入RFCOMM AT交互前,需要先通过SDP完成服务发现。
对外表现为:服务端先注册SDP记录,客户端先查SDP再连RFCOMM通道。
HFP常用UUID
| UUID-16 | 名称 | 说明 |
|---|---|---|
0x111E |
Handsfree | HFP 免提服务(HF) |
0x111F |
HandsfreeAudioGateway | HFP 音频网关服务(AG) |
HFP最小SDP属性(建议)
| Attribute ID | 名称 | 作用 |
|---|---|---|
0x0001 |
ServiceClassIDList | 声明本记录是HFP HF还是HFP AG |
0x0004 |
ProtocolDescriptorList | 描述连接栈(L2CAP + RFCOMM + Server Channel) |
0x0009 |
BluetoothProfileDescriptorList | 声明Profile及版本 |
0x0100 |
ServiceName | 便于调试识别 |
0x0311 |
SupportedFeatures | 声明支持特性位图(影响后续AT能力协商) |
ProtocolDescriptorList关键点
HFP基于RFCOMM,所以ProtocolDescriptorList里至少应包含:
[
[L2CAP, PSM=0x0003],
[RFCOMM, Server Channel=N]
]
其中Server Channel=N是客户端后续发起RFCOMM连接时必须使用的通道号。
示例
HF侧(耳机/车机)
ServiceClassIDList = [0x111E]
ProtocolDescriptorList = [[L2CAP,0x0003],[RFCOMM,Channel=2]]
BluetoothProfileDescriptorList= [[0x111E,Version=0x0107]]
ServiceName = "Handsfree"
SupportedFeatures (0x0311) = 0xXXXX
AG侧(手机/网关)
ServiceClassIDList = [0x111F]
ProtocolDescriptorList = [[L2CAP,0x0003],[RFCOMM,Channel=3]]
BluetoothProfileDescriptorList= [[0x111E,Version=0x0107]]
ServiceName = "Handsfree Audio Gateway"
SupportedFeatures (0x0311) = 0xXXXX
SLC建立连接
SLC(Service Level Connection)可以理解为:HFP中HF与AG在RFCOMM控制通道上的AT命令协商阶段。
只有双方把规定的AT命令序列交互完成(能力协商 + 指示器查询/订阅),才算SLC建立成功。
常见最小交互顺序:
AT+BRSF/+BRSF:双方能力协商AT+CIND=?/+CIND:查询AG支持的指示器AT+CIND?/+CIND:读取当前指示器状态AT+CMER=...:开启状态变化上报(如来电、通话状态)
可选交互(按版本/特性):
AT+CHLD=?:三方通话能力查询AT+BIND / AT+BIND? / AT+BIEV:HF指示器相关能力与状态
SLC成功后,才进入稳定业务阶段:拨号、接听、挂断、音量同步,以及后续的SCO/eSCO语音链路建立。
下面具体讲解一下连接建立过程:
① 支持功能交换(Supported features exchange)
首先由HF向AG发送AT+BRSF=<HF supported features>,告诉网关本地支持的特性;
当AG接收到HF特性后,会返回+BRSF: <AG supported features>(并跟随OK),完成支持特性的交换。
交互示意:
HF -> AG : AT+BRSF=<hf_features>
AG -> HF : +BRSF: <ag_features>
AG -> HF : OK
HF Supported Features(AT+BRSF参数,HF上报)
| Bit | 含义 |
|---|---|
| 0 | EC/NR 功能(回声消除/噪声抑制) |
| 1 | Call Waiting / Three-way Calling(三方通话能力) |
| 2 | CLI Presentation Capability(来电号码显示能力) |
| 3 | Voice Recognition Activation(语音识别激活) |
| 4 | Remote Volume Control(远端音量控制) |
| 5 | Enhanced Call Status(增强通话状态) |
| 6 | Enhanced Call Control(增强通话控制) |
| 7 | Codec Negotiation(编解码协商,如mSBC) |
| 8 | HF Indicators(HF指示器) |
| 9 | eSCO S4 Setting Supported(支持eSCO S4设置) |
| 10 | Enhanced Voice Recognition Status(增强语音识别状态) |
| 11 | Voice Recognition Text(语音识别文本) |
AG Supported Features(+BRSF返回值,AG上报)
| Bit | 含义 |
|---|---|
| 0 | Three-way Calling(三方通话) |
| 1 | EC/NR Function(回声消除/噪声抑制) |
| 2 | Voice Recognition Function(语音识别) |
| 3 | In-band Ring Tone Capability(带内铃声) |
| 4 | Attach Number to Voice Tag(语音标签关联号码) |
| 5 | Ability to Reject a Call(拒接来电) |
| 6 | Enhanced Call Status(增强通话状态) |
| 7 | Enhanced Call Control(增强通话控制) |
| 8 | Extended Error Result Codes(扩展错误码) |
| 9 | Codec Negotiation(编解码协商) |
| 10 | HF Indicators(HF指示器支持) |
| 11 | eSCO S4 Setting Supported(支持eSCO S4设置) |
| 12 | Enhanced Voice Recognition Status(增强语音识别状态) |
| 13 | Voice Recognition Text(语音识别文本) |
features格式:
这个特性的说法就直接按照哪个bit移动即可,例如 HF 支持 bit0、bit2、bit4:
features = 1 + 4 + 16 = 21所以直接发送AT+BRSF=21即可,AG也是如此。
快速解析方法:
如果features是十进制值,判断某bit是否支持可用:
bool support = (features & (1 << bit)) != 0;
② 编解码协商(Codec negotiation)
Codec negotiation 的作用是:在建立语音链路前,协商使用哪种语音编码。
常见编码:
| Codec ID | 编码 | 说明 |
|---|---|---|
1 |
CVSD | 窄带语音(兼容性最好) |
2 |
mSBC | 宽带语音(音质更好) |
前提条件:HF 和 AG 的 BRSF 位图里都声明支持 Codec Negotiation(对应bit置1)。
常见交互流程(简化):
HF -> AG : AT+BAC=1,2 // HF上报本端支持的编码列表
AG -> HF : OK
AG -> HF : +BCS:2 // AG选择mSBC(示例)
HF -> AG : AT+BCS=2 // HF确认使用该编码
AG -> HF : OK
随后建立/更新 SCO/eSCO 语音链路
说明:
- 如果协商失败或对端不支持宽带语音,通常会回退到
CVSD (Codec ID=1)。 - 没有Codec negotiation能力时,一般默认按CVSD进行语音通话。
格式说明:
AT+BAC=<codec_id1>[,<codec_id2>,...]即是直接发即可
AT+BAC=1,2 支持CVSD以及mSBC编解码功能 AT+BAC=1仅支持CVSD编解码功能
③ AG状态指示器(AG Indicators)
AG Indicators可以理解为:AG(手机)暴露给HF的状态字段,HF通过这些字段感知当前电话状态。
常见指标:
| Indicator | 含义 |
|---|---|
service |
是否有移动网络服务 |
call |
是否处于通话中 |
callsetup |
呼叫建立过程状态(来电/外呼) |
callheld |
是否存在保持通话 |
signal |
信号强度 |
roam |
是否漫游 |
battchg |
手机电量等级 |
常见交互顺序:
HF -> AG : AT+CIND=? // 查询AG支持哪些indicator及取值范围
AG -> HF : +CIND: (...)
AG -> HF : OK
HF -> AG : AT+CIND? // 查询当前indicator值
AG -> HF : +CIND: <v1>,<v2>...
AG -> HF : OK
HF -> AG : AT+CMER=3,0,0,1 // 开启indicator变化上报
AG -> HF : OK
开启CMER后,AG状态变化会通过+CIEV异步上报给HF:
AG -> HF : +CIEV: <index>,<value>
注意:index对应AT+CIND=?返回的indicator顺序,所以实现时通常要先保存映射关系。
格式说明:
AT+CIND=?:查询AG支持的indicator定义(名称+取值范围)
AT+CIND?:查询当前indicator实时值
AT+CMER=<mode>,<keyp>,<disp>,<ind>:控制指示器上报
常用:AT+CMER=3,0,0,1(开启上报) / AT+CMER=3,0,0,0(关闭上报)
其中参数可简易理解为:
| 参数 | 含义 | 常用值 |
|---|---|---|
mode |
上报模式(HFP里通常用实时上报模式) | 3 |
keyp |
按键事件上报开关(HFP中一般不用) | 0 |
disp |
显示事件上报开关(HFP中一般不用) | 0 |
ind |
AG indicator上报总开关 | 1开 / 0关 |
+CIEV:<index>,<value>:AG异步上报某个indicator的新值(index按CIND=?顺序映射)
+CIEV里的value含义取决于具体indicator,例如:call常见 0/1,callsetup常见 0~3,signal常见 0~5。
例子(按常见顺序):
AT+CIND=?
+CIND: ("service",(0,1)),("call",(0,1)),("callsetup",(0-3)),("callheld",(0-2)),("signal",(0-5)),("roam",(0,1)),("battchg",(0-5))
其中返回的可以看出索引以及取值范围
来电流程中的+CIEV可读成:
+CIEV: 3,1 // callsetup=1,表示来电中
+CIEV: 2,1 // call=1,表示已进入通话
+CIEV: 3,0 // callsetup=0,呼叫建立流程结束
+CIEV: 2,0 // call=0,表示通话结束
AT+BIA=<i1>,<i2>,...,<in>(可选):按indicator顺序逐项开关上报(1允许,0屏蔽)
示例:AT+BIA=1,1,1,1,0,1,0 表示按顺序关闭第5和第7项上报。
④ 通话保持与多方通话能力查询(CHLD)
这一步通常用于确认AG支持哪些呼叫保持/三方通话控制命令。
前提一般是HF与AG在BRSF里都声明了相关能力(常见为bit1)。
典型交互:
HF -> AG : AT+CHLD=? // 查询AG支持哪些CHLD操作
AG -> HF : +CHLD: (0,1,1x,2,2x,3)
AG -> HF : OK
常见CHLD含义(不同设备实现可能有差异):
| 命令 | 常见含义 |
|---|---|
AT+CHLD=0 |
释放保持中的通话或拒接等待来电 |
AT+CHLD=1 |
释放当前活动通话,接听等待/保持通话 |
AT+CHLD=1x |
释放索引为x的指定通话 |
AT+CHLD=2 |
保持当前活动通话,并接听等待/保持通话 |
AT+CHLD=2x |
保持除索引x外的所有通话,并恢复x |
AT+CHLD=3 |
加入多方通话(会议) |
说明:
AT+CHLD=?属于能力查询,通常放在SLC建立阶段。- 实际通话中再按需发送
AT+CHLD=<op>执行控制。 - 若AG不支持某些操作,可能不会出现在
+CHLD:返回列表中。
格式说明:
AT+CHLD=?:查询AG支持的CHLD操作集合(能力查询)
+CHLD: (0,1,1x,2,2x,3):AG返回支持的操作列表;列表里没有的操作通常不可用
AT+CHLD=<op>:执行具体通话控制操作(op可为0/1/1x/2/2x/3)
其中x是通话索引,一般配合AT+CLCC返回的idx使用(如AT+CHLD=12表示执行1x且x=2)。
示例:
AT+CLCC // 先查看当前通话列表和idx
AT+CHLD=2 // 保持当前活动通话并接听等待通话
AT+CHLD=11 // 释放idx=1的通话(1x)
⑤ HF Indicators(BIND / BIEV)
这部分是HFP 1.7引入的可选能力,用于让HF把本地状态(如耳机电量)上报给AG。
前提通常是HF和AG在BRSF里都声明支持 HF Indicators(常见bit8/bit10相关能力位)。
常见HF Indicator类型:
| Indicator ID | 含义 |
|---|---|
1 |
Enhanced Safety(增强安全) 0-1 |
2 |
Battery Level(HF电量等级) 0-100 |
常见交互(简化,具体顺序依实现可能有差异):
HF -> AG : AT+BIND=1,2 // HF声明本端支持的HF indicators
AG -> HF : OK
HF -> AG : AT+BIND=? // 查询AG支持哪些HF indicators
AG -> HF : +BIND: (1,2)
AG -> HF : OK
HF -> AG : AT+BIND? // 查询当前已启用的HF indicators
AG -> HF : +BIND: 1,1
AG -> HF : +BIND: 2,1
AG -> HF : OK
当HF状态变化时(例如耳机电量变化),可发送:
HF -> AG : AT+BIEV=2,<level> // 上报HF电量
AG -> HF : OK
说明:
BIND主要做能力与启用状态协商,BIEV用于运行期状态上报。AT+BIEV一般在SLC完成后使用。- 若对端不支持HF Indicators,通常不会进入这组流程。
格式说明:
AT+BIND=<ind1>[,<ind2>...]:HF声明本端支持的HF Indicator ID列表
示例:AT+BIND=1,2
AT+BIND=?:查询AG支持哪些HF Indicator ID
返回示例:+BIND: (1,2)
AT+BIND?:查询当前已启用的HF Indicator状态
返回格式:+BIND: <id>,<enabled>
其中:enabled=1表示启用,enabled=0表示未启用。
AT+BIEV=<id>,<value>:HF运行期上报某个HF Indicator的新值
示例:AT+BIEV=2,85(上报HF电量85)
常见value取值:
id=1(Enhanced Safety):0/1id=2(Battery Level):0~100
注意:AT+BIEV一般在SLC建立后、且对应indicator已启用时发送。
下图为HF的SLC建立流程:

SLC断开连接
SLC断开本质上是HFP控制面(RFCOMM AT通道)被释放。 本质就是断掉HFP 对应 RFCOMM 的 server channel。
注意区分:
AT+CHUP是“挂断通话”,不等于断开SLC。- SLC断开后,后续若要继续HFP控制,需重新建立SLC。
推荐断开顺序(有语音通话时)
- 先结束通话业务(若仍在通话)
- 释放SCO/eSCO语音链路
- 释放RFCOMM控制通道(SLC结束)
- 视系统策略决定是否继续断开ACL链路
典型交互(简化)
HF主动断开SLC:
HF -> AG : RFCOMM DISC (DLCI=HFP通道)
AG -> HF : RFCOMM UA
AG主动断开SLC:
AG -> HF : RFCOMM DISC (DLCI=HFP通道)
HF -> AG : RFCOMM UA
若继续释放ACL,常见会看到:
HCI_Disconnect
HCI_Disconnection_Complete (Reason=0x13/0x16/0x08...)
抓包判断要点
- 看到RFCOMM
DISC/UA,即可判定SLC控制通道正常关闭。 - 只看到
AT+CHUP而没有DISC/UA,通常表示“仅通话结束,SLC仍在”。 - 若直接出现
HCI_Disconnection_Complete而无DISC/UA,多为链路异常或底层直接断链。
手机状态信息
手机状态信息(AG Indicators)上报可分为两层控制:
-
全局开关(CMER)
- 开启:
AT+CMER=3,0,0,1,默认全部的状态信息上报都开启 - 关闭:
AT+CMER=3,0,0,0
其中最后一位ind才是指示器上报开关。
- 开启:
-
单项开关(BIA)
AT+BIA=<i1>,<i2>,...,<in>按AT+CIND=?返回顺序,对每个indicator逐项控制:1= 允许上报0= 屏蔽上报
示例:
若有7个indicator,且只想关闭signal和battchg,可发:
AT+BIA=1,1,1,1,0,1,0
信号强度(Strength Indication)
这个特性就是 AG 把本地的信号发送给 HF,值得范围是0-5来表示信号强度,就是手机信号5格表示一样。
漫游状态(Roaming Status Indication)
这个特性就是 AG 把漫游状态发送给 HF,其中漫游状态指的就是手机当前是否在“非归属网络”上注册(比如跨运营商/跨区域网络)
- roam=1,漫游中
- roam=0,未漫游
电量信息(Battery Level Indication)
这个特性就是 AG 把电量信息状态发送给 HF,电量信息范围在0-5,分别对应0%、20%、40%、60%、80%、100%。
运营商查询(Query Operator Selection)
这个功能用于让HF查询AG当前注册的蜂窝运营商名称(例如中国移动/中国联通)。
常见交互(简化):
HF -> AG : AT+COPS=3,0 // 设置返回格式为长字符串名称
AG -> HF : OK
HF -> AG : AT+COPS? // 查询当前运营商
AG -> HF : +COPS: 0,0,"CHINA MOBILE"
AG -> HF : OK
格式说明:
AT+COPS=3,0:设置运营商显示格式(常见为长字母名称)
AT+COPS?:查询当前运营商
+COPS:<mode>,<format>,<oper>:AG返回运营商信息
字段简易说明:
<mode>:选择模式,常见0(自动)<format>:运营商字段格式0= 长字母名称(如"CHINA MOBILE")1= 短字母名称2= 数字编码(MCC/MNC)
<oper>:运营商名称或编码
注意:通常在SLC建立后查询更稳定;若当前无网络服务,<oper>可能为空或不可用。
用户号码信息(Subscriber Number Information)
这个功能用于HF主动查询AG侧“本机号码”信息(若可用)。
常见交互:
HF -> AG : AT+CNUM
AG -> HF : +CNUM: "My Number","+8613800138000",145,7
AG -> HF : OK
格式说明:
AT+CNUM:查询本机号码信息
+CNUM: <alpha>,<number>,<type>,<service>:AG返回号码记录
字段简易说明:
<alpha>:号码标签(可为空)<number>:本机号码(可为空)<type>:号码类型(常见129普通,145国际)<service>:业务类型(常见4语音、5传真、7语音+传真,依实现而异)
注意:很多手机/SIM不会返回有效本机号,所以+CNUM为空或不返回都很常见。
扩展错误信息(Extended Audio Gateway Error Results)
这个特性用于让AG在命令失败时返回更详细错误信息,而不是只回一个笼统的ERROR。
常见交互:
HF -> AG : AT+CMEE=1 使能
AG -> HF : OK
开启后,若后续命令失败,可能返回:
AG -> HF : +CME ERROR: <err_code>
格式说明:
AT+CMEE=<n>:设置扩展错误返回方式
常见取值(按实现):
0:关闭扩展错误(通常只返回ERROR)1:返回数字错误码(常见)2:返回文本错误信息(部分实现支持)
+CME ERROR:<err_code>:AG返回具体错误原因码,HF可据此做更精确的失败定位。
注意:是否支持该功能取决于AG能力(通常与+BRSF中的扩展错误位相关)。
电话状态(Transfer of Call Status)
这个特性用于让AG把通话相关状态实时上报给HF,核心是3个indicator:call、callsetup、callheld。
| Indicator | 取值 | 含义 |
|---|---|---|
call |
0/1 |
0无通话;1有通话 |
callsetup |
0~3 |
0无建立过程;1来电中;2外呼拨号中;3外呼振铃中 |
callheld |
0~2 |
0无保持;1有保持且有活动通话;2仅有保持通话 |
这些状态通常通过+CIEV:<index>,<value>上报(index按AT+CIND=?顺序映射)。
来电到挂断示例(假设 2=call,3=callsetup):
+CIEV: 3,1 // 来电中(callsetup=1)
+CIEV: 2,1 // 接听后进入通话(call=1)
+CIEV: 3,0 // 建立流程结束(callsetup=0)
+CIEV: 2,0 // 挂断后无通话(call=0)
呼叫控制流程(HF视角)
本章主要关注AT控制面:来电、接听、拒接、外呼、重拨、挂断等流程。
AG侧来电
先了解一下带内铃声(In-band ring):来电铃声由AG(手机)通过蓝牙音频链路传给HF(耳机/车机)播放。它是AG的一个能力位(+BRSF相关bit)。
In-band ring = 1:支持带内铃声In-band ring = 0:不支持带内铃声
如果支持带内铃声,通常来电阶段就会建立SCO/eSCO;HF在收到RING/来电状态后可直接听到铃声。
如果不支持带内铃声,来电阶段通常不建立SCO/eSCO,而是在call active后才建立。
**总结:**是否支持带内铃声,主要影响“音频链路是在来电阶段建立,还是在接听后建立”。
AG侧来电时,会主动给HF上报来电提示,常见为:
AG -> HF : RING
若开启来电号码显示(CLIP),通常还会看到:
AG -> HF : +CLIP: "<number>",<type>
注意:RING会不断发送,直到接听、拒接或超时结束。
HF侧接听来电
HF侧接听来电直接发送AT指令即可,之后call进入active状态。
HF -> AG : ATA
AG -> HF : OK
接听后,AG会通过+CIEV继续上报状态变化。
下图为支持带内铃声和不支持带内铃声的交互流程图:


通话中第二路来电(Call Waiting Notification)
该场景指的是:当前已经在通话中(call=1),又来了新的来电。
我们在SLC建立过程中如果HF和AG都支持该功能的话,我们后续HF还需要手动开启才可以支持该功能
- AT+CCWA=1 开启第二路来电
- AT+CCWA=0 关闭第二路来电
AG常见会给HF上报等待来电通知(若支持):
AG -> HF : +CCWA: "<number>",<type> //type-129普通号码 type-145国际
AG -> HF : +CIEV: <callsetup_index>,1 // 进入来电建立状态
AG只是负责讲状态上报到HF,HF端可以用CHLD配合进行处:
HF -> AG : AT+CHLD=2 // 保持当前通话并接听待来电
AG -> HF : OK
也可根据策略执行其他CHLD操作,例如:
AT+CHLD=0:拒接等待来电AT+CHLD=1:释放当前活动通话并接听等待来电
核心点:这是“第二路来电通知”,不是当前通话结束;call通常保持为1。
来电号码显示
来电号码显示就是CLIP(Calling Line Identification Presentation),用于在来电时把主叫号码上报给HF。
常见控制方式:
AT+CLIP=1:开启来电号码显示上报AT+CLIP=0:关闭来电号码显示上报
常见交互:
HF -> AG : AT+CLIP=1
AG -> HF : OK
AG -> HF : RING
AG -> HF : +CLIP: "13800138000",129
格式说明:
+CLIP: "<number>",<type>
<number>:来电号码<type>:号码类型(TON/NPI)129:普通号码145:国际号码(常见带+)
注意:是否实际上报+CLIP还取决于网络侧是否提供主叫号码。
来电降噪
来电降噪主要指HFP中的EC/NR能力:
EC(Echo Cancelling):回声消除,减少扬声器回灌到麦克风产生的回声NR(Noise Reduction):噪声抑制,降低环境噪声(风噪、路噪、背景声)
该能力通常在BRSF功能交换阶段体现(对应EC/NR相关bit)。
常见控制命令(按实现支持):
HF -> AG : AT+NREC=0
AG -> HF : OK
含义:HF通知AG关闭AG侧EC/NR(常用于HF端自己已做语音处理的场景)。
若AG不支持或不允许控制,可能返回ERROR或忽略该命令。
注意:这个命令本质上是修改AG 内部的 EC/NR(回声消除/噪声抑制)处理链。当然HF侧也可以自己做降噪,常见的就是HF做主处理,AG侧处理弱化或关闭。
语音识别激活(Voice Recognition Activation)
这个功能在耳机/车机场景下:HF可以不拿起手机,直接远程唤起AG(手机)侧语音助手或语音拨号。(功能比较鸡肋)
常见控制命令:
HF -> AG : AT+BVRA=1 // 启动语音识别
AG -> HF : OK
HF -> AG : AT+BVRA=0 // 停止语音识别
AG -> HF : OK
部分实现中,AG状态变化时还会主动上报:
AG -> HF : +BVRA: 1 // 语音识别已开启
AG -> HF : +BVRA: 0 // 语音识别已关闭
前提:HF和AG在BRSF能力交换时都声明支持Voice Recognition相关能力。
HF侧拒绝来电/挂断通话
HF侧拒绝来电,或断开正在进行的通话,通常都直接发送挂断命令:
HF -> AG : AT+CHUP
AG -> HF : OK
拒接成功后,AG一般会停止RING并上报状态恢复,例如:
AG -> HF : +CIEV: <callsetup_index>,0 // 来电建立流程结束
常见结果:
callsetup回到0call保持0(未进入通话)
如果AG端拒绝来电/断开通话,AG同样会上报+CIEV状态变化。
HF主动拨号
HF侧主动外呼通常使用ATD<number>;,其中分号;表示语音呼叫。
常见交互(简化):
HF -> AG : ATD10086;
AG -> HF : OK
随后AG会通过+CIEV上报通话建立状态(按常见映射:2=call,3=callsetup):
+CIEV: 3,2 // callsetup=2,外呼拨号中
+CIEV: 3,3 // callsetup=3,对端振铃中
+CIEV: 2,1 // call=1,通话建立
+CIEV: 3,0 // callsetup=0,建立流程结束
若对端未接听或失败,常见表现是callsetup回到0。
HF重拨(Redial Last Number)
HF可使用重拨命令拨打最近一次号码:
HF -> AG : AT+BLDN
AG -> HF : OK
后续状态上报与主动拨号一致,通常也是callsetup: 2 -> 3 -> 0,接通后call=1。
拨号过程按键
AT+VTS用于在通话中发送DTMF按键音(双音多频),常见场景是拨打客服电话后按1、2、#进行菜单选择。
常见格式:
AT+VTS=<dtmf>
示例(通话中输入“1#”):
HF -> AG : AT+VTS=1
AG -> HF : OK
HF -> AG : AT+VTS=#
AG -> HF : OK
注意:
- 一般在通话建立后使用(
call=1)。 - 多位按键通常逐个发送,不建议一次性拼成长串。
- 这里需要注意一点,AT+VTS=后面的数字是 acsii 编码,比如你要发送AT+VTS=1,那么这个 1 其实并不是 0x01,而是 0x31。我们自己状态AT包时就直接用字符就可以。
音量控制
音量控制(Remote Audio Volume Control)用于在通话中同步HF与AG的音量状态。
常见命令:
AT+VGS=<gain>/+VGS:<gain>:扬声器音量(Speaker Gain)AT+VGM=<gain>/+VGM:<gain>:麦克风音量(Microphone Gain)
<gain>常见范围是0~15。
常见方向:
- HF本地按音量键后,HF可上报给AG:
AT+VGS=<gain> - 手机侧音量变化后,AG也可能主动通知HF:
+VGS:<gain>
示例(通话中把扬声器音量调到10):
HF -> AG : AT+VGS=10
AG -> HF : OK
示例(手机侧主动把音量改到12并通知HF):
AG -> HF : +VGS: 12
示例(手机侧主动把麦克风增益改到8并通知HF):
AG -> HF : +VGM: 8
说明:VGS/VGM通常使用**“绝对音量值”**同步,不是“加一/减一”增量命令。
HF侧结束外呼
在外呼建立过程中或通话中,HF都可通过:
HF -> AG : AT+CHUP
AG -> HF : OK
结束后常见状态回落:
+CIEV: 2,0 // call=0
+CIEV: 3,0 // callsetup=0
音频连接与转移(Audio Connection)
SLC负责控制面(能力协商、状态上报、拨号/接听/挂断等);
Audio连接负责语音面(SCO/eSCO),用于传输真实通话音频数据。
对于SCO/eSCO连接,可以由AG发起,也可以由HF发起;此处主要看HF主动建立。
HF主动建立SCO
前提条件:
- ACL链路已建立
- SLC已建立
- 若走宽带语音(mSBC),通常已完成
AT+BAC / +BCS / AT+BCS协商
常见流程:
HF -> AG : AT+BCC // HF请求发起音频连接建立(常见实现)
AG -> HF : OK
随后进入HCI同步连接建立(SCO/eSCO)
**注意:**如果在SLC阶段进行了codec协商,AG可能会对codec进行再次确认:
AG -> HF : +BCS:<codec_id> // 编解码确认
HF -> AG : AT+BCS:<codec_id>
AG -> HF : OK
通话中音频转移
这个场景指的是:通话不断开(call仍为1),只切换语音路径(手机听筒 ↔ HF设备)。
常见有两种方向:
-
AG本地音频 -> HF设备
- HF可通过
AT+BCC请求把音频拉到蓝牙链路 - 后续建立/恢复 SCO/eSCO
- HF可通过
-
HF设备音频 -> AG本地
- 通常通过释放 SCO/eSCO 实现(由AG或HF侧策略触发)
- 通话本身继续进行,SLC一般保持
典型交互(HF把音频拉到本机):
HF -> AG : AT+BCC
AG -> HF : OK
... HCI同步连接建立 ...
... 出现SCO Data ...
转回AG本地音频(通话不断)常见表现:
... HCI同步链路断开(SCO/eSCO release) ...
... 不出现AT+CHUP ...
... call状态通常仍为1 ...
抓包判断要点:
- 音频转移看的是SCO/eSCO的建立/释放,不是看
AT+CHUP - 若出现
AT+CHUP,那是结束通话,不是“仅转移音频路径”
常用AT指令表
| AT指令 | 用途说明 |
|---|---|
AT+BRSF=<features> |
HF上报本端支持能力(SLC能力交换) |
AT+BAC=<codec_id1,...> |
HF上报支持的语音编解码列表 |
AT+BCS=<codec_id> |
HF确认AG选择的编解码 |
AT+BCC |
HF请求建立/拉起音频链路(SCO/eSCO) |
AT+CIND=? |
查询AG支持的indicator定义与范围 |
AT+CIND? |
查询AG当前indicator状态值 |
AT+CMER=<mode>,<keyp>,<disp>,<ind> |
控制AG indicator上报总开关(常用AT+CMER=3,0,0,1) |
AT+BIA=<i1>,<i2>,...,<in> |
按indicator顺序逐项开关上报 |
AT+CHLD=? |
查询AG支持的多路通话控制操作 |
AT+CHLD=<op> |
执行多路通话控制(等待/保持/切换/会议) |
AT+CCWA=1/0 |
开启/关闭呼叫等待通知(第二路来电) |
AT+CLIP=1/0 |
开启/关闭来电号码显示 |
AT+NREC=0/1 |
控制AG侧EC/NR(回声消除/噪声抑制) |
AT+BVRA=1/0 |
启动/停止AG侧语音识别(语音助手) |
ATA |
接听来电 |
AT+CHUP |
拒接来电或挂断当前通话 |
ATD<number>; |
主动发起语音呼叫 |
AT+BLDN |
重拨最近一次号码 |
AT+VTS=<dtmf> |
通话中发送DTMF按键音 |
AT+VGS=<gain> |
设置扬声器音量(Speaker Gain) |
AT+VGM=<gain> |
设置麦克风增益(Microphone Gain) |
AT+BIND=<id1,...> |
HF声明支持的HF Indicators列表 |
AT+BIND=? |
查询AG支持哪些HF Indicators |
AT+BIND? |
查询当前已启用的HF Indicators |
AT+BIEV=<id>,<value> |
HF上报本地indicator状态(如HF电量) |
AT+COPS=3,0 |
设置运营商名称返回格式(长字符串) |
AT+COPS? |
查询当前运营商信息 |
AT+CNUM |
查询AG侧本机号码信息(若可用) |
AT+CMEE=<n> |
设置扩展错误上报方式(返回+CME ERROR) |
AT+CLCC |
查询当前通话列表(常与CHLD联动) |
| D=?` | 查询AG支持的indicator定义与范围 |
AT+CIND? |
查询AG当前indicator状态值 |
AT+CMER=<mode>,<keyp>,<disp>,<ind> |
控制AG indicator上报总开关(常用AT+CMER=3,0,0,1) |
AT+BIA=<i1>,<i2>,...,<in> |
按indicator顺序逐项开关上报 |
AT+CHLD=? |
查询AG支持的多路通话控制操作 |
AT+CHLD=<op> |
执行多路通话控制(等待/保持/切换/会议) |
AT+CCWA=1/0 |
开启/关闭呼叫等待通知(第二路来电) |
AT+CLIP=1/0 |
开启/关闭来电号码显示 |
AT+NREC=0/1 |
控制AG侧EC/NR(回声消除/噪声抑制) |
AT+BVRA=1/0 |
启动/停止AG侧语音识别(语音助手) |
ATA |
接听来电 |
AT+CHUP |
拒接来电或挂断当前通话 |
ATD<number>; |
主动发起语音呼叫 |
AT+BLDN |
重拨最近一次号码 |
AT+VTS=<dtmf> |
通话中发送DTMF按键音 |
AT+VGS=<gain> |
设置扬声器音量(Speaker Gain) |
AT+VGM=<gain> |
设置麦克风增益(Microphone Gain) |
AT+BIND=<id1,...> |
HF声明支持的HF Indicators列表 |
AT+BIND=? |
查询AG支持哪些HF Indicators |
AT+BIND? |
查询当前已启用的HF Indicators |
AT+BIEV=<id>,<value> |
HF上报本地indicator状态(如HF电量) |
AT+COPS=3,0 |
设置运营商名称返回格式(长字符串) |
AT+COPS? |
查询当前运营商信息 |
AT+CNUM |
查询AG侧本机号码信息(若可用) |
AT+CMEE=<n> |
设置扩展错误上报方式(返回+CME ERROR) |
AT+CLCC |
查询当前通话列表(常与CHLD联动) |
更多推荐
所有评论(0)