彻底吃透 蓝牙电话本访问(PBAP)协议

 零.声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

-------------------------------------------------------------------------------------------------------------------------

蓝牙视频教程(跟韦东山老师合作):

https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.20.5aeb41f98e267j&id=693788592796

蓝牙交流扣扣群:765961169

Github代码:GitHub - sj15712795029/bluetooth_stack: 这是一个开源的双模蓝牙协议栈(bluetooth.stack)(btstack),可以运行在STM32,Linux.,包含HCI,L2CAP,SDP,RFCOMM,HFP,SPP,A2DP,AVRCP,AVDTP,AVCTP,OBEX,PBAP等协议,后续会继续维护,以达到商用的目的

入手开发板:https://shop220811498.taobao.com/category-1542116976.htm?spm=a1z10.5-c-s.w4010-22329603913.7.39ca7dbe2EA0K3&search=y&catName=%C0%B6%D1%C0%BF%AA%B7%A2%B0%E5#bd

蓝牙学习目录一篇文章足够你学习蓝牙技术,提供史上最全的蓝牙技术(传统蓝牙/低功耗蓝牙)文章总结,文档下载总结(2020/12/11更新)_Wireless_Link的博客-CSDN博客_蓝牙eir

--------------------------------------------------------------------------------------------------------------------------

一.PBAP概述

1. PBAP概念

电话本访问协议Phone Book Access Profile (PBAP)用于访问电话本对象(通过Vcard形式),是基于客户端/服务器的模型,一般用于client从server下载电话本。这个协议为为HFP/SIM协议设计。

2. PBAP架构

这个小节我们来介绍下PBAP的架构,分别介绍下V1.2以下以及V1.2以上的架构!为什么要分开呢,因为在PBAP1.2做了一次重大更新,底层协议变了!

V1.2以下的架构图如下:

V1.2架构

可以看到两个架构在OBEX层以下稍微有点不同,V1.2之前是OBEX直接走RFCOMM,但是在V1.2后基于GOEP的版本,如果是GOEP V2.0以后那么走L2CAP ertm,如果是1.1版本,那么继续走RFCOMM,对旧版本做兼容!

整个协商走哪条PATH有以下MAP:

只有当PCE跟PSE都在SDP中宣称GOEP 2.0或者更新的情况下数据走L2CAP,否则数据走RFCOMM!

3. PBAP角色

PBAP分为server端以及client端

Phone Book Server Equipment (PSE) – This is the device that contains the source phone book objects.

Phone Book Client Equipment (PCE) – This is the device that retrieves phone book objects from the Server Equipment.

上图就是一个典型的示意图,车载跟手机连接,车载作为PBAP的PCE角色,手机作为PBAP的PSE的角色!

二. PBAP名词介绍

1)电话本仓库(Phone book repositories)

存储电话本的地方,比如智能手机,有两个存储电话本的地方:

① 手机本身的存储空间

② SIM卡的存储空间

2)电话本对象(Phone book objects)

① 主电话本对象,The main phone book object (pb),手机跟SIM卡中都有这个

② 来电电话本对象,The Incoming Calls History object (ich)

③ 去电电话本对象,The Outgoing Calls History object (och)

④ 未接电话本对象,The Missed Calls History object (mch)

⑤ 组合电话记录对象,The Combined Calls History object (cch),包括来电/去电/未接电话

⑥ 快速拨号电话本对象,The Speed-Dial object (spd),V1.2才增加的内容

⑦ 收藏人电话本对象,The Favorite Contacts object (fav),V1.2才增加的内容

3)电话本格式(Phone book entries format)

以Vcard的形式来标示,此部分需要注意:PSE需要同时支持Vcard2.1跟Vcard3.0,并且编码必须以UTF-8的格式呈现。

1)PBAP虚拟文件夹结构(PBAP virtual folders structure)

三. PBAP特性(Feature)

PBAP一共有以下几个特性,如下图所示:

在介绍特定的feature之前,我们先来看下application的tag id都有哪些(这些是扩展用OBEX的Tag ID的),在后续的feature都会用到,我们先列出来,后续用到哪个我们再列举:

1. Phone Book Download feature

此特性提供了电话本下载功能,只有PullPhonebook功能,如图所示:

下面我们来讲解下PullPhonebook功能,整个流程是这样,PCE连接了PSE的前提下,下载电话本,直到下载结束或者取消下载。

这个功能就是下载电话本的功能,用OBEX Get功能,参数如下:

我们来一一说下header参数:

Connection ID:这个是在connection response的时候获取到的参数

Single Response Mode:这个是在GOEP 2.0或者更新的版本必须要使用。

