一个大概的协议框图

版本变动:V1.1.1to v1.2的时候OBEX直接走L2CAP,v1.2之前会先走RFCOMM再走L2CAP。
角色:
PCE(Phone Book Clint Equipment):下载电话本的角色
PSE (Phone Book Server Equipment):提供电话本的角色
以车载电话本举例,手机就是PSE,车机就是PCE。
PBAP virtual folders structure
PBAP虚拟文件夹结构

root 下会有两个文件夹,一个是telecom 一个是sim,我们可以理解成是存储在手机端的还是存储在sim卡端的电话。
pb :phone book object 也就是电话本 pb.vcf就是在pb目录下的 0.vcf,1.vcf...n.vcf的集合
ich : incoming call history object 来电历记录 ich.vcf就是在ich目录下1.vcf,2.vcf...n.vcf的集合
och :outgoing call history object 去电历史记录 och.vcf就是在och目录下1.vcf,2.vcf...n.vcf的集合
mch :missed call history object 未接电话历史记录 mch.vcf就是在mch目录下1.vcf,2.vcf...n.vcf的集合
cch:combined call history object 上述三个通话记录的集合 cch.vcf就是在cch目录下1.vcf,2.vcf...n.vcf的集合
spd :speed-dial object 快捷键电话拨打目录 spd.vcf就是在spd目录下1.vcf,2.vcf...n.vcf的集合---V1.2才增加的内容
fav :favorite contacts 常用联系人目录 fav.vcf就是在fav目录下1.vcf,2.vcf...n.vcf的集合---V1.2才增加的内容
PBAP连接所需要的内容
SDP相关
PCE端SDP需要注册的内容

PSE端SDP


OBEX相关
OBEX连接请求的格式
PBAP的UUID:796135f0-f0c5-11d8-0966-0800200c9a66

参数说明:
Opcode:0x80 固定的
Packet Length:这一包的长度
OBEX Version Number: obex的版本号
flags:0x00(是否有多连接,0就是没有)
Maximum Packet length:PCE 端所能够接受的一包的数据最大包长
Target : PABP的UUID
Application Parameters 参数设置后面介绍
后面几个不常用,不写也行
OBEX连接响应格式:

参数说明:
Response Code:连接状态 0xA0就是连接成功 其他的就是错误码
Packet Length :这一包的长度
OBEX Version Number: OBEX的版本号
Flag :0x00(是否有多连接,0就是没有)
Maximum Packet length:PSE 端所能够发送的一包的数据最大包长(一般手机都会根据PCE端所能支持的最大包长动态变化)
Who :走OBEX协议的UUID 在这边就是PBAP的UUID
Connection ID:OBEX分配的ID,后续的操作都得使用这个ID.
后面几个不常用,不写也行
PBAB features
不使用SRM的话都是PCE发送一个
requestPSE回复一个response。如果使用了SRM那么PCE发送发送一次request就可以了,PSE就会一直回复response直到执行结束。
Download
Phone Book Download feature 的流程图

下载操作流程:
PullPhoneBook function
PBAP 拉取电话本request 的一个格式

- Opcode: GET opcode 是0x03/0x83(在OBEX介绍为什么是这个值)
- Packet Length :数据包长度
- Connection ID: 连接OBEX成功会设置的id 上面有介绍
- Single Response Mode:0x01(这个是在GOEP 2.0或者更新的版本必须要使用。如果启用了就不需要一包一包的向PSE请求电话本,发起一次PSE就会一直回复,直到将电话本发完)
- Single Response Mode Param:0x01(这个是在GOEP 2.0或者更新的版本必须要使用。)
- Name:要下载电话本的名称,unicode编码的,也就是一个字符占两个字节,如果你要下载的是telecom/cch.vcf,那就得在他每一位之前加上一个0,0t0e类似这样的格式,代码中就是写的话就是
name_string[index*2] = 0; name_string[index*2+1] = name_string_temp[index]; - type:"x-bt/vcard-listing" BT下载的固定就是这个字符串
- Application Parameters 这个是一个TLV的构型 他的type是0x4c(为什么是0x4c在OBEX里面介绍,这边先了解就好)。
Application Parameters 我们可以看到Application Parameters下面有很多的参数,这些参数也是TLV的构型,TAG|Length|Value ,TAG值都是规定好的,
PropertySelector {PropertyMask (64-bit value)} vCard 2.1 一定要写入参数VERSION ,N and TEL。vCard 3.0 一定要写入 VERSION, N, FN and TEL. Response的时候会把这几位的值返回给我们,下图是PropertySelector 每一位的含义
Format :也就是Vcard 的版本 0 表示2.1,1表示3.0
MaxListCount:我们需要获取的电话本数量。如果这一位设置0的话,那么PSE就会返回我们是要那个电话本的数目给到我们 ,如果我们不知道要获取多少的话,这边也可以填入0xffff,PSE就会把所有的电话本都发完。
ListStartOffset:开始获取电话本的一个偏移量,如果没有设置那么默认从第一个开始获取,必选项的如果你是要获取电话本的数目这个可以不写,否则都写一下。
拉取电话本response的一个格式

