【蓝牙协议栈】【BLE】低功耗蓝牙工作流程(角色\广播\扫描\连接等专业名词介绍)

本文主要是介绍【蓝牙协议栈】【BLE】低功耗蓝牙工作流程(角色\广播\扫描\连接等专业名词介绍),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论

2. 欢迎大家关注和订阅,【精讲蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待!

前言

        本节我们介绍低功耗蓝牙的基本行为状态和主从机交互过程,为后面的低功耗蓝牙协议的学习准备基础

1. BLE工作流程介绍

1.1 角色

BLE设备角色主要分为两种角色,主机(Master或Central)从机(Peripheral),当主机和从机建立连接之后才能相互收发数据

  • 主机,主机可以发起对从机的扫描连接。例如手机,通常作为BLE的主机设备
  • 从机,从机只能广播并等待主机的连接。例如智能手环,是作为BLE的从机设备

另外还有观察者(Observer)广播者(Broadcaster),这两种角色不常使用,但也十分有用,例如iBeacon,就可以使用广播者角色来做,只需要广播特定内容即可。

  • 观察者,观察者角色监听空中的广播事件,和主机唯一的区别是不能发起连接,只能持续扫描从机。
  • 广播者,广播者可以持续广播信息,和从机的唯一区别是不能被主机连接,只能广播数据

蓝牙协议栈没有限制设备的角色范围,同一个BLE设备,可以作为主机,也可以作为从机,我们称之为主从一体,主从一体的好处是,每个BLE设备都是对等的,可以发起连接,也可以被别人连接,更加实用。

1.2 广播

广播是指从机每经过一个时间间隔发送一次广播数据包,这个时间间隔称为广播间隔,这个广播动作叫做广播事件,只有当从机处于广播状态时,主机才能发现该从机。

在每个广播事件中,广播包会分别在37,38和39三个信道上依次广播,如下图所示。

广播时间间隔的范围是从20ms到10.24s,广播间隔影响建立连接的时间。广播间隔越大,连接的时间越长。

另外BLE链路层会在两个广播事件之间添加一个0~10ms的随机延时,保证多个设备广播时,不会一直碰撞广播。也就是说,设置100ms的广播间隔,实际上两次广播事件的时间间隔可能是100~110ms之间的任意时间。

广播数据包最多能携带31个字节的数据,一般包含可读的设备名称,设备是否可连接等信息。

当主机收到从机广播的数据包后,它可以再发送获取更多数据包的请求,这个时候从机将广播扫描回应数据包,扫描回应数据包和广播包一样,可以携带31个字节的数据。

注意:

        蓝牙4.x,广播有效载荷最多是31个字节。而在蓝牙5.0中,通过添加额外的广播信道和新的广播PDU,将有效载荷增加到了255个字节

1.3 扫描

扫描是主机监听从机广播数据包和发送扫描请求的过程,主机通过扫描,可以获取到从机的广播包以及扫描回应数据包,主机可以对已扫描到的从机设备发起连接请求,从而连接从机设备并通信。

扫描动作有两个比较重要的时间参数:扫描窗口扫描间隔,如果扫描窗口等于扫描间隔,那么主机将一直处于扫描状态之中,持续监听从机广播包。

  • 被动扫描,主机监听广播信道的数据,当接收到广播包时,协议栈将向上层(也就是应用层,用户可编程)传递广播包。
  • 主动扫描,主动扫描除了完成被动扫描的动作外,还会向从机发送一个扫描请求,从机收到该请求时,会再次发送一个称作扫描回应的广播包。

所以,主动扫描比被动扫描,可以多收到扫描回应数据包。

1.4 连接

在BLE连接中,使用跳频方案,两个设备在特定时间、特定频道上彼此发送和接收数据。这些设备稍后在新的通道(协议栈的链路层处理通道切换)上通过这个约定的时间相遇。这次用于收发数据的相遇称为连接事件。如果没有要发送或接收的应用数据,则交换链路层数据来维护连接。两个连接事件之间的时间跨度称为连接间隔,是以1.25 ms为单位,范围从最小值7.5 ms到最大值4.0 s

1.4.1 连接参数

Connection Interval连接间隔,两次连接事件之间的时间间隔称为连接间隔。1.25 ms为单位,范围从最小值7.5 ms到最大值4.0 s

Slave Latency从机延迟,如果从机没有要发送的数据,则可以跳过连接事件,继续保持睡眠节省电量。

Supervision Time-out监控超时,是两次成功连接事件之间的最长时间。如果在此时间内没有成功的连接事件,设备将终止连接并返回到未连接状态。该参数值以10 ms为单位,监控超时值可以从最小值10(100 ms)到3200(32.0 s)。超时必须大于有效的连接间隔。

1.4.2 连接参数更新请求

