蓝牙低功耗(BLE)概述

一、初始蓝牙低功耗

Android 4.3(API Level 18)开始引入Bluetooth Low Energy(BLE,低功耗蓝牙)的核心功能并提供了相应的 API, 应用程序通过这些 API 扫描蓝牙设备、查询 services、读写设备的 characteristics(属性特征)等操作。

二、通用访问规范GAP

详细介绍 GATT 之前,需要了解 GAP(Generic Access Profile),它在用来控制设备连接和广播GAP 使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与合同设备进行交互。例如 Beacon 设备就只是向外广播,不支持连接,小米手环就等设备就可以与中心设备连接。

1. 设备角色

GAP 给设备定义了若干角色,其中主要的两个是:外围设备(Peripheral)中心设备(Central)

  • 外围设备(Peripheral):这一般就是非常小或者简单的低功耗设备,用来提供数据,并连接到一个更加相对强大的中心设备。例如小米手环。
  • 中心设备(Central):中心设备相对比较强大,用来连接其他外围设备。例如手机等。

2. 广播数据

在 GAP 中外围设备通过两种方式向外广播数据: Advertising Data Payload(广播数据)Scan Response Data Payload(扫描回复),每种数据最长可以包含 31 byte。

这里广播数据是必需的,因为外设必需不停的向外广播,让中心设备知道它的存在。扫描回复是可选的,中心设备可以向外设请求扫描回复,这里包含一些设备额外的信息,例如设备的名字。

3. 广播流程

GAP 的广播工作流程如下图所示:


GAP广播工作流程
  • ADVERTISING INTERVAL:广播间隔
  • ADVERTISING DATA:广播数据
  • SCAN RESPONSE REQUEST:扫描响应请求
  • SCAN RESPONSE DATA:扫描响应数据

外围设备会设定一个广播间隔,每个广播间隔中,它会重新发送自己的广播数据,广播时间越长,越省电,同时也不太容易扫描到。

4. 广播的网络拓扑结构

大部分情况下,外设通过广播自己来让中心设备发现自己,并建立 GATT 连接,从而进行更多的数据交换。

也有些情况是不需要连接的,只要外设广播自己的数据即可。用这种方式主要目的是让外围设备,把自己的信息发送给多个中心设备。因为基于 GATT 连接的方式的,只能是一个外设连接一个中心设备。使用广播这种方式最典型的应用就是苹果的 iBeacon。广播工作模式下的网络拓扑图如下:

广播的网络拓扑结构

5. 更多关于GAP

查看这篇博客

三、通用属性配置文件 GATT

GATT 的全名是 Generic Attribute Profile,它定义两个 BLE 设备通过叫做 Service 和 Characteristic 的东西进行通信。GATT 就是使用了 ATT(Attribute Protocol)协议,ATT 协议把 Service, Characteristic以及对应的数据保存在一个查找表中,次查找表使用 16 bit ID 作为每一项的索引。

一旦两个设备建立起了连接,GATT 就开始起作用了,这也意味着,你必需完成前面的 GAP 协议。这里需要说明的是,GATT 连接,必需先经过 GAP 协议。实际上,我们在 Android 开发中,可以直接使用设备的 MAC 地址,发起连接,可以不经过扫描的步骤。这并不意味不需要经过 GAP,实际上在芯片级别已经给你做好了,蓝牙芯片发起连接,总是先扫描设备,扫描到了才会发起连接。

GATT 连接需要特别注意的是:GATT 连接是独占的。也就是一个 BLE 外设同时只能被一个中心设备连接。一旦外设被连接,它就会马上停止广播,这样它就对其他设备不可见了。当设备断开,它又开始广播。

中心设备和外设需要双向通信的话,唯一的方式就是建立 GATT 连接。

1. 相关专业术语

  • 通用属性配置文件(GATT,Generic Attribute Profile)

    • 现在BLE连接都是建立在 GATT 协议之上。
    • GATT 配置文件是一种通用规范,内容针对在 BLE 链路上发送和接收称为“属性”的简短数据片段
    • GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很短的数据段被称为属性(Attribute)。
    • 目前所有低功耗应用配置文件均以 GATT 为基础。
  • 属性协议(ATT):属性协议 (ATT) 是 GATT 的构建基础,二者的关系也被称为 GATT/ATT。

    • ATT 经过优化,可在 BLE 设备上运行。为此,该协议尽可能少地使用字节。
    • 每个属性均由通用唯一标识符 (UUID) 进行唯一标识,后者是用于对信息进行唯一标识的字符串 ID 的 128 位标准化格式。
    • 由 ATT 传输的属性采用特征和服务格式。
  • 特征:特征包含一个值和 0 至多个描述特征值的描述符。您可将特征理解为类型,后者与类类似。

  • 描述符:描述符是描述特征值的已定义属性。例如,描述符可指定人类可读的描述、特征值的可接受范围或特定于特征值的度量单位。

  • Service — 服务是一系列特征。例如,您可能拥有名为“心率监测器”的服务,其中包括“心率测量”等特征。您可以在 bluetooth.org 上找到基于 GATT 的现有配置文件和服务的列表。

2. GATT连接的网络拓扑

下图展示了 GTT 连接网络拓扑结构。这里很清楚的显示,一个外设只能连接一个中心设备,而一个中心设备可以连接多个外设。Connected Topology一旦建立起了连接,通信就是双向的了,对比前面的 GAP 广播的网络拓扑,GAP 通信是单向的。如果你要让两个设备外设能通信,就只能通过中心设备中转。

GATT连接的网络拓扑

3. GATT通信事务

