主要解决方案领域
-
音频传输
Bluetooth®技术摒弃了耳机、耳麦、扬声器等设备上繁琐的接线,彻底改变了音频设备,永远改变了我们消费媒体和体验世界的方式。
-
数据传输
从家用电器和健身追踪器到健康传感器和医疗创新产品,Bluetooth®技术连接着数十亿台日常设备,并促成了无数新设备的发明。
-
设备网络
Bluetooth® Mesh 是创建控制、监控和自动化系统的理想选择,在这些系统中,数十、数百或数千台设备需要可靠、安全地相互通信。
-
位置服务
Bluetooth®技术是开发人员的首选工具,可用于创建用于兴趣点信息和物品查找的近距离解决方案以及定位系统,如用于资产跟踪的实时定位系统和用于寻路的室内定位系统。
零、基本概念 - 官方文档
-
GATT(Generic Attribute Profile 通用属性配置文件)
它定义了两个BLE设备互相传输数据进行通信的方法,该方法用了两个概念,Service和Characteristic。
-
Profile
profile 可以理解为一种规范,标准的通信协议,它存在与蓝牙从机中(服务端)。每个profile中会包含多个service,每个service代表从机的一种能力。
-
Service
在BLE从机中有多个服务,例如:电量信息服务、系统信息服务等; 每个service中又包含多个characteristic特征值; 每个具体的characteristic特征值才是BLE通信的主题,比如当前的电量,电量的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取电量数据。
-
Characteristic
characteristic特征值,BLE主、从机的通信都是通过characteristic来实现,可以理解为一个通道,通过这个通道可以获取或者写入内容。
-
UUID
UUID,统一识别码,每个Service,Characteristic,Descriptor,都是由一个UUID定义。
一、BLE设备连接通信
设备角色
BLE设备角色主要分为两种角色,主机(Master或Central)和从机(Peripheral),当主机和从机建立连接之后才能相互收发数据。
● 主机
主机可以发起对从机的扫描、连接。例如手机,通常作为BLE的主机设备
● 从机
从机只能广播并等待主机的连接。例如智能手环,蓝牙耳机,是作为BLE的从机设备
蓝牙协议栈没有限制设备的角色范围,同一个BLE设备,可以作为主机,也可以作为从机,我们称之为主从一体,主从一体的好处是,每个BLE设备都是对等的,可以发起连接,也可以被别人连接,更加实用。
通信
站在APP作为中心设备的角度,常用于数据交互的通信方式主要有3种:接收通知、写、读,此外还有设置最大传输单元,获取实时信号强度等通信操作。
-
读、写操作
读写是作为主机主动向从机传输和获取数据的主要通信方式
-
通知
有两种方式可以接收通知,indicate和notify。indicate和notify的区别就在于,indicate是一定会收到数据,notify有可能会丢失数据。indicate底层封装了应答机制,如果没有收到中央设备的回应,会再次发送直至成功;而notify不会有central收到数据的回应,可能无法保证数据到达的准确性,优势是速度快。通常情况下,当外围设备需要不断地发送数据给APP的时候,比如血压计在测量过程中的压力变化,胎心仪在监护过程中的实时数据传输,这种频繁的情况下,优先考虑notify形式。当只需要发送很少且很重要的一条数据给APP的时候,优先考虑indicate形式。
-
设置最大传输单元
进行BLE数据相互发送的时候,一次最多能发送20个字节。如果需要发送的数据超过20个字节,有两种方法,一种是主动尝试拓宽MTU,另一种是采用分包传输的方式。
注意:
1、 连接设备前,请先关闭扫描蓝牙,否则连接成功后,再次扫描会发生阻塞,扫描不到设备
2、Android ble最大属性值的长度为600个字节
3、IOS 最大MTU
iOS 在连接时自动启动 MTU 交换。 运行 iOS < 10 的设备将请求 MTU 大小为 158。iOS 10以上的较新设备将请求 MTU 大小为 185。
源码路径:www.aospxref.com/android-10....
stackoverflow:stackoverflow.com/questions/4...
github issue: github.com/don/cordova...
BLE设备连接交互流程
下面有两个BLE设备,一个是主机,名称为:BleCentral,另一个是从机,名称为:BlePeripheral。
步骤1:启动初始化
主机、从机上电后(不分先后顺序),首先进行协议栈初始化和相关功能调用。
● 主机设备初始化时,需要设置设备类型,设置用于扫描的相关参数,初始化GATT等协议相关的参数。
● 从机设备初始化时,需要设置设备名称,广播相关参数,从机Profile等。从机一般会立即开启广播,也可以等待一个事件来触发广播。
步骤2:主机扫描从机
此时,主机正在扫描,从机仍然处于广播状态。
步骤3:发现从机设备
当主机扫描到从机时,可以返回已扫描到的从机相关信息,例如可以提取到下图中的从机设备名称,从机MAC地址,从机的RSSI信号值等数据。
因此,有些应用在从机的广播包或者扫描回应包中添加自定义字段,这样就可以被主机通过扫描的方式拿到数据。
步骤4:发送连接请求
当主机扫描到从机后,通过MAC地址向从机发送连接请求。低功耗蓝牙的连接速度非常快,100ms左右即可成功连接上。
从机在未收到连接请求之前仍然处于自由的广播状态。
步骤5:成功连接从机
当从机收到连接请求后,双方成功建立连接,此时双方的状态均变为已连接状态。
然后主机可以调用协议栈提供的接口函数来获取从机的服务。
步骤6:获取从机服务
获取从机服务通常是在连接成功后就立即执行的,因为只有获取从机的服务后,才能与其通信。
此刻,从机处于已连接状态。响应服务获取请求是在底层自动完成,上层无需理会。
步骤7:成功获取服务
主机成功获取到从机的服务,例如获取到UUID为0xFFF0的Services,该Service有两个特征值,分别是具有读写属性的0xFFF1,以及具有通知属性的0xFFF2。
读写属性是指主机可以读写该特征值的内容。而通知属性是指从机可以通过该特征值向主机发送数据。
步骤8:主机向从机发送数据
主机通过特征值0xFFF1,主动向从机发送自定义数据,当数据成功发送后,主机状态变为:数据已发送。从机将收到主机发来的数据,从机状态变为收到数据。
步骤9:从机向主机发送数据
从机可以通过Norify的方式主动向主机发送数据,例如下图,从机通过特征值0xFFF2发送了一条Notify通知。
步骤10:发送断开请求
主机和从机任何一方均可以发起断开连接的请求,对方收到后,状态将 变为已断开。
步骤11:成功断开连接
从机收到主机发来的断开请求,此刻状态变为已断开。
扫描的工作流程
建议:尽可能少地扫描,因为毕竟扫描是一个比较重的操作,耗电,也会减慢 BLE 连接速度
目前移动设备上适用的蓝牙大多是V4.0以上。
BLE协议栈:由控制器(Controller)、主机控制接口(HCI)和主机(Host)组成。
-
GATT
GATT 连接需要特别注意的是:GATT 连接是独占的。也就是一个 BLE 外设同时只能被一个中心设备连接。一旦外设被连接,它就会马上停止广播,这样它就对其他设备不可见了。当设备断开,它又开始广播。中心设备和外设需要双向通信的话,唯一的方式就是建立 GATT 连接。
GATT 通信的双方是 C/S 关系。外设作为 GATT 服务端(Server),它维持了 ATT 的查找表以及 service 和 characteristic 的定义。中心设备是 GATT 客户端(Client),它向 Server 发起请求。
-
GAP(Generic Access Profile),它用来控制设备连接和广播。GAP 使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与设备进行交互。包括设备发现,建立连接,终止连接,初始化安全特性,设备配置。
GAP层总是作为下面四种角色之一:(1)广播者:不可连接的广播设备。(2)观察者:扫描设备,但不发起建立连接。(3)外部设备:可连接的广播设备,可以在单个链路层连接中作为从机 。(4)集中器:扫描广播设备并发起连接,可以在单个链路层连接中作为主机。
二、BLE应用
分类
BLE应用目前可以分为两大类。
-
基于非连接的:
意思就是外设和周边设备不发生连接,外设主要依赖周边设备发出的BLE广播,也叫做Beacon。这里有两个角色,发送广播的一方叫做Broadcaster。监听广播的一方叫做Observer。这个在蓝牙协议栈的GAP层都有相应的角色定义。
-
基于连接的:
就是外设和周边设备要建议显式的GATT连接,需要双方有通信。这个也有两个角色,外设设备(周边)叫做Peripheral。中心设备(一般是手机)叫做Centeral。
(1)基于非连接的BLE应用,下面是它的网络拓扑结构:
由于广播是单向的,Broadcaster向外发送广播 ,Observer接受广播。总体来说是多对多的关系。BLE广播中也能够带上数据,包括某些私有协议等。所以基于这种协议也是能够开发出独特的应用。完全基于广播的应用,有大名鼎鼎的iBeacon,这是苹果公司基于BLE广播实现的功能,可以实现广告推送以及室内定位。包括某些商场内部柜台寻找的功能,也是基于这种协议开发出来的。
在上图的设备都是单一的角色,而实际上有些设备是可以同时实现两种角色的,它即可以发送广播,也可以接受广播。在现在比较火的智能家居系统中,有很多的传感器,如果一个设备接受到广播,做了处理以后在发送出去,就形成了一个双向的网格,是不是就有点像因特网了,这也就是有名的蓝牙Mesh。
- iBeacon是苹果推出的一种蓝牙定位广播协议
- iBeacon室内定位原理:
ibeacon设备会主动发射蓝牙信号,当手机打开蓝牙靠近ibeacon设备时,就会收到设备发送的蓝牙信号,这时只需要根据ibeacon设备的uuid、major、minor、mac这四个值,就可以确认是哪一台ibeacon设备,然后调用服务端考勤接口(ibeacon设备只为了确认手机在考勤机边上,不需要发送考勤数据到ibeacon设备上),即可实现蓝牙考勤。(参考钉钉蓝牙打卡机)
(2)基于连接的蓝牙应用(Connection App)
一个中心设备可以连接多个外设,但是一个外设只能连接一个中心(主要是因为连接成功以后,外设就会停止对外广播,别人则发现不了它了)。其实一个中心连接的外设设备数量也是有限的,具体看底层芯片的限制
三、BLE中GATT的服务和特征发现机制
- BLE开发过程中协助调试的app(nRF Connect 、BLE调试助手...)
- 在BLE中,GATT客户端发现服务端服务的过程与经典蓝牙不同,经典蓝牙会有专门的SDP协议来完成。而BLE中,这个过程会直接在GATT层完成服务和特征的发现
- respond 应答数据
四、蓝牙连接数据包
1、BLE 连接过程中有三个重要的数据包:SCAN_REQ, SCAN_RSP 和 CONNECT_REQ
- SCAN_REQ:
扫描请求,由主设备(MASTER DEVICE
)向从设备(SLAVE DEVICE
)发出,目的是为了获得从设备的响应以得到更多的从设备广播数据信息(包括设备名字,或者服务UUID
,及其它如厂家特定格式的信息(如硬件版本,软件版本号,设备系列号等等)。 - SCAN_RSP:
从设备对就主设备发起的SCAN_REQ的响应,作为广播包的补充,从设备可以给主设备更多的广播数据,比如说,有些设备在广播包里面没有设备名字,这个时候就可以把设备名字放在这个包里面发给主设备。 - CONNECT_REQ:
主设备向从设备发出连接请求。至此连接建立完成(从设备不会响应这个请求),如果从设备没有连接上面的问题的话,以后主从双方会开始相互交换有效数据(基于GAP,GATT
及SMP
协议)或者交换空包。
2、什么是MTU
MTU (MAXIMUM TRANSMISSION UNIT
)最大传输单元,指在一个PDU (Protocol Data Unit
:协议数据单元,在一个单元中的有效传输数据)能够传输的最大数据量(多少字节可以一次传输给对方)。
3、设置reqeustMtu
MTU
交换是为了在主从双方设置一个PDU中最大能够交换的数据量 ,通过MTU
的交换和双方确认(注意这个MTU
是不可以协商的,只是通知对方,双方在知道对方的极限后会选择一个较小的值作为以后的MTU。
比如说,主设备发出一个150个字节
的MTU
请求,但是从设备回应MTU
是23字节
,那么今后双方要以较小的值23字节
作为以后的MTU
),主从双方约定每次在做数据传输时不超过这个最大数据单元,MTU
交换通常发生在主从双方建立连接关系后。
4、数据包大小(MTU)的限制
Android
系统从4.3(API 18)
开始支持BLE
,且从5.1(API 21)
才开始支持MTU
修改(默认MTU
仅为23字节
,而且传输本身用掉3字节
)。
问题一、为什么BLE默认限制数据传输长度为20个字节?
core spec
(核心规范)里面定义了ATT的默认MTU
为23个bytes
,除去ATT
的opcode
一个字节以及ATT
的handle 2个字节
之后,剩下的20个字节
便是留给GATT
的了。
考虑到有些Bluetooth smart
设备功能弱小,不敢太奢侈的使用内存空间,因此core spec
规定每一个设备都必须支持MTU
为23
。
在两个设备连接初期,大家都像新交的朋友一样,不知对方底细,因此严格的按照套路来走,即最多一次发20个字节
,是最保险的。
由于ATT
的最大长度为512byte
,因此一般认为MTU
的最大长度为512个byte
就够了,再大也没什么意义,你不可能发一个超过512
的ATT
的数据。
所以ATT
的MTU
的最大长度可视为512个bytes
。
问题二、为什么需要记录MTU
记录MTU
主要是用于传输过程中判断数据是否需要分包发送。按照MTU
的大小严格约束每次发送的数据包大小,如果不这么做,很可能远端接收就会出错。除非你的数据包大小本身就很小。
五、 BLE(Bluetooth low energy)协议栈简介
控制器(Controller)
● 物理层(Physical Layer,PHY),工作在免费的2.4G频段,采用高斯频移键控。
● 链路层(Link Layer,LL),控制设备的射频状态,让设备处于这五种状态之一:
- Standby:默认状态,不进行收发。
- Advertising:广播状态,在3个广播信道广播数据包,同时监听和回复扫描者发送的扫描数据包。
- Scanning:扫描状态,在3个广播信息监听广播数据包,同时发送扫描数据包。
- nitiating:初始化状态,在广播信道监听广播数据包,从而发起连接。
- Connection:连接状态。
主机控制接口(HCI)
主机控制接口(Host-Controller Interface,HCI)提供了Host与Controller之间的通道。该接口层的实现可以是软件接口,也可以是标准硬件接口,比如UART,SPI或USB。
主机(Host)
● 逻辑链路控制和适配器协议(Logical Link Control and Adaption Protocol,L2CAP)为上层提供了多路复用、数据分段与重组服务,并且支持逻辑端对端的数据通信。
● 安全管理层(Security Manager,SM)定义了配对和密钥分发的方法,并为其他层提供了与对端设备进行安全连接和数据交换的功能。
● 通用访问规范层(Generic Access Profile,GAP)是BLE协议栈与Application和Profiles的直接接口。它负责设备发现以及连接相关的各项服务,包括工作模式和访问模式。BLE的工作模式有4种:广播、扫描、周边外设和主设备。访问模式包括设备发现、连接模式、认证和服务发现等。
● 属性协议层(Attribute Protocol,ATT)使本地设备可以暴露一些数据或属性给对端设备。它区分两种角色:客户机和服务器。客户机和服务器通过逻辑信道通信。
● 通用属性配置文件层(Generic Attribute Profile,GATT)定义使用ATT的一系列子过程。两个BLE设备之间的数据通信是由这些子过程来处理的。GATT Services和Applications可以直接使用GATT。
BLE协议栈各层功能机制/体系结构
如上图所述,要实现一个BLE应用,首先需要一个支持BLE射频的芯片,然后还需要提供一个与此芯片配套的BLE协议栈,最后在协议栈上开发自己的应用。可以看出BLE协议栈是连接芯片和应用的桥梁,是实现整个BLE应用的关键。那BLE协议栈具体包含哪些功能呢?简单来说,BLE协议栈主要用来对你的应用数据进行层层封包,以生成一个满足BLE协议的空中数据包,也就是说,把应用数据包裹在一系列的帧头(header)和帧尾(tail)中。具体来说,BLE协议栈主要由如下几部分组成:
PHY层(Physical layer物理层)。PHY层用来指定BLE所用的无线频段,调制解调方式和方法等。PHY层做得好不好,直接决定整个BLE芯片的功耗,灵敏度以及selectivity等射频指标。
LL层(Link Layer链路层)。LL层是整个BLE协议栈的核心,也是BLE协议栈的难点和重点。像Nordic的BLE协议栈能同时支持20个link(连接),就是LL层的功劳。LL层要做的事情非常多,比如具体选择哪个射频通道进行通信,怎么识别空中数据包,具体在哪个时间点把数据包发送出去,怎么保证数据的完整性,ACK如何接收,如何进行重传,以及如何对链路进行管理和控制等等。LL层只负责把数据发出去或者收回来,对数据进行怎样的解析则交给上面的GAP或者ATT。
HCI(Host controller interface)。HCI是可选的,HCI主要用于2颗芯片实现BLE协议栈的场合,用来规范两者之间的通信协议和通信命令等。
GAP层(Generic access profile)。GAP是对LL层payload(有效数据包)如何进行解析的两种方式中的一种,而且是最简单的那一种。GAP简单的对LL payload进行一些规范和定义,因此GAP能实现的功能极其有限。GAP目前主要用来进行广播,扫描和发起连接等。
L2CAP层(Logic link control and adaptation protocol)。L2CAP对LL进行了一次简单封装,LL只关心传输的数据本身,L2CAP就要区分是加密通道还是普通通道,同时还要对连接间隔进行管理。
SMP(Secure manager protocol)。SMP用来管理BLE连接的加密和安全的,如何保证连接的安全性,同时不影响用户的体验,这些都是SMP要考虑的工作。
ATT(Attribute protocol)。简单来说,ATT层用来定义用户命令及命令操作的数据,比如读取某个数据或者写某个数据。BLE协议栈中,开发者接触最多的就是ATT。BLE引入了attribute概念,用来描述一条一条的数据。Attribute除了定义数据,同时定义该数据可以使用的ATT命令,因此这一层被称为ATT层。
GATT(Generic attribute profile )。GATT用来规范attribute中的数据内容,并运用group(分组)的概念对attribute进行分类管理。没有GATT,BLE协议栈也能跑,但互联互通就会出问题,也正是因为有了GATT和各种各样的应用profile,BLE摆脱了ZigBee等无线协议的兼容性困境,成了出货量最大的2.4G无线通信产品。