1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论
2. 欢迎大家关注和订阅,【蓝牙协议栈】专栏会持续更新中.....敬请期待!
目录
1. 协议简述
1.1 PBAP
1.2 OBEX
2. PBAP协议栈
2.1 vCard格式
2.2 PBAP 角色介绍
2.3 PSE & PCE 功能
2.3.1 Download
2.3.1.1 PullPhonebook Data Format
2.3.1.2 Application Parameters Header
2.3.2 Browsing
2.3.2.1 SetPhonebook Data Format
2.3.2.2 PullvCardListing Data Format
2.3.2.3 PullvCardEntry Data Format
2.3.3 vcf文件
1. 协议简述
蓝牙电话应用不但需要HFP协议来支持打电话的功能,同时在很多车载蓝牙应用中,都支持查看通讯录和通话记录等信息,而这一部分的所涉及到的协议为PBAP.
1.1 PBAP
PBAP(Phone Book Access Profile):电话本访问协议 ,是一种基于OBEX的上层协议,该协议可以同步手机这些具有电话本功能设备上的通讯录和通话记录等信息,用于访问电话本对象(通过 Vcard形式),是基于客户端/服务器的模型,一般是 client从 server端下载电话本。这个协议是为 HFP/SIM协议设计.
1.2 OBEX
Object Exchange,对象交换协议,来源与红外通讯协议,但又不局限与具体的传输方式,后来被蓝牙组织SIG吸纳其中部分并进行优化处理作为蓝牙协议中的OBEX层用于蓝牙设备间的文件数据传输,如蓝牙传输文件(OPP)、同步电话簿(PBAP)和同步短信(MAP)等场景下都是以OBEX协议组织相关数据进行传输的;
OBEX协议有两种角色:Server和Client,通过request-response(请求-响应)形式进行交互,即客户端Client进行请求,服务端Server响应客户端请求的方式传输数据对象;应用于PBAP协议中,Client只能进行数据的读取操作,不能对源数据进行修改,保证了源数据的安全性;
2. PBAP协议栈
PBAP应用层协议处于最上层,之后就是数据格式处理方式,由于通讯录在手机中都是以vCard的格式存储的,所以这边为vCard的数据处理格式。在往下就是通过OBEX协议层联通蓝牙协议栈中的RFCOMM,最后通过统一的数据传输通道L2CAP链路发送数据;
2.1 vCard格式
BEGIN:VCARD\r\n
VERSION:3.0\r\n
N:;胡x;;;\r\n
FN:胡x\r\n
TEL;TYPE=CELL:610xxx\r\n
END:VCARD\r\n
- BEGIN:VCARD:一组联系人信息开始标志
- END:VCARD:结束标志
- VERSION:版本
- FN:姓名
- TEL;TYPE=CELL:联系人联系方式
上述的参数为必要的,有些参数是可选项,例如:住址、邮件等信息;
当前vCard的版本有vCard 2.1 和 vCard 3.0 两个版本,所以PSE需要两种数据格式都支持,同步数据时根据PCE请求的哪种格式就以哪种格式封装数据进行传输。但是无论是哪种格式,vCard属性内容字符集使用唯一的字符编码utf-8格式进行编码转换;
2.2 PBAP 角色介绍
协议栈中定义了两种角色:
- PSE:Phone Book Server Equipment,拥有电话本源数据的设备,作为Server,比如手机;
- PCE:Phone Book Client Equipment,向PSE端请求电话本源数据的设备,作为Client,例如车机;
因为PBAP协议是基于OBEX协议实现的,那PBAP协议获取数据的方式也是通过request-response形式传输的;
2.3 PSE & PCE 功能
Feature | Support by the PCE | Support by the PSE |
---|---|---|
Download | C1 | M |
Browsing | C1 | M |
Database Identifier | C3 | M |
Folder Version Counters | O | M |
vCard Selecting | O | M |
Enhanced Missed Calls | O | O |
X-BT-UCI vCard Property | O | O |
X-BT-UID vCard Property | O | O |
Referencing Contacts | C2 | C2 |
Contact Image Default Format | X | M |
- C1:至少支持其中一种
- C2:如果支持' X-BT-UID vCard Property ',则可选,否则不支持不可选
- C3:如果支持“Folder Version Counters” 或 “X-BT-UID vCard Property”,则必选,否则可选
- O:可选
- M:必选,必须支持
我们常使用到的功能为:Download和Browsing;我们分析一下;
2.3.1 Download
Download功能可以将电话簿对象的全部内容同步到PCE,从而PCE端获取到数据后完全可以通过蓝牙电话等应用程序将数据显示到界面,一样可以达到滚动浏览电话簿信息的目的;
Download这个功能特别是用于PSE端存储的电话簿容量相对较大,PCE设备通常从PSE端下载这些大容量数据并在其本地存储整个电话簿的场景。
Feature | Function | Support by the PCE | Support by the PSE |
---|---|---|---|
Phone Book Download feature | PullPhonebook | M | M |
协议层提供了PullPhonebook函数,这个函数就是用来下载自己感兴趣的电话簿对象;
2.3.1.1 PullPhonebook Data Format
由于PBAP协议是基于OBEX的,所以PullPhonebook函数顾名思义也是采用request-response这种一问一答的形式传输数据;
请求格式如下:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Opcode | GET(0x03 or 0x83) | M |
Field | Packet Length | Varies | M |
Header | Connection ID | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Name | Object name (*.vcf) | M |
Header | Type | "x-bt/phonebook" | M |
Header | Application Parameters | ||
- PropertySelector | Varies | O | |
- Format | Varies | O | |
- MaxListCount | Varies | O | |
- ListStartOffset | Varies | O | |
- ResetNewMissedCalls | Varies | C3 | |
- vCardSelector | Varies | C4 | |
- vCardSelectorOperator | Varies | C5 |
- Opcode:操作码,可以理解为标识码,和Type参数组合形成了唯一标识;
- Connection ID:PBAP连接指令中PSE回复的连接ID 号;
- Name:表明了需要同步哪种数据;
- Type:对应了Function,基本上每一个Function对应一个Type,除了SetPhonebook Function;
- Application Parameters:应用设置的参数,PSE的回复数据会根据这些参数来组装回复data数据,其中就包括了PropertySelector、Format、MaxListCount等参数信息;
- MaxListCount:本次 GET 获取的最大List Count;
- ListStartOffset:本次 GET 开始的List Offset;
响应格式如下:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Response | 0x09 or 0xA0 or Error Code | M |
Field | Packet Length | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Application Parameters | ||
- PhonebookSize | Varies | C3 | |
- NewMissedCalls | Varies | C4 | |
- PrimaryFolderVersion | Varies | C5 | |
- SecondaryFolderVersion | Varies | C5 | |
- DatabaseIdentifier | Varies | C6 | |
Header | Body/End of Body | vCard object(s) | C7 |
- PhonebookSize:Name个数,当MaxListCount = 0时,返回Name的总个数;
- NewMissedCalls:新增的未接电话
- Body/End or Body:请求中MaxListCount != 0时,返回Name对应的数据,回复数据中的vCard对象只应包含使用属性选择器Attribute Selector参数指示的属性,并且应使用格式Format参数指示的格式组装数据;
2.3.1.2 Application Parameters Header
该数据是由一组不同的TAG组成的整体的Application Parameters;
Value | Tag ID | Length | Possible Values |
---|---|---|---|
Order | 0x01 | 1 byte | 0x00 = indexed 0x01 = alphanumeric 0x02 = phonetic |
Search Value | 0x02 | variable | Text |
SearchProperty | 0x03 | 1 byte | 0x00 = Name 0x01 = Number 0x02 = Sound |
MaxListCount | 0x04 | 2 bytes | 0x0000 to 0xFFFF |
ListStartOffset | 0x05 | 2 bytes | 0x0000 to 0xFFFF |
PropertySelector | 0x06 | 8 bytes | 64 bits mask |
Format | 0x07 | 1 byte | 0x00 = 2.1 0x01 = 3.0 |
PhonebookSize | 0x08 | 2 bytes | 0x0000 to 0xFFFF |
NewMissedCalls | 0x09 | 1 byte | 0x00 to 0xFF |
PrimaryVersionCounter | 0x0A | 16 bytes | 0 to (2 128 – 1) |
SecondaryVersionCounter | 0x0B | 16 bytes | 0 to (2 128 – 1) |
vCardSelector | 0x0C | 8 bytes | 64 bits mask |
DatabaseIdentifier | 0x0D | 16 bytes | 0 to (2 128 – 1) |
vCardSelectorOperator | 0x0E | 1 byte | 0x00 = OR 0x01 = AND |
ResetNewMissedCalls | 0x0F | 1 byte | 0x01 = Reset |
PbapSupportedFeatures | 0x10 | 4 bytes | Bit 0 = Download Bit 1 = Browsing Bit 2 = Database Identifier Bit 3 = Folder Version Counters Bit 4 = vCard Selecting Bit 5 = Enhanced Missed Calls Bit 6 = X-BT-UCI vCard Property Bit 7 = X-BT-UID vCard Property Bit 8 = Contact Referencing Bit 9 = Default Contact Image Format Bit 10 ~ 31 Reserved 1 |
- PropertySelector:用于指示请求的vCard object中应该包含的属性,PSE根据这些属性来组织恢复的Body/End of Body Header中包含的数据,PCE只能使用此Header接收所请求的vCard所需要内容,PSE不得回复任何其他性能数据,除非PCE有其他要求;
PropertySelector的值是由一个64位的数据组成,所以每一位都代表了一种属性,如果PCE请求的电话簿需要包含对应的数据,就将该数据对应在PropertySelector的二进制位设置为true(1)。具体每一位的含义见下图:
流程图
这里有一个需要注意的,PCE和PSE的服务连接不是一直保持的,只有在同步Phone Book的时候,服务保持连接,同步完成之后,就会断开;
2.3.2 Browsing
Feature | Function | Support by the PCE | Support by the PSE |
---|---|---|---|
Phone Book Browsing Feature | SetPhonebook | M | M |
PullvCardListing | M | M | |
PullvCardEntry | M | M |
- SetPhonebook:选择感兴趣的Phone Object
- PullvCardListing:client使用该Function获取感兴趣的Phone Object 列表
- PullvCardEntry:client使用该Function获取感兴趣的Phone Object(单个)
2.3.2.1 SetPhonebook Data Format
请求格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Opcode | SETPATH (0x05) | M |
Field | Packet Length | Varies | M |
Field | Flags | Up / Down / Root | M |
Field | Constant | Reserved (0) | M |
Header | Connection ID | Varies | M |
Header | Name | Name of the folder | O |
响应格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Response Code | 0xA0 or Error Code | M |
Field | Packet Length | 3 | M |
2.3.2.2 PullvCardListing Data Format
请求格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Opcode | GET(0x03 or 0x83) | M |
Field | Packet Length | Varies | M |
Header | Connection ID | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Name | Name of the folder | M |
Header | Type | "x-bt/vcard-listing" | M |
Header | Application Parameters | ||
- Order | Varies | O | |
- SearchValue | Varies | O | |
- SearchProperty | Varies | C3 | |
- MaxListCount | Varies | O | |
- ListStartOffset | Varies | O | |
- ResetNewMissedCalls | Varies | C4 | |
- vCardSelector | Varies | C5 | |
- vCardSelectorOperator | Varies | C6 |
响应格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Response Code | 0x09 or 0xA0 or Error Code | M |
Field | Packet Length | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Application Parameters | ||
- PhonebookSize | Varies | C3 | |
- NewMissedCalls | Varies | C4 | |
- PrimaryFolderVersion | Varies | C5 | |
- SecondaryFolderVersion | Varies | C5 | |
- DatabaseIdentifier | Varies | C6 | |
Header | Body/End of Body | vCard object(s) | C7 |
2.3.2.3 PullvCardEntry Data Format
请求格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Opcode | GET(0x03 or 0x83) | M |
Field | Packet Length | Varies | M |
Header | Connection ID | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Name | Object name (*.vcf) or X-BT-UID (X-BT-UID) | M |
Header | Type | "x-bt/vcard" | M |
Header | Application Parameters | ||
- PropertySelector | Varies | O | |
- Format | Varies | O |
响应格式:
Field / Header | Name | Value | Status |
---|---|---|---|
Field | Response Code | 0x09 or 0xA0 or Error Code | M |
Field | Packet Length | Varies | M |
Header | Single Response Mode | 0x01 | C1 |
Header | Single Response Mode Param | 0x01 | C2 |
Header | Application Parameters | ||
- DatabaseIdentifier | Varies | C3 | |
Header | Body/End of Body | vCard object | C4 |
流程图
2.3.3 vcf文件
Download和Browsing功能描述完成之后,我们需要知道,所有的Phone Object信息都是来自于PSE端,而在PSE端保存Phone Object的方式或者是路径可能有很多;
-
存储设备
- 手机:telecom/xxx.vcf
- SIM卡:SIM1/telecom/xxx.vcf
无论是哪种存储方式,其对应都有相同的数据存储类型,例如通讯录、通讯记录,而在通讯记录中,又可以分为:来电、去电、未接来电、所有通讯记录。同时电话簿还提供了两个功能:快速拨号和收藏联系人;
上述描述的分类方式,对应了PSE端存储文件格式;
Phone Object | AS | Format | Desc |
---|---|---|---|
Phone Book Object | pb | pb.vcf | 通讯录 |
Incoming Calls History Object | ich | ich.vcf | 来电通话记录 |
Outgoing Calls History Object | och | och.vcf | 去电通话记录 |
Missed Calls History Object | mch | mch.vcf | 未接来电通话记录 |
Commbined Calls History Object | cch | cch.vcf | 所有的通话记录 |
Speed-Dial Object | spd | spd.vcf | 快速拨号 |
Favorite Contacts Object | fav | fav.vcf | 收藏通讯录 |