【Android】【Bluetooth Stack】蓝牙电话本协议分析(超详细)

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 功能

FeatureSupport by the PCESupport by the PSE
DownloadC1M
BrowsingC1M
Database IdentifierC3M
Folder Version CountersOM
vCard SelectingOM
Enhanced Missed CallsOO
X-BT-UCI vCard PropertyOO
X-BT-UID vCard PropertyOO
Referencing ContactsC2C2
Contact Image Default FormatXM
  • 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端下载这些大容量数据并在其本地存储整个电话簿的场景。

FeatureFunctionSupport by the PCESupport by the PSE
Phone Book Download featurePullPhonebookMM

协议层提供了PullPhonebook函数,这个函数就是用来下载自己感兴趣的电话簿对象;

2.3.1.1 PullPhonebook Data Format

        由于PBAP协议是基于OBEX的,所以PullPhonebook函数顾名思义也是采用request-response这种一问一答的形式传输数据;

请求格式如下:

Field / HeaderNameValueStatus
FieldOpcodeGET(0x03 or 0x83)M
FieldPacket LengthVariesM
HeaderConnection IDVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderNameObject name (*.vcf)M
HeaderType"x-bt/phonebook"M
HeaderApplication Parameters
- PropertySelectorVariesO
- FormatVariesO
- MaxListCountVariesO
- ListStartOffsetVariesO
- ResetNewMissedCallsVariesC3
- vCardSelectorVariesC4
- vCardSelectorOperatorVariesC5
  • 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 / HeaderNameValueStatus
FieldResponse0x09 or 0xA0 or Error CodeM
FieldPacket LengthVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderApplication Parameters
- PhonebookSizeVariesC3
- NewMissedCallsVariesC4
- PrimaryFolderVersionVariesC5
- SecondaryFolderVersionVariesC5
- DatabaseIdentifierVariesC6
HeaderBody/End of BodyvCard 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;

ValueTag IDLengthPossible Values
Order0x011 byte0x00 = indexed 0x01 = alphanumeric 0x02 = phonetic
Search Value0x02variableText
SearchProperty0x031 byte0x00 = Name 0x01 = Number 0x02 = Sound
MaxListCount0x042 bytes0x0000 to 0xFFFF
ListStartOffset0x052 bytes0x0000 to 0xFFFF
PropertySelector0x068 bytes64 bits mask
Format0x071 byte0x00 = 2.1 0x01 = 3.0
PhonebookSize0x082 bytes0x0000 to 0xFFFF
NewMissedCalls0x091 byte0x00 to 0xFF
PrimaryVersionCounter0x0A16 bytes0 to (2 128 – 1)
SecondaryVersionCounter0x0B16 bytes0 to (2 128 – 1)
vCardSelector0x0C8 bytes64 bits mask
DatabaseIdentifier0x0D16 bytes0 to (2 128 – 1)
vCardSelectorOperator0x0E1 byte0x00 = OR 0x01 = AND
ResetNewMissedCalls0x0F1 byte0x01 = Reset
PbapSupportedFeatures0x104 bytesBit 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

FeatureFunctionSupport by the PCESupport by the PSE
Phone Book Browsing FeatureSetPhonebookMM
PullvCardListingMM
PullvCardEntryMM

  • SetPhonebook:选择感兴趣的Phone Object
  • PullvCardListing:client使用该Function获取感兴趣的Phone Object 列表
  • PullvCardEntry:client使用该Function获取感兴趣的Phone Object(单个)
2.3.2.1 SetPhonebook Data Format

请求格式:

Field / HeaderNameValueStatus
FieldOpcodeSETPATH (0x05)M
FieldPacket LengthVariesM
FieldFlagsUp / Down / RootM
FieldConstantReserved (0)M
HeaderConnection IDVariesM
HeaderNameName of the folderO

响应格式:

Field / HeaderNameValueStatus
FieldResponse Code0xA0 or Error CodeM
FieldPacket Length3M
2.3.2.2 PullvCardListing Data Format

请求格式:

Field / HeaderNameValueStatus
FieldOpcodeGET(0x03 or 0x83)M
FieldPacket LengthVariesM
HeaderConnection IDVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderNameName of the folderM
HeaderType"x-bt/vcard-listing"M
HeaderApplication Parameters
- OrderVariesO
- SearchValueVariesO
- SearchPropertyVariesC3
- MaxListCountVariesO
- ListStartOffsetVariesO
- ResetNewMissedCallsVariesC4
- vCardSelectorVariesC5
- vCardSelectorOperatorVariesC6