Single Response Mode Param:这个是在GOEP 2.0或者更新的版本必须要使用。

Name:要下载的电话本名称,是虚拟文件夹的绝对路径,比如你要下载手机中的所有的电话本,那么这个名字就是:telecom/pb.vcf,比如你要下载SIM卡中的电话本,这个名字就是:SIM1/telecom/pb.vcf,比如你要下载手机全部的通话记录,那么name就是:telecom/cch.vcf等等吧,总之就是虚拟文件夹的绝对路径+.vcf格式,另外这里要提下,编码方式是unicode,也就是一个字符占用两个byte.,我个人觉得是OBEX是为了兼容多国语言吧,比如OPP下载文件名称之类的。

Type:类型,在PBAP中一直是x-bt/phonebook

Application - PropertySelector:用于过滤返回vcard中属性,如果没有设置这个或者设置为0,那么vcard中所有属性都会返回,另外,有几个属性会强制返回,不管你有没有设定,这个是区分Vcard版本,Vcard2.1会强制返回VERSION ,N and TEL,Vcard3.0会强制返回VERSION, N, FN and TEL,属性Mask如下图:

Application - Format:vcard格式,在上面applicantion中已经有截图

Application - MaxListCount:这个代表最大可以下载多少笔vcard,在这里有一个隐藏功能,就是设置为0可以获取到手机有多少笔vcard.原文如下:

Application - ListStartOffset:这个就是下载的开始偏移,如果你想从50笔开始下载,那么就设置为50,这个一般用在通话记录的时候,因为一般的手机只会发送最近50笔的通话记录,但是你想要全部下载,那么就要通过这个参数做文章。如果你不设置或者设置为0,那么默认从0开始!

Application - ResetNewMissedCalls:

Application - vCardSelector:

Application - vCardSelectorOperator:

返回的参数如下:

其中Body/End of Body就是vcard数据,vcard格式我们已经在上个章节介绍,所以我们就不再这里重复了!

接下来,我们来举例说明下获取电话本笔数跟下载电话本的btsnoop交互流程!我们在前面已经介绍了各个Req跟Rsp的格式,所以我们就不再重复数据格式!

1) 获取电话本笔数

整个步骤如下:

PCE发送OBEX get指令

Connection id是obex connect resp PSE回复给PCE的,后续基本上每个封包都要附带Conection ID.

此部分有name设定,也就是获取特定仓库特定Type的笔数

APP Param关键参数是Max List Count,此部分一定要设置为0,才是获取电话本功能!

PSE回复特定的仓库的笔数

2) 下载电话本

整个步骤如下:

1) 根据特定的仓库获取电话本

2) 手机回复Continue

注意有的手机在这里会附带APP Para的Body参数,部分手机下一次才会出现Body参数!

3) 我们继续Get数据

4) 手机最终回复OK,电话本下载完成

另外,有人可能想看下下载的电话本是什么,但是在软件中NAME在raw data中是乱码,所以我在这里教大家一个Tip,可以从Ellisys中导出vcard数据,操作如下:

1) 操作File->Export

2) 选择Bluetooth Mobile Phone Data(Vcards,Messages)

3) 一路Next,然后保存文件,格式为vcf文件

打开效果如图,还记得我们获取电话本笔数为3吗?这样对的上了吧?

另外,我vcf格式是用notepad++打开的,如果你下载的带photo,肯定要用特定vcf打开工具了,因为ellisys可以保存photo哦!

另外,关于下载速度我做了几个实验(仅代表三星S7的测试结果),结果如下:

至于为啥做这个实验,我开始本来想着每次下载一笔vcard,这样优点很明显,方便解析,但是后来发现时间巨长··,所以这种方式并不适合笔数很大的下载,然后OBEX MTU的size我本来考虑是减少交互次数,也能加快速度,但是并不是我想的那样,速度不会快很多!

2. Phone Book Browsing feature

此特性提供了电话本浏览功能,包含了三个功能

其中SetPhonebook就是进入PBAP server特定的虚拟文件夹

其中PullvCardListing就是下载vCard列表

其中PullvCardEntry就是下载特定的vCard数据

整个流程如下:

整个流程就是:

1)进入特定的虚拟文件夹

2)下载vCard列表

3)真正用到的时候下载特定的vCard

2.1. SetPhoneBook function

在讲这个SetPhoneBook 功能之前,我们来说明下Setpath的版本差异

1)首先来说下PBAP 1.2之前的这个功能封包,首先来看下OBEX setpath的request以及response,封包格式我们已经在obex说明,我们只贴下图,如图:

其中constants must be zero,flag如下图:我们一般选择填bit1,也就是0x02

然后PBAP的后续封包如图:

