一文带你认识蓝牙 GATT 协议

4,180 阅读9分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

磨刀不误砍柴工,本文了解一些基本的蓝牙协议基础知识

前言

但是对于蓝牙 GATT 概念,我们还是只停留留在 蓝牙协议栈基本框架层面的内容,对于更具体的理解我们还不知道,所以针对示例来说,我们也无从修改测试。

正所谓磨刀不误砍柴工,我们有必要先深入的学习一下 GATT 以及 GATT 相关的一些知识。

本文我们就来了解一下 蓝牙 GATT 到底是什么?同时了解下我们使用的 ESP32-C3 GATT示例的工程的代码结构。


一、概念导图

☆ 即便看完了很多资料,博主自己还是感觉蓝牙协议的专有名词定义有点复杂(相对其他很多物联网无线协议来说),如果不是专门从事蓝牙行业的人,即便官方有资料,对于这些专有名词专有定义也难以全部理解到位。

☆ 但是我们系列博文最终是以应用为目的,使用蓝牙最终还是使用蓝牙做一些数据的传输交互应用。所以对于专有名词暂时不用研究那么深,知道一些基本概念的的作用和意义即可。

对于基本的概念知识,查阅了很多相关的资料后多少有了一个初步的认识,对于蓝牙 GATT 来说,以应用为主所需要的了解的基本概念,主要就是 GATT,GAP,ATT 这几个协议,在系列博文第一篇《ESP32-C3 学习测试 蓝牙 篇(一、认识 ESP-IDF 的蓝牙框架、简单的了解蓝牙协议栈)》关于蓝牙协议的说明对于这几个协议的简单说明,如下图:

图片.png

对于我们的应用来说,蓝牙无非是用来进行数据交互,我们直接从应用说起,我们使用手机和开发板进行蓝牙通讯,对应的 手机就是 Client 设备,开发板就是 Server 设备。

对于我的学习来说,就是从 BLE通信的这两种设备入手的 :Client 和 Server。

GATT 的结构

对于 Client 和 Server 的通讯,先来看一张图:

图片.png

从上面的示意图可以看出,对于 GATT server 有很多分支,可想而知对于他的协议规定会有很多专有名词,我们的应用程序也大多是对 GATT server 这些参数进行修改配置,我总结了几张概念导图。

图片.png

图中用的是 GATT Server 后面的分支应该是 Service!!

Service 的结构

图中用的是 Server(服务器),应该用 Service ,做图的时候估计还有点蒙:

图片.png

上图中虽然以 Server 作为开头,其实 Server 可组成一个叫 profile 的概念(下面概念说明会讲到 )。

Profile 的结构

蓝牙官方文档中对于 Profile 说明图:

图片.png

二、概念说明

虽然上面上了一张概念导图,但是对于里面的一些基本概念我们有必要一个一个单独说明一下。

2.1 名词解释

对概念导图中提到的专有名词进行单独的说明。

Server

  • Service可以理解为一个服务,提供数据的服务,比如从机设备,但是在一个 Ble 从机中,可以有多个服务。

    Server 和 Client 通过ATT PDU进行交互。

    Server通过characteristic对数据进行封装,每个service中又包含多个characteristic特征值。

profile

  • 如果上面说的 service 是一个蓝牙联盟定义的标准服务,也可以称其为profile。

    profile 可以理解为一种规范,一个标准的通信协议,它存在于从机中。

    蓝牙组织规定了一些标准的profile,比如HID/心率计/体温计/血糖仪等,都是标准蓝牙服务,因此都有相应的profile规格书。

    每个从机都会有一个叫做profile的东西存在,不管是的自定义的simpleprofile,还是标准的心率计profile。

    每个profile中会包含多个service,每个service代表从机的一种能力。

characteristic

  • 上面讲到: Server通过characteristic对数据进行封装,每个service中又包含多个 characteristic 特征值。

    ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。

    一个characteristic包含三种条目:characteristic声明,characteristic的值以及characteristic的描述符。

    这3个条目的含义可参考上面的概念导图,这里需要说明的是它们是用attribute来表达的,它们每一个都是一个 attribute 。

    Characteristic是在GATT规范中最小的逻辑数据单元,由一个Value和多个描述特性的Desciptior组成。实际上,在与蓝牙设备打交道,主要就是读写Characteristic的value来完成。

attribute

  • Attribute 是属于 ATT属性层的东西,它是 ATT层 的核心。

    Attribute其实就是一条一条的数据。前面说过,每个蓝牙设备就是用来提供服务的,而服务就是众多数据的合集,这个合集可以称为数据库,数据库里面每个条目都是一个attribute。

    Attribute 由以下 4 部分组成:属性句柄(Attribute Handler)、属性类型(Attribute Type)、属性值(Attribute Value)、属性权限(Attribute Permissions)。

    图片.png

