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协议栈
3. PBAP协议数据包分析
3.3 同步通话记录
3.3.1 获取 All CCH Count
3.3.2 同步 All CCH
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链路发送数据;
3. PBAP协议数据包分析
在PBAP协议同步通讯录和通讯记录中,都是基于OBEX协议实现的,PBAP协议作为了应用层协议;
3.3 同步通话记录
3.3.1 获取 All CCH Count
同步所有的通话记录;
Request:
OBEX Protocol
[Profile: PBAP (4)]
[Current Path: /]
.000 0011 = Opcode: Get (0x03)
1... .... = Final Flag: True
Packet Length: 72
[Response in Frame: 566]
Headers
Connection Id: 1
Header Id: Connection Id (0xcb)
11.. .... = Encoding: 4 byte quantity (network order) (0x3)
..00 1011 = Meaning: Connection Id (0x0b)
Connection ID: 1
Name: "telecom/cch.vcf"
Header Id: Name (0x01)
00.. .... = Encoding: Null terminated Unicode text, length prefixed with 2 byte Unsigned Integer (0x0)
..00 0001 = Meaning: Name (0x01)
Length: 35
Name: telecom/cch.vcf
Type: "x-bt/vcard-listing"
Header Id: Type (0x42)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 0010 = Meaning: Type (0x02)
Length: 22
Type: x-bt/vcard-listing
Application Parameters
Header Id: Application Parameters (0x4c)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 1100 = Meaning: Application Parameters (0x0c)
Length: 7
Parameter: Max List Count
Parameter Id: Max List Count (0x04)
Parameter Length: 2
Max List Count: 0 (0x0000)
-
Name = "telecom/cch.vcf":代表了需要加载或访问的数据为所有通话记录;
-
Type = "x-bt/vcard-listing":获取感兴趣的Phone Object 列表;
-
Application Parameters
- Parameter - Max List Count = 0:= 0的情况下,表明本次Request获取的是符合条件的所有信息的Count;
Response:
OBEX Protocol
[Profile: PBAP (4)]
[Current Path: /]
.010 0000 = Response Code: Success (0x20)
1... .... = Final Flag: True
Packet Length: 15
[Request in Frame: 562]
Headers
Connection Id: 1
Header Id: Connection Id (0xcb)
11.. .... = Encoding: 4 byte quantity (network order) (0x3)
..00 1011 = Meaning: Connection Id (0x0b)
Connection ID: 1
Application Parameters
Header Id: Application Parameters (0x4c)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 1100 = Meaning: Application Parameters (0x0c)
Length: 7
Parameter: Phonebook Size
Parameter Id: Phonebook Size (0x08)
Parameter Length: 2
Phonebook Size: 1631 (0x065f)
- Phonebook Size = 1631:代表所有的通话记录信息为1631条;
3.3.2 同步 All CCH
Request:
OBEX Protocol
[Profile: PBAP (4)]
[Current Path: /]
.000 0011 = Opcode: Get (0x03)
1... .... = Final Flag: True
Packet Length: 71
[Response in Frame: 578]
Headers
Connection Id: 1
Header Id: Connection Id (0xcb)
11.. .... = Encoding: 4 byte quantity (network order) (0x3)
..00 1011 = Meaning: Connection Id (0x0b)
Connection ID: 1
Name: "telecom/cch.vcf"
Header Id: Name (0x01)
00.. .... = Encoding: Null terminated Unicode text, length prefixed with 2 byte Unsigned Integer (0x0)
..00 0001 = Meaning: Name (0x01)
Length: 35
Name: telecom/cch.vcf
Type: "x-bt/phonebook"
Header Id: Type (0x42)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 0010 = Meaning: Type (0x02)
Length: 18
Type: x-bt/phonebook
Application Parameters
Header Id: Application Parameters (0x4c)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 1100 = Meaning: Application Parameters (0x0c)
Length: 10
Parameter: Max List Count
Parameter Id: Max List Count (0x04)
Parameter Length: 2
Max List Count: 50 (0x0032)
Parameter: Format
Parameter Id: Format (0x07)
Parameter Length: 1
Format: 3.0 (0x01)
-
Name = "telecom/cch.vcf":被访问加载的数据文件路径;
-
Type = "x-bt/phonebook":同步通话记录;
-
Application Parameters
- Parameter - Max List Count = 50:本次Request需要同步的最大的信息数
- Parameter - Format:版本格式为3.0格式;
Response:
Frame 578: 61 bytes on wire (488 bits), 61 bytes captured (488 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
[Direction: Rcvd (0x01)]
HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet
.... 0000 0000 0010 = Connection Handle: 0x002
..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)
00.. .... .... .... = BC Flag: Point-To-Point (0)
Data Total Length: 56
Data
[Connect in frame: 109]
[Source BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)]
[Source Device Name: dupz]
[Source Role: Slave (2)]
[Destination BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)]
[Destination Device Name: HAVAL_6720]
[Destination Role: Master (1)]
[Last Role Change in Frame: 107]
[Current Mode: Active Mode (0)]
[Last Mode Change in Frame: 564]
Bluetooth L2CAP Protocol
Length: 52
CID: Dynamically Allocated Channel (0x0041)
[Connect in frame: 178]
[PSM: RFCOMM (0x0003)]
Bluetooth RFCOMM Protocol
Address: E/A flag: 1, C/R flag: 0, Direction: 0, Channel: 19
1001 10.. = DLCI: 0x26 (Direction: 0, Channel: 19)
1001 1... = Channel: 19
.... .0.. = Direction: 0x0
.... ..0. = C/R Flag: Response (0x0)
.... ...1 = EA Flag: Last field octet (0x1)
Control: Frame type: Unnumbered Information with Header check (UIH) (0xef), P/F flag: 1
...1 .... = P/F flag: 0x1
111. 1111 = Frame type: Unnumbered Information with Header check (UIH) (0xef)
Payload length: 47
Credits: 1
Frame Check Sequence: 0xe1
OBEX Protocol
[Profile: PBAP (4)]
[Current Path: /]
[8 OBEX Fragments (6977 bytes): #569(990), #570(990), #571(990), #572(990), #573(990), #574(990), #576(990), #578(47)]
[Frame: 569, payload: 0-989 (990 bytes)]
…………………………
[Frame: 578, payload: 6930-6976 (47 bytes)]
[Fragment count: 8]
[Reassembled OBEX length: 6977]
.010 0000 = Response Code: Success (0x20)
1... .... = Final Flag: True
Packet Length: 6977
[Request in Frame: 567]
Headers
Connection Id: 1
Header Id: Connection Id (0xcb)
11.. .... = Encoding: 4 byte quantity (network order) (0x3)
..00 1011 = Meaning: Connection Id (0x0b)
Connection ID: 1
End Of Body
Header Id: End Of Body (0x49)
01.. .... = Encoding: Byte sequence, length prefixed with 2 byte Unsigned Integer (0x1)
..00 1001 = Meaning: End Of Body (0x09)
Length: 6969
Value: 424547494e3a56434152440d0a56455253494f4e3a332e30…
Line-based text data: x-bt/phonebook (350 lines)
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN:\r\n
N:\r\n
TEL;TYPE=0:03511008611\r\n
X-IRMC-CALL-DATETIME;TYPE=DIALED:20220609T145831\r\n
END:VCARD\r\n
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN:\r\n
N:\r\n
TEL;TYPE=0:03511008611\r\n
X-IRMC-CALL-DATETIME;TYPE=DIALED:20220609T143109\r\n
END:VCARD\r\n
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN:\r\n
N:\r\n
TEL;TYPE=0:131xxxxxxxx\r\n
X-IRMC-CALL-DATETIME;TYPE=RECEIVED:20220608T184054\r\n
END:VCARD\r\n
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN:\r\n
N:\r\n
TEL;TYPE=0:03511008611\r\n
X-IRMC-CALL-DATETIME;TYPE=DIALED:20220608T092034\r\n
END:VCARD\r\n
……………………
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN;CHARSET=UTF-8:中通快递\r\n
N;CHARSET=UTF-8:中通快递\r\n
TEL;TYPE=0:95720\r\n
X-IRMC-CALL-DATETIME;TYPE=DIALED:20220606T142440\r\n
END:VCARD\r\n
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN;CHARSET=UTF-8:中通快递\r\n
N;CHARSET=UTF-8:中通快递\r\n
TEL;TYPE=0:95720\r\n
X-IRMC-CALL-DATETIME;TYPE=MISSED:20220606T141702\r\n
END:VCARD\r\n
……………………
在本次的Response中,一共返回了50组通话记录信息,对应了Request中的MaxListCount = 50;
我们发现,在这50组信息中,有很多相同的来电或者是去电信息,他们以发生的时间节点作为唯一标识;
BEGIN:VCARD\r\n
VERSION:3.0\r\n
FN:\r\n
N:\r\n
TEL;TYPE=0:03511008611\r\n
X-IRMC-CALL-DATETIME;TYPE=DIALED:20220609T145831\r\n
END:VCARD\r\n
-
BEGIN:VCARD:一组通话记录信息开始标志
-
END:VCARD:结束标志
-
VERSION:版本
-
N:姓名,现在的这组信息中为空,因为在一般情况下,我们手机中保存的联系人来电时,会提示Name Info,如果是陌生号码,一般直接显示电话号码,无法显示Name Info,但是存在一种情况:公共类型的电话号码是默认支持的,例如外卖、快递、中国移动、中国联通类似性质的号码是无需备注,来电时可以直接显示Name;
- CHARSET=UTF-8:针对中文Name,采用UTF-8的编码方式
-
TEL;TYPE=0:联系人联系方式
-
X-IRMC-CALL-DATETIME:发生的时间点
-
X-IRMC-CALL-DATETIME;TYPE:通话记录类型
- TYPE=DIALED:拨号,去电
- TYPE=RECEIVED:来电
- TYPE=MISSED:未接