响应格式:

Field / HeaderNameValueStatus
FieldResponse Code0x09 or 0xA0 or Error CodeM
FieldPacket LengthVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderApplication Parameters
- PhonebookSizeVariesC3
- NewMissedCallsVariesC4
- PrimaryFolderVersionVariesC5
- SecondaryFolderVersionVariesC5
- DatabaseIdentifierVariesC6
HeaderBody/End of BodyvCard object(s)C7
2.3.2.3 PullvCardEntry Data Format

请求格式:

Field / HeaderNameValueStatus
FieldOpcodeGET(0x03 or 0x83)M
FieldPacket LengthVariesM
HeaderConnection IDVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderNameObject name (*.vcf) or X-BT-UID (X-BT-UID)M
HeaderType"x-bt/vcard"M
HeaderApplication Parameters
- PropertySelectorVariesO
- FormatVariesO

响应格式:

Field / HeaderNameValueStatus
FieldResponse Code0x09 or 0xA0 or Error CodeM
FieldPacket LengthVariesM
HeaderSingle Response Mode0x01C1
HeaderSingle Response Mode Param0x01C2
HeaderApplication Parameters
- DatabaseIdentifierVariesC3
HeaderBody/End of BodyvCard objectC4

 流程图

2.3.3 vcf文件

        Download和Browsing功能描述完成之后,我们需要知道,所有的Phone Object信息都是来自于PSE端,而在PSE端保存Phone Object的方式或者是路径可能有很多;

  • 存储设备

    • 手机:telecom/xxx.vcf
    • SIM卡:SIM1/telecom/xxx.vcf

        无论是哪种存储方式,其对应都有相同的数据存储类型,例如通讯录、通讯记录,而在通讯记录中,又可以分为:来电、去电、未接来电、所有通讯记录。同时电话簿还提供了两个功能:快速拨号和收藏联系人;

上述描述的分类方式,对应了PSE端存储文件格式;

Phone ObjectASFormatDesc
Phone Book Objectpbpb.vcf通讯录
Incoming Calls History Objectichich.vcf来电通话记录
Outgoing Calls History Objectochoch.vcf去电通话记录
Missed Calls History Objectmchmch.vcf未接来电通话记录
Commbined Calls History Objectcchcch.vcf所有的通话记录
Speed-Dial Objectspdspd.vcf快速拨号
Favorite Contacts Objectfavfav.vcf收藏通讯录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人商城系统开源(配置支付宝支付2)

原文地址:个人商城系统开源(配置支付宝支付2) - Pleasure的博客 下面是正文内容: 前言 在上一篇文章中我曾提到过关于网站支付宝支付的方法,接下来我们来介绍第二种。 个人博客地址:个人商城系统开源&…

GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例应用

随着航空、航天、近地空间等多个遥感平台的不断发展,近年来遥感技术突飞猛进。由此,遥感数据的空间、时间、光谱分辨率不断提高,数据量也大幅增长,使其越来越具有大数据特征。对于相关研究而言,遥感大数据的出现为其提…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+GTX 8b/10b编解码SFP光口传输,提供2套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI…

C++:类和对象(上篇)

目录: 一:面向对象和过程的介绍 二:类的引入 三:类的定义 四:类的访问限定符以及封装 五:类的作用域 六:类的实例化 七:类对象大小的计算 八:类成员函数的this指…

【Linux】编译器-gcc/g++的使用(预处理、编译、汇编、连接)

目录 01.预处理(宏替换) 02.编译(生成汇编) 03.汇编(生成机器可识别码) 04.连接(生成可执行文件或库文件) 05.选项 编译器在编译代码时包含以下四个步骤:1.预处理 2…

MongoDB启动报错

spring boot 引入MongoDB启动报错 java.lang.IllegalStateException: Failed to introspect Class [io.micrometer.core.instrument.binder.mongodb.DefaultMongoConnectionPoolTagsProvider] from ClassLoader [sun.misc.Launcher$AppClassLoader18b4aac2] at org.springfra…

爬虫综合案例-获取房源信息并在地图上显示

文章目录 1.项目介绍2.项目分析3.爬取房源信息4. 导入高德地图5.地图上显示房源信息6.运行程序 1.项目介绍 本次案例将从 58 同城信息网爬取相关城市的房源出租信息,然后通过高德地图把房源信息地图显示,通过地图进行浏览,点击相应的热点文字…

[运维] 可视化爬虫易采集-EasySpider(笔记)

