BLE蓝牙协议 — BLE连接建立过程梳理(三)_蓝牙协议时序图-程序员宅基地

技术标签: 连接建立过程  BLE/BT蓝牙协议  BLE  

文章出处iini01的博客

                BLE蓝牙的连接和配对过程

转载文章,如有不妥,通知后我会立即删除)

同一款手机,为什么跟某些设备可以连接成功,而跟另外一些设备又连接不成功?同一个设备,为什么跟某些手机可以建立连接,而跟另外一些手机又无法建立连接?同一个手机,同一个设备,为什么他们两者有时候连起来很快,有时候连起来又很慢?Master是什么?slave又是什么?什么又是Connection event和slave latency?希望这篇文章能帮助你回答上述问题。


BLE连接示例

假设我们有一台手机A(以安卓手机为例),一个设备B(设备名称:Nordic_HRM),如下所示,我们可以通过安卓设置菜单里面的蓝牙界面,让两者连接起来。

  1. 打开安卓设置菜单
  2. 选择“蓝牙”条目
  3. 打开蓝牙
  4. 等待系统搜索结果,不出意外的话,设备“Nordic_HRM”会出现在结果列表中
  5. 点击“Nordic_HRM”,手机将与此设备建立连接

上述即为大家直观感受到的“连接”,那么手机要与设备Nordic_HRM建立连接,具体包含哪些流程?他们为什么可以连接成功?下面给大家一一道来。


广播(advertising)

在手机跟设备B建立连接之前,设备B需要先进行广播,即设备B(Advertiser)不断发送如下广播信号,t为广播间隔。每发送一次广播包,我们称其为一次广播事件(advertising event),因此t也称为广播事件间隔。虽然图中广播事件是用一根线来表示的,但实际上广播事件是有一个持续时间的,蓝牙芯片只有在广播事件期间才打开射频模块,这个时候功耗比较高,其余时间蓝牙芯片都处于idle状态,因此平均功耗非常低,以Nordic nRF52810为例,每1秒钟发一次广播,平均功耗不到11uA

 

上面只是一个概略图,按照蓝牙spec,实际上每一个广播事件包含三个广播包,即分别在37/38/39三个通道上同时广播相同的信息,即真正的广播事件是下面这个样子的。

 

设备B不断发送广播信号给手机(Observer),如果手机不开启扫描窗口,手机是收不到设备B的广播的,如下图所示,不仅手机要开启射频接收窗口,而且只有手机的射频接收窗口跟广播发送的发射窗口匹配成功,手机才能收到设备B的广播信号。由于这种匹配成功是一个概率事件,因此手机扫到设备B也是一个概率事件,也就是说,手机有时会很快扫到设备B,比如只需要一个广播事件,手机有时又会很慢才能扫到设备B,比如需要10个广播事件甚至更多。


建立连接(connection)

根据蓝牙spec规定,advertiser发送完一个广播包之后150us(T_IFS),advertiser必须开启一段时间的射频Rx窗口,以接收来自observer的数据包。Observer就可以在这段时间里给advertiser发送连接请求。如下图所示,手机在第三个广播事件的时候扫到了设备B,并发出了连接请求conn_req

 

上图的交互流程比较粗略,为此我们引入下图,以详细描述连接建立过程。

图5:连接建立过程

注:图中M代表手机,S代表设备B,M->S表示手机将数据包发给设备B,即手机开启Tx窗口,设备B开启Rx窗口;S->M正好相反,表示设备B将数据包发给手机,即设备B开启Tx窗口,手机开启Rx窗口。

如图所示,手机在收到A1广播包ADV_IND后,以此为初始锚点(这个锚点不是连接的锚点),T_IFS后给Advertiser发送一个connection request命令,即A2数据包,告诉advertiser我将要过来连你,请做好准备。Advertiser根据connect_req命令信息做好接收准备,connect_req包含如下关键信息:

  • Transmit window offset,定义如图5所示
  • Transmit window size,定义如图5所示
  • connect_req数据包完整定义如下所示  

connect_req其实是在告诉advertiser,手机将在Transmit Window期间发送第一个同步包(P1)给你,请在这段时间里把你的射频接收窗口打开。设备B收到P1后,T_IFS时间后将给手机回复数据包P2。一旦手机收到数据包P2,连接即可认为建立成功。后续手机将以P1为锚点(原点),Connection Interval为周期,周期性地给设备B发送Packet,Packet除了充当数据传送功能,它还有如下两个非常重要的功能:

  1. 同步手机和设备的时钟,也就是说,设备每收到手机发来的一个包,都会把自己的时序原点重新设置,以跟手机同步。
  2. 告诉设备你现在可以传数据给我了。连接成功后,BLE通信将变成主从模式,因此把连接发起者(手机)称为Master或者Central,把被连接者(之前的Advertiser)称为Slave或者Peripheral。BLE通信之所以为主从模式,是因为Slave不能“随性”给Master发信息,它只有等到Master给它发了一个packet后,然后才能把自己的数据回传给Master。


连接失败