连接参数由主机发起连接的时候提供,如果从机对连接参数有自己的要求,例如要求更低的功耗,或者更高的通信速率等,从机可以向主机发送连接参数更新请求。

从机可以在连接后的任何时候发起连接参数更新请求,但最好不要在主从建立连接后立刻发起,建议延迟5s左右再发送请求。

连接参数更新请求可以修改:Connection Interval连接间隔,Slave Latency从机延迟,Supervision Time-out监控超时。

1.4.3 有效连接间隔

Effective Connection Interval有效连接间隔等于两个连接事件之间的时间跨度,假设从机跳过最大数量的连接事件,且允许从机延迟(如果从机延迟设置为0,则有效连接间隔等于实际连接间隔,)。

从机延迟表示可以跳过的最大事件数。该数字的范围可以从最小值0(意味着不能跳过连接事件)到最大值499。最大值不能使有效连接间隔(见下列公式)大于16秒。间隔可以使用以下公式计算:

Effective Connection Interval = (Connection Interval) × (+ [Slave Latency])

Consider the following example:

  • Connection Interval: 80 (100 ms)
  • Slave Latency: 4
  • Effective Connection Interval: (100 ms) × (+ 4) = 500 ms

当没有数据从从机发送到主机时,从机每500ms一个连接事件交互一次。

1.4.4 iOS对连接参数的要求

不同的平台对有连接间隔有着不同的要求,例如iOS系统对ble的连接间隔有着如下的要求。

  • Interval Max * (Slave Latency + 1) <=2s
  • Interval Min >=20ms
  • Interval Min + 20 ms <= Interval Max
  • Slave Latency <= 4
  • SupervisionTimeout <= 6 s
  • Interval Max * ( Slave Latency + 1) * 3 < SupervisionTimeout
1.4.5 连接参数的优化考量

在许多应用中,从机跳过最大连接事件数。选择正确的连接参数组在低功耗蓝牙设备的功率优化中起重要作用。以下列表给出了连接参数设置中权衡的总体概述。

减少连接间隔如下:

  • 增加两个设备的功耗
  • 增加双向吞吐量
  • 减少任一方向发送数据的时间

增加连接间隔如下:

  • 降低两个设备的功耗
  • 降低双向吞吐量
  • 增加任一方向发送数据的时间

减少从机延迟(或将其设置为零)如下:

  • 增加外围设备的功耗
  • 减少外围设备接收从中央设备发送的数据的时间

增加从机延迟如下:

  • 在周边没有数据发送期间,可以降低外设的功耗到主机设备
  • 增加外设设备接收从主机设备发送的数据的时间

1.5 通信

通俗的说,我们将从机具有的数据或者属性特征,称之为Profile,Profile可翻译为:配置文件。

从机中添加Profile配置文件(定义和存储Profile),作为GATT的Server端,主机作为GATT的Client端。

Profile包含一个或者多个Service,每个Service又包含一个或者多个Characteristic。主机可以发现和获取从机的Service和Characteristic,然后与之通信。Characteristic是主从通信的最小单元。

  • 主机可主动向从机Write写入或Read读取数据。
  • 从机可主动向主机Notify通知数据。

注意,这里引用了服务 Service 和 特征值 Characteristic 的概念。每个服务和特征值都有自己的唯一标识 UUID,标准UUID为128位,蓝牙协议栈中一般采用16位,也就是两个字节的UUID格式。

一个从机设备包括一个或者多个服务;一个服务中又可以包括一条或者多条特征值,每个特征值都有自己的属性 Property,属性的取值有:可读 Read可写 Write 以及 通知 Notify

  • 可读可写的字面意思容易理解,表示该特征值可以被主机读取和写入数据,
  • 而通知则表示从机可以主动向主机发送通知数据。这便是主从机之间两个典型的通信方式。

下图是一个典型的从机设备,该从机包含有一个Profile,两个个Service和五个Characteristic。我们先来介绍这些特征值的作用,然后介绍如何通过特征值通信。

服务0x180A

180A是蓝牙协议里标准的服务UUID,用来描述设备信息 Device Information,可以通过该服务,来提供从机设备的相关说明,例如硬件版本,软件版本,序列号等信息。这样,主机就可以获取从机的设备信息。上图中我们添加了三个提供具体设备信息的特征值,他们分别是:

  • 特征值0x2A24,描述产品型号 Model Number String,例如某智能锁的产品型号为:“DSL-C07”。
  • 特征值0x2A25,描述产品序列号 Serial Number String,例如某智能锁的产品序列号为:“lkjl0016190502500269”
  • 特征值0x2A26,描述产品固件版本号 Firmaware Revision String,例如某智能锁的固件号为:“2.7.2.0”

上述特征值仅有Read属性,因此主机只能读,不能执行写操作。

服务0xFFF0