回包的一个格式
- Response Code: 0x90(未发完) or 0xA0(发完了) 表示回复,其他的都是错误代码
- ...其他的跟request是一样的
- PhonebookSize :如果request中的MaxListCount是0的话,Response就会用到这个告诉PCE 电话本的数量
- Body/End of Bady :body就是电话本vcard解析,存在数据黏包的情况的,一个Body会存在多个vcard内容。End of Bady就是发完了
上面说到的TAG值见下表


当我们首次发起Get的时候request的所有必选项都要写入,但是如果当我们没有获取完电话本还要接着获取,那么就不request就不用写那么多了,只需要opcode,Packet Length 和Connection Id
Browsing
Phone Book Browsing feature
流程图:

Browsing的操作流程
1.SetPhoneBook function
可以理解成设置一个我们要去的目录
SetPhoneBook function 的request 结构

这边跟downloading的内容是差不多,只有一个flag要注意一下
如果我们要去到root下面flag就是 2 name不需要填
如果我们要去往下一级 flag 也是2 name写入我们去去往的目录名:telecom/pb(unicode 编码的)
如果要回到上一级 flag就是3 name可写可不写
response结构:

建议第一步是先去到root目录下,在选择其他目录,这样不会将当前的目录结构混乱了。
2.PullvCardListing function
下载vcarlist
vcarlist 里面的有两个部分 一个是 handle x.vcf(x就是数字比如说1.vcf这种) 一个就是name也就是这个电话的备注
PullvCardListing function 的request 格式

第一步已经set path 所以这边的那么的name可以填空
Application Parameters 也可以不写好像没什么用
Response 结构:

Body:就是vcardlist 的内容
3.PullvCardEntry Function
通过这一步可以获取完整的vcard 信息
PullvCardEntry Function request 结构

name 一般写入 第二部获取到的x.vcf 就可以,x写入你要获取那个具体的vcard
response 结构

body 就是vcard具体内容
Vcard 介绍
vCard 2.1 一定要写入参数VERSION ,N and TEL。
vCard 3.0 一定要写入 VERSION, N, FN and TEL.
vCard 不管是2.1还是3.0开头都是BEGIN:VCARD 结尾都是END:VCARD.
Vcard: Property格式
PropertyName [';' PropertyParameters] ':' PropertyValue
属性名称[;属性参数(可选项如果有就要用;隔开)]:属性值
TEL;HOME:+1-919-555-1234
还有一种是是属性参数后面还带有一个值 name=value
NOTE;ENCODING=QUOTED-PRINTABLE:Don't remember to order Girl=
Scout cookies from Stacey today! //Full property parameter expression
属性参数是可以缩写的:格式参考
NOTE;QUOTED-PRINTABLE:Don't remember to order Girl=
Scout cookies from Stacey today! //Full property parameter expression
依次介绍一下必须要获取的到值
- VERSION:2.1
- N(name):name 一共会回来5个参数 依次是:Family Name (first field), Given Name
(second field), Additional Names (third field), Name Prefix (fourth field), and Name Suffix (fifth
field) strings :N:Public;John;Quinlan;Mr.;Esq哪怕没有也必须要用;隔开 - FN(Formatted Name):就是将Nz做了格式化处理:
FN:Mr. John Q. Public, Esq - TEL;HOME:+1-919-555-1234 冒号后面的就是电话号码
其他的内容可以去Vcard协议里面具体查看