有如下几种典型的连接失败情况:

  1. 如图5所示,如果slave在transmit window期间没有收到master发过来的P1,那么连接将会失败。此时应该排查master那边的问题,看看master为什么没有在约定的时间把P1发出来。
  2. 如果master在transmit window期间把P1发出来了,也就是说master按照connect_req约定的时序把P1发出来了,但slave没有把P2回过去,那么连接也会失败。此时应该排查slave这边的问题,看一看slave为什么没有把P2回过去
  3. 如果master把P1发出来了,slave也把P2回过去了,此时主机还是报连接失败,这种情况有可能是master软件有问题,需要仔细排查master的软件。
  4. 还有一种比较常见的连接失败情况:空中射频干扰太大。此时应该找一个干净的环境,比如屏蔽室,排除干扰后再去测试连接是否正常。


Connection events

连接成功后,master和slave在每一个connection interval开始的时候,都必须交互一次,即master给slave发一个包,slave再给master发一个包,整个交互过程称为一个connection event。蓝牙芯片只有在connection event期间才把射频模块打开,此时功耗比较高,其余时间蓝牙芯片都是处于idle状态的,因此蓝牙芯片平均功耗就非常低,以Nordic nRF52810为例,每1秒钟Master和Slave通信1次,平均功耗约为6微安左右。Master不可能时时刻刻都有数据发给slave,所以master大部分时候都是发的空包(empty packet)给slave。同样slave也不是时时刻刻都有数据给master,因此slave回复给master的包大部分时候也是空包。另外在一个connection event期间,master也可以发多个包给slave,以提高吞吐率。综上所述,连接成功后的通信时序图应该如下所示:

 

图7: 连接成功后的通信时序图(每个connection event只发一个包)

图9: 连接成功后的通信时序图( connection event可能发多个包)

 

图10:connection event细节图


Slave latency

图10中出现了slave latency(slave latency = 2),那么什么叫slave latency?

如前所述,在每一个connection interval开始的时候,Master和Slave必须交互一次,哪怕两者之间交互的是empty packet(空包),但如果slave定义了slave latency,比如slave latency = 9,此时slave可以每9个connection interval才回复一次master,也就是说slave可以在前面8个connection interval期间一直睡眠,直到第9个connection interval到来之后,才回复一个packet给master,这样将大大节省slave的功耗,提高电池续航时间。当然如果slave有数据需要上报给master,它也可以不等到第9个connection interval才上报,直接像正常情况进行传输即可,这样既节省了功耗,又提高了数据传输的实时性。


GAP层角色总结

对上面提到的手机和设备B,在BLE通信过程中,随着时间的推移,他们的状态在发生变化,两者的关系也在发生变化,为此蓝牙spec根据不同的时间段或者状态给手机和设备B取不同的名字,即GAP层定义了如下角色:

  • advertiser。 发出广播的设备
  • observer或者scanner。可以扫描广播的设备
  • initiator。能发起连接的设备
  • master或者central。连接成功后的主设备,即主动发起packet的设备
  • slave或者peripheral。连接成功后的从设备,即被动回传packet的设备

图11通过时间把observer,initiator和central串起来了,其实这三个角色是相互独立的,也就是说一个设备可以只支持observer角色,而不支持initiator和central角色。同样,图11也把advertiser和peripheral串起来了,其实advertiser和peripheral也是相互独立的,即一个设备可以只作为advertiser角色,而不支持peripheral角色。

图11:GAP层角色

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhanghuaishu0/article/details/81189577

智能推荐

基于小波变换的时间序列预测,Python实现,来自雪球,_预测振荡-程序员宅基地

文章浏览阅读4.6w次,点赞34次,收藏333次。作者:量化哥-优矿Uqer链接:https://xueqiu.com/4105947155/67920429?page=1来源:雪球基于小波变换的时间序列预测本文的主题是考察小波变换在预测方面的应用。思路将数据序列进行小波分解,每一层分解的结果是上次分解得到的低频信号再分解成低频和高频两个部分。如此进过N层分解后源信号X被分解为:X = D1 + D2 + _预测振荡

64位Linux编译C代码,crt1.o文件格式不对的问题-程序员宅基地

文章浏览阅读4.6k次。今天在某台64位LInux下编译一个简单的hello world的C程序,报错:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../crt1.o: could not read symbols: File in wrong format查看该文件的格式,竟然是32位的:[@s366.zjm.db.d tmp]# file /usr/lib/g_crt1.o

Python基础教程:切片的赋值-程序员宅基地

文章浏览阅读241次,点赞5次,收藏9次。切片有一个强大功能是给切片赋值,如果把切片放在赋值语句的左边,或把它作为del操作的对象,我们就可以对序列进行嫁接、切除或就地修改操作。当起止位置信息都可见时,可以快速计算出长度,用stop - start就可以了,比如my_list[1:3]长度为2。利用任意一个下标把序列切割成不重叠的两部分,只要写成my_list[:x]和my_list[x:]就可以了,比如。,意思是对s在a和b之间以c为间隔取值,c还可以为负,负值意味着反向取值。Python学习交流,免费公开课,免费资料,