FFF0是我们自定义的服务UUID,它包含两个特征值,用来发送和接收数据。

  • 特征值0xFFF1,自定义的数据发送通道,具有Read和Write属性,主机可以通过该特征值,向从机发送数据,至于发送的数据最大长度,可以在Profile中配置。
  • 特征值0xFFF2,自定义的数据接收通道,具有Notify属性,从机可以通过该特征值,主动向主机发送数据。

假设主机写特征值的协议栈函数原型为 int GATT_WriteCharValue(uuid_t UUID, uint8 *pValue, uint8 len)

假设从机发送通知的协议栈函数原型为 int GATT_Notification(uuid_t UUID, uint8 *pValue, uint8 len)

那么主机向从机发送Hello,可以这样调用协议栈的函数:GATT_WriteCharValue(0xFFF1,"Hello",5)

那么从机向主机发送1234,可以这样调用协议栈的函数:GATT_Notification(0xFFF2,"1234",4)

1.6 断开

主机或从机都可以发起断开连接请求,对方会收到该请求,然后断开连接恢复连接前的状态。

1.7 过程演示

现在我们总结一下BLE的工作流程,使用两个虚拟的BLE硬件来模拟主从机的交互过程。

假设有两个BLE设备,使用的是BLE261低功耗蓝牙模块(假设已经下载了用于交互演示的功能固件),一个是主机,名称为:BleCentral,另一个是从机,名称为:BlePeripheral,如下图所示。

1.7.1 步骤1:上电初始化

主机、从机上电后(不分先后顺序),首先进行协议栈初始化和相关功能调用,如下图所示。

  • 主机设备,主机初始化时,需要设置设备类型,设置用于扫描的相关参数,初始化GATT等协议相关的参数。(下一章节详细介绍何为GATT)
  • 从机设备,从机初始化时,需要设置设备名称,广播相关参数,从机Profile等。从机一般会立即开启广播,也可以等待一个事件来触发广播,例如按键触发。
1.7.2 步骤2:主机扫描从机

按键按下,触发主机扫描从机,此时,主机显示屏打印Scanning正在扫描。此刻的从机仍然处于广播状态。

1.7.3 步骤3:发现从机设备

当主机扫描到从机时,可以返回已扫描到的从机相关信息,例如可以提取到下图中的从机设备名称,从机MAC地址,从机的RSSI信号值等数据。

因此,有些应用在从机的广播包或者扫描回应包中添加自定义字段,这样就可以被主机通过扫描的方式拿到数据。

1.7.4 步骤4:发送连接请求

当主机扫描到从机后,通过MAC地址向从机发送连接请求。低功耗蓝牙的连接速度非常快,100ms左右即可成功连接上。如果从机的广播比较大,则会影响连接的速度。

从机在未收到连接请求之前仍然处于自由的广播状态。

1.7.5 步骤5:成功连接从机

当从机收到连接请求后,双方成功建立连接,此时双方的状态均变为已连接状态。

然后主机可以调用协议栈提供的接口函数来获取从机的服务。

1.7.6 步骤6:获取从机服务

获取从机服务通常是在连接成功后就立即执行的,因为只有获取从机的服务后,才能与其通信。下图是主机向从机发送获取服务的请求。

此刻,从机处于已连接状态。响应服务获取请求是在底层自动完成,上层无需理会。

1.7.7 步骤7:成功获取服务

如下图所示,主机成功获取到从机的服务,例如获取到UUID为0xFFF0的Services,该Service有两个特征值,分别是具有读写属性的0xFFF1,以及具有通知属性的0xFFF2。

读写属性是指主机可以读写该特征值的内容。而通知属性是指从机可以通过该特征值向主机发送数据。

1.7.8 步骤8:主机向从机发送数据

主机通过特征值0xFFF1,主动向从机发送自定义数据Hello,当数据成功发送后,主机状态变为:数据已发送。从机将收到主机发来的数据,从机状态变为收到数据。

1.7.9 步骤9:从机向主机发送数据

从机可以通过Norify的方式主动向主机发送数据,例如下图,从机通过特征值0xFFF2发送了一条Notify通知,数据内容为:1234

1.7.10 步骤10:发送断开请求

主机和从机任何一方均可以发起断开连接的请求,对方收到后,状态将变为已断开。

1.7.11 步骤11:成功断开连接

从机收到主机发来的断开请求,此刻状态变为已断开。

这篇关于【蓝牙协议栈】【BLE】低功耗蓝牙工作流程(角色\广播\扫描\连接等专业名词介绍)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931589

相关文章

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Python3.6连接MySQL的详细步骤

《Python3.6连接MySQL的详细步骤》在现代Web开发和数据处理中,Python与数据库的交互是必不可少的一部分,MySQL作为最流行的开源关系型数据库管理系统之一,与Python的结合可以实... 目录环境准备安装python 3.6安装mysql安装pymysql库连接到MySQL建立连接执行S

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语