1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论
2. 欢迎大家关注和订阅,【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待!
1. 协议架构
1.1 Profile Dependencies
在蓝牙电话的数据传输中使用的是SCO协议(同步定向链接)。支持对时延敏感的信息如语音。
使用保留带宽进行同步通信,即两台设备在LMP层利用保留时隙在物理信道上周期传送数据包,这种类型的链接主要用于传送SCO包(语音数据)。SCO不包括CRC码,且不进行重传,主要支持传输有时间限制的信息,例如声音。
仅仅在ACL链接已经建立之后,才可以建立SCO链接;
-
AT CMD:AT指令是应用于终端设备和PC应用之间的连接与通信的指令;
-
SPP:蓝牙串口协议,在蓝牙设备之间建立虚拟的串口进行数据通信,简单的说就是两个蓝牙设备对端发送自定义数据;iPhone不支持SPP协议;
-
GAP:通用访问配置文件,该Profile保证不同的Bluetooth产品可以互相发现对方并建立连接;GAP定义了蓝牙设备如何发现和建立与其他设备的安全/不安全连接,它处理一些一般模式的业务(询问、命名和搜索)和一些安全性问题;GAP一般有4个作用:
- Profile Role
- 可发现模式和过程
- 连接模式和过程
- 安全模式和过程
-
eSCO:可以简单的理解为和SCO不同点:支持数据包的重传;
-
incoming call:由Phone Network到AG的通话,即称为来电;
-
outgoing call:由AG到Phone Network的通话,即称为拨号,去电;
1.2 HFP Protocol Stack
针对蓝牙电话,涉及到的协议有:HFP、RFCOMM;
目前HFP的使用场景常见的有车载蓝牙、耳机、PDA(Personal Digital Assistant - 掌上电脑,类似于智能手机、平板电脑、手持游戏机等),其中HFP协议中定义了AG和HFP两种角色:
- AG(Audio Gate):音频网关 - 音频设备输入输出网关;
- HF(Hands Free):免提 - 该设备作为音频网关的远程音频输入 / 输出机制,并可提供若干遥控功能;
在车载领域,手机侧为AG,车载侧为HF,在Android源码定义中,通常将AG称为HFP/AG,将HF称为HFPClient/HF;
2. HFP功能支持情况
(M代表强制支持,O代表可选)
Num | function | HF | AG | Num | function | HF | AG |
---|---|---|---|---|---|---|---|
1 | 连接管理 | M | M | 14 | 噪声抑制回声消除 | O | O |
2 | 电话状态信息 | M | M | 15 | 语音识别 | O | O |
3 | 音频连接处理 | M | M | 16 | 号码绑定语音标签 | O | O |
4 | 接收语音来电 | M | M | 17 | 传输多音频能力 | O | M |
5 | 拒绝语音来电 | M | O | 18 | 远程音量控制 | O | O |
6 | 中断电话 | M | M | 19 | 回复和保持 | O | O |
7 | 通话中音频链路切换 | M | M | 20 | 描述号码信息 | O | M |
8 | 免提设备拨号 | O | M | 21a | 扩展电话状态 | O | M |
9 | 历史列表拨号 | O | M | 21b | 扩展电话控制 | O | O |
10 | 拨打最后一个电话 | O | M | 22 | 特有指示 | O | M |
11 | 拨号等待通知 | O | M | 23 | 宽频语音 | O | O |
12 | 三方通话 | O | O | 24 | 编解码器协商 | O | O |
13 | CLI(呼叫线路识别) | O | M | 25 | 手持设备指示器 | O | O |
3. 通话过程协议分析
上述过程中,描述的都是在非通话状态下的 AT+ 指令的状态信息,接下来我们对通话状态过程中涉及到的AT指令状态信息进行描述;
3.1 接听电话 - AG
从AG端接听Incoming call的流程比较简单,其中包括了几个动作:来电、响铃和接听,AG只是会通过+CIEV、RING和AT+CLCC等指令进行交互,其中通过+CIEV指令更新callsetup和call状态;
3.1.1 来电
+CIEV
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CIEV: 2,1\r\nCommand 0: +CIEVCommand: +CIEV (Indicator Events Reporting)Type: Response (0x003a)ParametersIndicator Index: 2Indicator 2: 1
- Indicator Index = 2:对应了AT+CIND指令的Indicator,index = 2对应的是callsetup;
- Indicator 2 = 1:对应了callsetup的1,意为正在呼叫中,但是不区分是outgoing还是incoming;
+AT+CLCC
Bluetooth HFP Profile[Role: HS - Headset (2)]AT Stream: AT+CLCC\rCommand 0: +CLCCCommand Line Prefix: ATCommand: +CLCC (Current Calls)Type: Action Command (0x000d)Parameters: No
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CLCC: 1,1,4,0,0,"18717895345",129\r\nCommand 0: +CLCCCommand: +CLCC (Current Calls)Type: Response (0x003a)ParametersID: 1Direction: Mobile Terminated (1)State: Incoming (4)Mode: Voice (0)Mpty: Call is not one of multiparty (conference) call parties (0)Number: "18717895345"Type: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required. (129)
- ID = 1:当前电话是第几路,从 1 开始计数;
- Direction:电话方向,0代表往外拨打的电话outgoing;1代表来电incoming;
- State:电话状态,当前状态为4,意为incoming;
- Mode:电话模式,当前模式为0,意为voice;
- Mpty:是否为多方通话的电话,0代表当前为非多方通话状态;
- Number:来电号码
- Type:可选项,电话类型,129代表了国内号码;
3.1.2 选择编解码器
选择编解码器逻辑基本上和拨号逻辑类同;
+BCS & AT+BCS
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+BCS: 2\r\nCommand 0: +BCSCommand: +BCS (Bluetooth Codec Selection)Type: Response (0x003a)ParametersCodec: mSBC (2)
当前选用的编解码器为mSBC,AT+BAC指令用于获取蓝牙可用编解码器,而对应的AT+BCS指令用于指定使用哪种编解码器;
Bluetooth HFP Profile[Role: HS - Headset (2)]AT Stream: AT+BCS=2\rCommand 0: +BCSCommand Line Prefix: ATCommand: +BCS (Bluetooth Codec Selection)Type: Action Command (0x003d)ParametersCodec: mSBC (2)
然后返回对应的OK Response;
同步连接请求
3.1.3 响铃
RING
Frame 501: 21 bytes on wire (168 bits), 21 bytes captured (168 bits)
Bluetooth[Source: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination: BarrotTe_50:67:20 (04:7f:0e:50:67:20)]
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth RFCOMM Protocol
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\nRING\r\nCommand 0: RINGCommand: RING (Incoming Call Indication)Type: Response (0x0d0a)Parameters: No
AT+CLIP & +CLIP
一般情况下,AT+CLIP指令和+CLIP指令不会出现,即AT+CLIP指令的Response不是+CLIP;
AT+CLIP指令,标准呼叫线路识别通知激活AT命令,它启用/禁用呼叫线路识别通知主动结果代码 +CLIP;
该指令的执行时间一般是在ProfileService启动阶段就设置好了;
…………………………
Bluetooth HFP Profile[Role: HS - Headset (2)]AT Stream: AT+CLIP=1\rCommand 0: +CLIPCommand Line Prefix: ATCommand: +CLIP (Calling Line Identification Notification)Type: Action Command (0x003d)ParametersMode: Enabled (1)
- Mode:Enabled (1),启用呼叫线路识别通知激活,0代表禁用;
对应的Response为OK;
呼叫线路识别通知激活之后,就可以等待incoming;
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CLIP: "18717895345",129\r\nCommand 0: +CLIPCommand: +CLIP (Calling Line Identification Notification)Type: Response (0x003a)ParametersNumber: "1871789xxxx"Type: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required. (129)
- Number:来电号码;
- Type = 129:国内号码;
AT+CLCC & +CLCC
Bluetooth HFP Profile[Role: HS - Headset (2)]AT Stream: AT+CLCC\rCommand 0: +CLCCCommand Line Prefix: ATCommand: +CLCC (Current Calls)Type: Action Command (0x000d)Parameters: No
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CLCC: 1,1,4,0,0,"18717895345",129\r\nCommand 0: +CLCCCommand: +CLCC (Current Calls)Type: Response (0x003a)ParametersID: 1Direction: Mobile Terminated (1)State: Incoming (4)Mode: Voice (0)Mpty: Call is not one of multiparty (conference) call parties (0)Number: "1871789xxxx"Type: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required. (129)
- ID = 1:路线1;
- Direction = 1:来电;
- State = 4:来电状态;
- Mode = 0:voice;
- Mpty = 0:非多方通话;
- Number = 1871789xxxx:来电号码;
- Type = 129:国内号码;
然后 AT+CLCC & +CLCC指令组合会一直响应,在响铃阶段和通话阶段都会响应,只是响应的状态值不一样;
然后返回对应的Response为OK;
3.1.4 接听
+CIEV: 1,1
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CIEV: 1,1\r\nCommand 0: +CIEVCommand: +CIEV (Indicator Events Reporting)Type: Response (0x003a)ParametersIndicator Index: 1Indicator 1: 1
- call = 1:代表了至少有一个电话在进行中,call 状态从 0 -> 1,代表了从未接通状态到接通状态的变化;
+CIEV: 2,0
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CIEV: 2,0\r\nCommand 0: +CIEVCommand: +CIEV (Indicator Events Reporting)Type: Response (0x003a)ParametersIndicator Index: 2Indicator 2: 0
- callsetup = 0:代表了当前没在呼叫中,callsetup 状态从 1 -> 0,代表了从呼叫状态到结束呼叫状态的变化;
3.1.5 通话中
AT+CLCC & +CLCC
HF侧向AG侧发送 Action Command 类型的 AT+CLCC 指令,请求列出当前的呼叫状态信息;
Bluetooth HFP Profile[Role: AG - Audio Gate (1)]AT Stream: \r\n+CLCC: 1,1,0,0,0,"18717895345",129\r\nCommand 0: +CLCCCommand: +CLCC (Current Calls)Type: Response (0x003a)ParametersID: 1Direction: Mobile Terminated (1)State: Active (0)Mode: Voice (0)Mpty: Call is not one of multiparty (conference) call parties (0)Number: "1871789xxxx"Type: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required. (129)
- ID = 1:路线1;
- Direction = 1:来电;
- State = 0:活跃状态,即通话中;
- Mode = 0:voice;
- Mpty = 0:非多方通话;
- Number = 1871789xxxx:来电号码;
- Type = 129:国内号码;
而该指令的响应直到通话结束之后,才会停止响应;
3.2 接听电话 - HF
和拨打阶段类似,在HF响应操作的时候,对应ATD多了一个ATA的指令操作,该指令为标准呼叫应答命令,用于HF侧告知AG侧接电话;
3.2.1 接听
ATA
Bluetooth HFP Profile[Role: HS - Headset (2)]AT Stream: ATA\rCommand 0: ACommand Line Prefix: ATCommand: A (Call Answer)Type: Action Command (0x000d)Parameters: No
- Command:A,CAll Answer,电话应答指令;
然后返回对应的OK Response;