ArcGIS For JavaScript API OpenStreetMap Layer(打开街道地图层)————(九)_openstreetmap采用api编程-程序员宅基地

文章浏览阅读5.1k次。描述:此示例演示如何添加OpenStreetMap的地图层,使用默认选项。在这个代码中,创建一个新的OpenStreetMapLayer一个添加到地图上。osmLayer = new esri.layers.OpenStreetMapLayer();map.addLayer(osmLayer);有几个可选的构造函数的参数,可以用来定义附加的可见性,透明度和显示级别的值,_openstreetmap采用api编程

(附源码)ssm高校实验室系统 毕业设计 800008_学校实验管理系统源代码-程序员宅基地

文章浏览阅读1k次,点赞7次,收藏4次。技术可行性:(1)硬件可行性分析系统的硬件要求方面不存在特殊的要求,只需要在普通的硬件配置就能够轻松的实现,只是需要确保系统的正常工作即可,以及拥有较高的效率。如果有特别低的硬件,它可以导致系统的低性能以及效率低,从而导致整个网站的运行不顺畅。以目前普遍的个人计算机的配置而言,这是十分容易实现的 。因此,本系统的开发在硬件方面是可行的。提供完整的技术支持和保护,确保网站的稳定,安全运行,提供24×7和24小时技术支持项目完成提供主要的服务器系统安全及时的通知和更新服务。(2)软件可行性分析提供一个_学校实验管理系统源代码

SIT2596,可替代LM2596,40V 输入 150KHz 3A 降压型电源转换器-程序员宅基地

文章浏览阅读655次。SIT2596 封装形式包括标准的 5 脚 TO-220 封装(DIP)和 5 脚 TO-263 表贴封装(SMD)。输出电压,电压输出范围在 1.2V-37V,输入电压最高可达 40V,输出电流可达 3A;SIT2596 是一款降压型开关电压调节芯片,可固定输出 3.3V、5V、12V,也可根据需要调节。准电感,这更优化了 SIT2596 的使用,极大地简化了开关电源电路的设计,节约了外围的成本。可选固定输出 3.3V、5V、12V 电压或输出电压可调;优异的线性调整率和负载调整率;_替代lm2596

随便推点

SOLIDWORKS手把手教你安装_solidworks安装教程-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏29次。若已经没有该文件,需重新解压安装包。12.打开安装包解压后的【SolidWorks2022(64bit)】文件夹,鼠标右击【虚拟光驱】选择【以管理员身份运行】。31.打开安装包解压后的【SolidWorks2022(64bit)】文件夹,双击打开【_SolidSQUAD_】文件夹。34.打开解压后的【SolidWorks2022(64bit)】,双击打开【_SolidSQUAD_】文件夹。_solidworks安装教程

windows10 安装tensorflow (cpu版本)_tensorflow-intel是cpu版的吗-程序员宅基地

文章浏览阅读8.6k次。参考https://blog.csdn.net/sylsjane/article/details/80871736安装tensorflow1.在开始菜单中找到Anaconda Prompt,双击运行2.输入清华的仓库镜像(更新包更快):conda config --add channels https://mirrors.tuna.tsinghua.edu.c..._tensorflow-intel是cpu版的吗

【 找出不是两个数组共有的元素 】 给定两个整型数组,本题要求找出不是两者共有的元素。-程序员宅基地

文章浏览阅读3.2w次,点赞8次,收藏13次。 输入格式:输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。输出格式:在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。输入样例:10 3 -5 2 8 0 3 5 -15 9 10011 6 4 8 2 6 -5 9 0 100 8 1输出样例:3..._找出不是两个数组共有的元素

简单图形界面初学 :tkinter+阿里云接口+爬虫,实现全国天气查询_tkinter显示爬虫七天天气折线图-程序员宅基地

文章浏览阅读1.1k次。 可能需要的环境: Python 3.6官网下载 需要下载的第三方库:requests 其余为python自带不需要下载 首先看下效果图具体写作过程参考b站视频传送门:GUI天气预报接下来实现过程,首先创建窗口,设置标题,布局窗口,设置标签,按钮,就直接粘贴代码:如果对创建窗口的函数不熟悉:请点击python中tkinter的使用(控件整理)(一..._tkinter显示爬虫七天天气折线图

JavaScript 逐点突破之单线程与异步,作为前端必知必会-程序员宅基地

文章浏览阅读638次,点赞12次,收藏28次。优点:实现比较简单,执行环境相对单纯缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段 Javascript 代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。为了解决这个问题,JavaScript 语言将任务的执行模式分为两种:同步和异步。

Python 学习路线思维导图, 经典收藏!-程序员宅基地

文章浏览阅读271次。目前为止,我总结了Python的知识体系,并且暂时包括了十五章内容。 Python简介 基础知识 列表和元祖 字符串 字典 条件、循环和其他语句 抽象 更加抽象 异常 魔法方法、属性和迭代器 模块 文件和流 图形用户界面 数据库支持 网络编程 ...