只需要填上connection id以及path name就行!

我们来查看一个btsnoop,我们是进入本机的pb虚拟文件夹

2)再来说下PBAP 1.2的这个功能封包

其中flag是有改变的,我们来看下具体的值

但是,为了兼容旧版本,我还是以旧的方式来实现code,没有按照最新的方式!!!

2.2. PullvCardListing function

在接收这个功能之前,我们先来看下vcard List是什么?

vcard list是一组xml格式的对象,采用utf-8编码,vcard list的example如下:

这个功能是下载vCard列表的功能,也是用的OBEX的Get封包,整个request封包格式为:

Name:就是你要下载的虚拟文件夹路径

Type:固定为x-bt/vcard-listing

其中Application Parameted我们就不再做介绍了

3. PullvCardEntry function

这个就是根据entry number来下载特定vcard数据的功能,封包格式如下:

返回数据如下:

其中vcard data我们已经在前面做了讲解

我们来看一个完整的PBAP的browing的流程来加深下印象:

整个分为4个大步骤:

1) 回到Root路径

2) 进入特定的Folder

3) 下载Vcard List

4) 下载Vcard Entry

下面我们来一个个步骤分析下:

1) 回到Root路径

PCE发送obex set path,name设置为空,进入Root Folder

PSE给PCE回复OK,路径设置成功

2) 进入特定的Folder

PCE发送obex set path,name设置为要进入的路径

PSE给PCE回复OK,路径设置成功

3) 下载Vcard List

进入特定的路径后,我们就要下载Vcard List了,整个步骤如下:

Get步骤我们就不说了,我们来看下获取到的vcard List

完全符合我们上面说的xml格式的list,我们从vcard list中可以看到一共哟偶三笔,分别是0.vcf,3.vcf,4.vcf

4) 下载Vcard Entry

这个是根据名字来获取整个vcard信息,假设我们要获取上面的0.vcf,流程如下:

获取到的vcard如图:

可以看到跟我们单独下载电话本下载下来的完全一样

最后介绍完毕这两个Feature,我们来延伸思考下,这两份分别都用在什么场景下呢?在这里我大概说下我考虑到的场景,如果你们有更多的场景,可以各抒己见!

l 根据跑蓝牙协议栈的资源来定,如果MCU/MPU资源有限,不足以保存所有vcard信息,那么肯定选择browing,只有用到的时候才会去下载特定的vcard信息

l 根据电话本笔数来定,如果电话本笔数巨多,下载要花很久,那么优先选择browing!

我个人觉得排除以上,download feature是优先选择!

四. OBEX协议在PBAP的功能

1. Phone Book connect/disconnect

由于在pbap文档中并没有把connect/disconnect列为feature中,但是我们还是在feature中做说明

1.1. Establishing an OBEX session

连接请求格式如下:

其中opcode/packet Length/OBEX version/flags/max packet length我们已经在obex讲解,不再重复,下面我们来说下下header部分

Target: 要连接的目标,其中796135f0-f0c5-11d8-0966-0800200c9a66就是PBAP的UUID,文档描述如下:

The use of the Target header is mandatory in the Phone Book Access Profile. The UUID below shall be used in the Target header:

796135f0-f0c5-11d8-0966-0800200c9a66

连接响应格式如下:

整个btsnoop如下:

但是这里有一个潜在的东西,需要我们了解下,我们本小节之说了OBEX协议本身的connect,那OBEX的底层是什么呢?可能换做以前,我们可能毫不犹豫的就脱口而出:RFCOMM,但是到了PBAP V1.2后,千万别再说RFCOMM了,这个是可选了,可以走RFCOMM,可以走L2CAP,那根据什么来决定呢?我们在1.2小节中已经做介绍了,跟根据GEOP来定的,主要是根据SDP中这个来决定

Terminate an OBEX session

断开文档说是通过OBEX disconnect,其实我们直接断开基于OBEX的L2CAP或者RFCOMM就好了,没必要再操作OBEX!

2. Abort function

这个功能是不管你在干嘛,就是取消掉当前的动作,比如你下载电话本的时候,想取消掉,就用这个命令,这个功能在pbap协议中只是提到了一下,并没有讲具体格式,那么根据obex描述的格式为,然后再optional header的地方加上connection id就行了

五. PBAP SDP

PCE的SDP如下:

PSE的SDP如下:

其实通过PCE跟PSE的SDP中可以看出来,PBAP连接只是单向的,只能PCE去连接PSE,你想啊·PCE都不注册RFCOMM的scn或者L2CAP的GOEP psm,PSE连接什么呢?所以又获取到一个Tip了吧?

Cod如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wireless_Link

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值