磨刀不误砍柴工,本文了解一些基本的蓝牙协议基础知识
... 更新概念导图部分关于 Server 和 Service 文字说明 2022/6/13
... 修改出错的地方,细节优化 2023/5/29
目录
前言
上一篇系列文章我们使用 ESP-IDF 中的示例 GATT server,完成了手机连接开发板的初次体验。
虽然上文我们找到的入门的 GATT server 示例,但是对于蓝牙 GATT 概念,我们还是只停留留在 蓝牙协议栈基本框架层面的内容,对于更具体的理解我们还不知道,所以针对示例来说,我们也无从修改测试。
正所谓磨刀不误砍柴工,我们有必要先深入的学习一下 GATT 以及 GATT 相关的一些知识。
本文我们就来了解一下 蓝牙 GATT 到底是什么?同时了解下我们使用的 ESP32-C3 GATT示例的工程的代码结构。
ESP32-C3学习 蓝牙 篇系列博文连接:
❤️
测试使用的开发板:
自己画一块ESP32-C3 的开发板(第一次使用立创EDA)(PCB到手)
❤️
测试使用的开发环境:
ESP32-C3 VScode开发环境搭建(基于乐鑫官方ESP-IDF——Windows和Ubuntu双环境)
❤️
蓝牙篇系列相关博文:
ESP32-C3 学习测试 蓝牙 篇(一、认识 ESP-IDF 的蓝牙框架、简单的了解蓝牙协议栈)
ESP32-C3 学习测试 蓝牙 篇(二、蓝牙调试APP、开发板手机连接初体验)
一、概念导图
☆ 即便看完了很多资料,博主自己还是感觉蓝牙协议的专有名词定义有点复杂(相对其他很多物联网无线协议来说),如果不是专门从事蓝牙行业的人,即便官方有资料,对于这些专有名词专有定义也难以全部理解到位。
☆ 但是我们系列博文最终是以应用为目的,使用蓝牙最终还是使用蓝牙做一些数据的传输交互应用。所以对于专有名词暂时不用研究那么深,知道一些基本概念的的作用和意义即可。
对于基本的概念知识,查阅了很多相关的资料后多少有了一个初步的认识,对于蓝牙 GATT 来说,以应用为主所需要的了解的基本概念,主要就是 GATT,GAP,ATT 这几个协议,在系列博文第一篇《ESP32-C3 学习测试 蓝牙 篇(一、认识 ESP-IDF 的蓝牙框架、简单的了解蓝牙协议栈)》关于蓝牙协议的说明对于这几个协议的简单说明,如下图:
对于我们的应用来说,蓝牙无非是用来进行数据交互,我们直接从应用说起,我们使用手机和开发板进行蓝牙通讯,对应的 手机就是 Client 设备,开发板就是 Server 设备。
对于我的学习来说,就是从 BLE通信的这两种设备入手的 :Client 和 Server。
GATT 的结构
对于 Client 和 Server 的通讯,先来看一张图:
从上面的示意图可以看出,对于 GATT server 有很多分支,可想而知对于他的协议规定会有很多专有名词,我们的应用程序也大多是对 GATT server 这些参数进行修改配置,我总结了几张概念导图。
图中用的是 GATT Server 后面的分支应该是 Service!!
Service 的结构
图中用的是 Server(服务器),应该用 Service ,当初做图的时候估计还有点蒙:上图中虽然以 Service 作为开头,其实 Service 可组成一个叫 profile 的概念(下面概念说明会讲到 )。
Profile 的结构
蓝牙官方文档中对于 Profile 说明图:
二、概念说明
虽然上面上了一张概念导图,但是对于里面的一些基本概念我们有必要一个一个单独说明一下。
这里推荐几篇文章,部分内容也有参考:
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)。
更多详细的说明可参考:
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 的信息的,为了加深对上面的概念的理解,我们使用手机连接后的图片来说明一些概念:
在上图中有一点,结合上面第一小节《一、概念导图》 中的 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的理解,同时开始进行初步的修改测试 。