GATT 通信的双方是 C/S 关系。外设作为 GATT 服务端(Server),它维持了 ATT 的查找表以及 service 和 characteristic 的定义。中心设备是 GATT 客户端(Client),它向 Server 发起请求。需要注意的是,所有的通信事件,都是由客户端(也叫主设备,Master)发起,并且接收服务端(也叫从设备,Slave)的响应。

一旦连接建立,外设将会给中心设备建议一个连接间隔(Connection Interval),这样,中心设备就会在每个连接间隔尝试去重新连接,检查是否有新的数据。但是,这个连接间隔只是一个建议,你的中心设备可能并不会严格按照这个间隔来执行,例如你的中心设备正在忙于连接其他的外设,或者中心设备资源太忙。

下图展示一个外设(GATT 服务端)和中心设备(GATT 客户端)之间的数据交换流程,可以看到的是,每次都是主设备发起请求:


服务端和客户端的数据交换流程
  • Peripheral GATT Server:外围GATT服务器
  • Central GATT Client:中心GATT客户端
  • CONNECTION INTERVAL:连接间隔
  • MASTER(Sends Request):客户端,也称主设备
  • SLAVE(Sends Response):服务器,也称从设备

3. GATT结构

GATT结构

3.1 Profile

  • 可以理解为一种规范,一个标准的通信协议
  • 存在于从机(BLE外设)中,但并不是实际存在的,它只是一个被 Bluetooth SIG 或者外设设计者预先定义的 Service 的集合。
  • 每个profile中会包含多个service,每个service代表从机的一种能力。

蓝牙组织规定了一些标准的profile,例如 HID OVER GATT ,防丢器 ,心率计等。

例如心率Profile(Heart Rate Profile)就是结合了 Heart Rate Service 和 Device Information Service。

3.2 Service

  • 一个低功耗蓝牙设备可以定义许多 Service

  • 可以理解为一个服务,一个功能的集合,在BLE从机中,通常有多个服务,例如电量信息服务、系统信息服务等。

  • Service把数据分成一个个独立逻辑项,每个Service中包含多个Characteristic特征值。

  • 每个具体的Characteristic特征值才是BLE通信的主体。

    比如当前的电量是80%,所以会通过电量信息服务的Characteristic特征值存储在从机的Profile里,这样主机就可以通过这个Characteristic来读取80%这个数据

  • 设备中每一个不同的Service有一个 128 bit 的 UUID 作为这个Service的独立标志

    UUID 有 16 bit 的,或者 128 bit 的。16 bit 的 UUID 是官方通过认证的,需要花钱购买,128 bit 是自定义的,这个就可以自己随便设置。

    官方通过了一些标准 Service,完整列表在这里。以 Heart Rate Service为例,可以看到它的官方通过 16 bit UUID 是 0x180D,包含 3 个 Characteristic:Heart Rate Measurement, Body Sensor Location 和 Heart Rate Control Point,并且定义了只有第一个是必须的,它是可选实现的。

3.3 Characteristic

  • Service下面,又包括了许多的独立数据项,我们把这些独立的数据项称作Characteristic

  • 每一个 Characteristic 也有一个唯一的16 bit 或者 128 bit的 UUID 作为标识符

  • 在 GATT 事务中的最低界别的是 Characteristic,Characteristic 是最小的逻辑数据单元,当然它可能包含一个组关联的数据,例如加速度计的 X/Y/Z 三轴值。

  • 可以理解为一个标签,通过这个标签可以获取或者写入想要的内容

  • BLE主从机的通信均是通过Characteristic来实现

  • 在 Android 开发中,建立蓝牙连接后,我们说的通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据给手机就是监听这些 Characteristic 中的 Value 字段有没有变化,如果发生了变化,手机的 BLE API 就会收到一个监听的回调。

    你可以免费使用 Bluetooth SIG 官方定义的标准 Characteristic,使用官方定义的,可以确保 BLE 的软件和硬件能相互理解。当然,你可以自定义 Characteristic,这样的话,就只有你自己的软件和外设能够相互理解

  • 举个例子, Heart Rate Measurement Characteristic,这是上面提到的 Heart Rate Service 必需实现的 Characteristic,它的 UUID 是 0x2A37。它的数据结构是,开始 8 bit 定义心率数据格式(是UINT8 还是 UINT16?),接下来就是对应格式的实际心率数据。

  • 实际上,和 BLE 外设打交道,主要是通过 Characteristic。你可以从 Characteristic 读取数据,也可以往 Characteristic 写数据。这样就实现了双向的通信。所以你可以自己实现一个类似串口(UART)的 Sevice,这个 Service 中包含两个 Characteristic,一个被配置只读的通道(RX),另一个配置为只写的通道(TX)。

3.4 UUID

  • UUID,统一识别码,我们刚才提到的ServiceCharacteristic,都需要一个唯一的UUID来标识整理一下

  • 蓝牙核心规范制定了两种不同的UUID,一种是基本的UUID,一种是代替基本UUID的16位UUID。所有的蓝牙技术联盟定义UUID共用了一个基本的UUID:

    0x0000xxxx-0000-1000-8000-00805F9B34FB
    为了进一步简化基本UUID,每一个蓝牙技术联盟定义的属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分。例如,心率测量特性使用0X2A37作为它的16位UUID,因此它完整的128位UUID为:
    0x00002A37-0000-1000-8000-00805F9B34FB

  • 每个从机都会有一个叫做Profile的东西存在,不管是上面的自定义的SimpleProfile,还是标准的防丢器Profile,他们都是由一些列Service组成,然后每个Service又包含了多个Characteristic,主机和从机之间的通信,均是通过Characteristic来实现。

其他:

转载于...等我整理完再附上 抱歉抱歉 看了太多了

你可能感兴趣的:(蓝牙低功耗(BLE)概述)