UUID

  • UUID(universally uniqueidentifier,通用唯一识别码)是一个软件构建标准,一个合法的UUID,一定是随机的、全球唯一的。(UUID并不是BLE独有的概念)

    上面提到的 service 和 characteristic,都需要一个唯一的uuid来标识。

    UUID是128 bit的。

    蓝牙联盟采用为官方的UUID:0000xxxx-0000-1000-8000-00805F9B34FB(上面概念图和推荐博文有详细说明)

2.2 GATT (Generic Attribute Profile)

GATT (通用属性配置) ,它定义两个 BLE 设备通过 Service 和 Characteristic 进行通信;

GATT 就是使用了 ATT(Attribute Protocol)协议,ATT层定义了一个通信的基本框架,数据的基本结构,以及通信的指令,Service 和 characteristic 就是GATT层定义的, GATT层用来赋予每个数据一个具体的内涵,让数据变得有结构和意义。

前面说过 server 端提供服务,服务就是数据,而数据就是一条一条的attribute,而service和characteristic 就是数据的逻辑呈现,或者说用户能看到的数据最终都转化为 service 和 characteristic。

一旦两个设备建立起了连接,GATT 就开始起作用了,这里需要说明的是,GATT 连接必需先经过 GAP 协议。

GATT 连接需要特别注意的是:GATT 连接是独占的。也就是一个 BLE 外设同时只能被一个中心设备连接;

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

2.3 GAP(Generic Access Profile)

Generic Access Profile(通用访问规范) 它在用来控制设备连接和广播,用于提供蓝牙设备的通用访问功能,包括设备发现、连接、鉴权、服务发现等等。

GATT是建立连接后通信规范, 而蓝牙是通过GAP建立通信的。

GAP 使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与合同设备进行交互。

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

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

2.4 ATT(Attribute Protocol)

ATT(Attribute Protocol)属性层是 GATT 和 GAP 的基础,它定义了BLE协议栈上层的数据结构和组织方式。

ATT协议定义了两种角色:服务器角色和客户端角色。

站在蓝牙协议栈角度来看,ATT层定义了一个通信的基本框架,数据的基本结构,以及通信的指令,而GATT层就是前文所述的service和characteristic,GATT层用来赋予每个数据一个具体的内涵,让数据变得有结构和意义。

GATT 是脱胎于 ATT ,ATT 是 Attribute Protocol Specification 属性规范协议,注意ATT是协议,而GATT是规范,两者不同点在于 ATT规定了数据格式,而 GATT 则是按照 ATT 的格式将具体数据填充进去。

三、Client 设备连接说明

我们上面讲了很多关于蓝牙 GATT 的概念知识,我们开发板使用了 GATT server 示例后,就是一个 Server 设备,我们的手机就是 Client 设备。

当我们连接上以后,其实可以查看 Server 的信息的,为了加深对上面的概念的理解,我们使用手机连接后的图片来说明一些概念:

图片.png

图片.png

图片.png

在上图中有一点,结合上面第一小节《一、概念导图》 中的 Profile的结构 说明,每个 characteristic 都带有Properties,这个 Properties 为蓝牙特征值的读写权限:

属性名称描述
read支持 read 操作
write支持 write 操作
notify支持 notify 操作
indicate支持 indicate 操作

上面是手机客户端与我们烧录示例的 ESP32-C3 开发板连接后的截图,配合本文的上面一些说明,可以让我们更直观的理解上面提到的概念。

结语

在写本文前,博主自己确实对蓝牙的这些概念不太理解,当初看这些概念的时候也参考了很多很多文章,花了很多时间去记住整理这些概念,到现在使用起来还是需要对着概念图看,尴尬 = =!

所谓开发蓝牙应用程序,其实就是开发 service 和 characteristic。通过API,添加自己需要的characteristic 和 service,一个蓝牙设备就诞生了。

只要 characteristic 和 service 是符合GATT规范的,你可以随意添加任何characteristic和service,并将他们组合成一个专门的蓝牙设备。由于这个蓝牙设备是按照规范来定义的,所以它可以与任何其他蓝牙设备,比如手机,互联互通,并完成所要求的的交互动作。

本文我们基本上把蓝牙 GATT 的概念认识了一遍,就算从来没接触过蓝牙,从本文入手,应该也能算是入门了解过了一些。 当然,本文并没有深入的阐述每一个概念,一来对于蓝牙协议,博主也是初学者;二来博主还是以应用为目的,应用就是先能够使用修改起来,再谈深入。

那么蓝牙系列的下一篇文章,我们就要回到示例 GATT server ,分析一下示例程序代码,通过实际的程序加深我们对蓝牙 GATT的理解,同时开始进行初步的修改测试 。