一、下载 ​下载地址 下滑到Assets页面,选择下载 二、解压运 ​解压压缩包,打开文件夹 在此文件夹下打开Linux Terimal, 并输入以下命令运行软件: ./easy-spider.sh 注意软件运行过程中不要关闭terminal。 三、使用 1.开始 首先点击…

使用 CSS 实现毛玻璃效果

在现代 Web 设计中,毛玻璃效果越来越受欢迎。它能够让界面元素看起来更加柔和、朦胧,同时又不会完全遮挡背景内容,给人一种透明而又不失质感的视觉体验。虽然过去实现这种效果需要借助图像编辑软件,但现在只需要几行 CSS 代码,就可以在网页上呈现出令人惊艳的毛玻璃效果。 使用…

IDEA 配置阿里规范检测

IDEA中安装插件 配置代码风格检查规范 使用代码风格检测 在代码类中,右键 然后会给出一些不符合规范的修改建议: 保存代码时自动格式化代码 安装插件: 配置插件:

SPSS k-均值聚类的 anova分析表解读

from&#xff1a;SPSS K均值聚类&#xff08;k-means&#xff09;和可视化方法 - CollinsLi - 博客园 (cnblogs.com) F值&#xff1a;变量对聚类的贡献 显著性水平&#xff1a;<0.05 则因子显著

CMake笔记之PROJECT_SOURCE_DIR、CMAKE_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR对比

CMake笔记之PROJECT_SOURCE_DIR、CMAKE_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR对比 —— 杭州 2024-03-19 夜 code review! 文章目录 CMake笔记之PROJECT_SOURCE_DIR、CMAKE_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR对比1.三者区别2.具体示例说明3.CMAKE_SOURCE_DIR 和 PROJECT_S…

Sora没体验资格?开源项目:Open-Sora,复现类Sora视频生成方案

项目简介 Open-Sora项目是一项高效制作高质量视频的工作&#xff0c;明确所有权使用其模型、工具和内容的计划。通过采用开源原则&#xff0c;Open-Sora 不仅实现了先进的视频生成技术的普及&#xff0c;还提供了一个专业且用户界面的方案&#xff0c;简化了视频制作的复杂性。…

php 对接Pangle海外广告平台收益接口Reporting API

今天对接的是Pangle广告reporting api接口&#xff0c;拉取广告收益回来自己做统计。记录分享给大家 首先是文档地址,进入到Pangle后台就能看到文档地址以及参数&#xff1a; 文档地址&#xff1a;https://www.pangleglobal.com/zh/integration/reporting-api-v2 在这里插入图片…

算法---二分查找练习-2(寻找旋转排序数组中的最小值)

寻找旋转排序数组中的最小值 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 首先&#xff0c;检查数组的最后一个元素是否大于第一个元素。如果是&#xff0c;说明数组没有进行旋转&#xff0c;直接返回第一个元素作为最小值…

稀碎从零算法笔记Day22-LeetCode:

题型&#xff1a;链表 链接&#xff1a;2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;Leet 题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 …

vue项目:使用xlsx导出Excel数据

文章目录 一、安装xlsx二、报错及解决三、编写公共方法四、方法使用 一、安装xlsx 执行命令&#xff1a;npm i xlsx file-saver --save 二、报错及解决 使用时&#xff1a;import XLSX from "xlsx"; 发现如下报错信息 报错原因&#xff1a;xlsx版本不兼容。 解…

Java项目基于SpringBoot和Vue的时装购物系统的设计与实现

今天要和大家聊的是一款基于SpringBoot和Vue的时装购物系统。 &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&#x1f495;个人简介&#xff1a;混迹在java圈十年有余&#xff0c;擅长Java、微信小程序、Python、Android等&#xff0c;大家有这一块的问题可…

web前端之不一样的下拉菜单、不选中第一个元素的样式效果、伪类排除第一个元素、符号选择器、hover、not、first、child

MENU 效果图htmlcssJShtmlcss 效果图 htmlcssJS html <nav><ul><li class"navli"><h4>HTML5</h4><ul class"ulson"><li class"lison">HTML5</li></ul></li><li class"na…

Django单表数据库操作

单表操作 测试脚本 当你只想测试django某一个py文件的内容,可以不用书写前后端的交互,直接写一个测试脚本即可 单表删除 数据库操作方法: 1.all():查询所有的数据 2.filter():带有过滤条件的查询 3.get():直接拿数据对象,不存在则报错 4.first():拿queryset里面的第一个元素…