安卓蓝牙GATT协议介绍

news2024/11/16 13:26:11

前言

现在低功耗蓝牙(BLE)连接都是建立在 GATT (Generic Attribute Profile) 协议之上。GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很短的数据段被称为属性(Attribute)。

  1. GAP

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

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

在 GAP 中外围设备通过两种方式向外广播数据: Advertising Data Payload(广播数据)和 Scan Response Data Payload(扫描回复),每种数据最长可以包含 31 byte。这里广播数据是必需的,因为外设必需不停的向外广播,让中心设备知道它的存在。扫描回复是可选的,中心设备可以向外设请求扫描回复,这里包含一些设备额外的信息,例如设备的名字。

  1. 广播流程

GAP 的广播工作流程如下图所示。
在这里插入图片描述
从图中我们可以清晰看出广播数据和扫描回复数据是怎么工作的。外围设备会设定一个广播间隔,每个广播间隔中,它会重新发送自己的广播数据。广播间隔越长,越省电,同时也不太容易扫描到。

  1. 广播的网络拓扑结构

大部分情况下,外设通过广播自己来让中心设备发现自己,并建立 GATT 连接,从而进行更多的数据交换。也有些情况是不需要连接的,只要外设广播自己的数据即可。用这种方式主要目的是让外围设备,把自己的信息发送给多个中心设备。因为基于 GATT 连接的方式的,只能是一个外设连接一个中心设备。使用广播这种方式最典型的应用就是苹果的 iBeacon。广播工作模式下的网络拓扑图如下:
在这里插入图片描述

介绍

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 连接。

GATT可以被Application或其他Profile使用,其协议栈如下图
在这里插入图片描述
GATT可以配置为如下两种角色(Role)

 - Client : 命令、请求发起方 
 - Server : 命令、请求接收方

角色配置实例如下:
在这里插入图片描述
Computer是一个温度服务客户端, Sensor是温度服务服务器
Computer向Sensor发起Procedure来读Sensor的值

GATT对蓝牙协议下层的需求如下

 - Physical Link 	: 使用GAP Channel Establishment建立的ATT Bearer 
 - GATT Role		: 不依赖于Coontroller角色(Master/Slave) 
 - Security		: 对于LE,Security Features(Authorization、Authentication、Encryption)是可选的 
                  对于BR/EDR, Encryption是强制的 
 - TX order		: GATT中的多字节字段,采用Little Endian

相关概念

  1. GATT Profile Hierarchy
    GATT指定了数据交互的结构(Structure);这个结构体定义了一些基本元素,如Service、Characteristic
    这些元素存在于Attribute中
    在这里插入图片描述
    Profile并不是实际存在于 BLE 外设上的,它只是一个被 Bluetooth SIG 或者外设设计者预先定义的 Service 的集合,由一个或多个服务(Service)组成。服务是由Characteristics组成,或是其他服务的引用(Include),Characteristic包含一个值(Value),可能还包含该Value的相关信息。
    Service
    Service是[数据]和与之关联的[完成某个特定功能的行为]or[特性]的集合,在GATT中,一个服务由服务定义(Service Defintion)来实现,一个服务定义可能包含引用服务(referenced Service)、必要Characteristic和可选Characteristic。
    Server有两类
- Primary Service   : 拥有基本功能的服务,可被其他服务包含,可以通过Primary Service Discovery过程来发现 
- Secondary Service : 仅用来被Primary/Other Secondary Service、高层协议引用的服务

Service definition如下:
Service必须包括一个服务声明(service declaration),可能包含包含零个或者多个Include和Characteristic。服务定义中的Include Definitions和Characteristic Definitions被认为是服务的一部分。服务定义中的顺序为

Service Declaration ~ Include Definitions(>=0) ~ Characteristic Definitions(>=0)

服务声明是一个Attribute,其中Attribute type是一个UUID,分别是0x2800(Primary Service)或者0x2801(Secondary Service)。从服务声明0x2800开始到下一个0x2800属性(即新的服务声明)之间的内容都属于同一个Service,也就是说它没有一个Length来直接说明它多长或多少个数据项。在上图Profile中,一个Profile至少包含一个Service,Gatt discover过程会以0x2800为界限,将两个0x2800中的所有属性划归为前后一个以0x2800开始的Service。服务声明的Attribute Value是第一个服务的UUID。
每个 Service 有一个 UUID 唯一标识。 UUID 有 16 bit 的,或者 128 bit 的。16 bit 的 UUID 是官方通过认证的(参考《16-bit UUID Numbers Document.pdf》),需要花钱购买,也可以自己随便设置。

Included Service(referenced Service)

一个Included Service是一种引用已存在服务的方法,具体办法为在服务定义的开始加上Included Service的引用,这样整个Included Service定义成为新服务定义的一部分。
在这里插入图片描述
它是一个Attribute,Attribute Type=0x2802。Attribute Type存储了Attribute Handle或服务的UUID,注意Handle并不真实存在和存储,它只是在远程蓝牙设备里面的程序构建GATTService时创建的、被程序识别和使用。
如果一个Service的Include Definition(A)是引用其他Server的Include Definition(B),那么Include Definition(B)不应该引用Include Definition(A),否则就是循环引用(Circular Reference),当一个Client检测到循环引用或detects nested include declarations to a greater level than it expects,Client应当终止本次通信(ATT Bearer)

Characteristic
由Characteristic Definition定义,包含一个Characteristic声明、Characteristic属性、值、值的描述(Optional)

- Characteristic Declaration                       : First 
- Characteristic Value declaration                 : Second 
- Characteristic Descriptor Declarations(Optional) : Last(含多个时顺序不关紧要)

Characteristic:在 GATT 事务中的最低界别的是 Characteristic,它是最小的逻辑数据单元,当然它可能包含几个关联的数据,例如加速度计的 X/Y/Z 三轴值。
Characteristic声明,Attribute Type=0x2803,与 Service 类似,从特性声明0x2803开始到下一个0x2803之间的内容都同属于一个特性。
在这里插入图片描述
Characteristic声明Attribute Value是特性Value的“特性Properties+属性Handle+特性UUID”(注意Properties和Handle是程序添加的,不是真实存在,实际存储中Characteristic声明Attribute Value只有特性UUID)。
特性Properties的用法,比如可用于广播、可读、可写等。
属性Handle是程序用来标识一个属性,它指向定特性里面的第一个属性值得Handle。因GATT是基于ATT的,所以Profile实际就是属性列表,成为为每个属性用一个Handle标识,制作成一个表,Handle值是按顺序生成的:
在这里插入图片描述
上面表格中,Handle为0x0012和0x0013才是一个正常的Characteristic的Value。它也是一个Attribute,可以免费使用 Bluetooth SIG 官方定义的标准 Characteristic,Attribute Type是个UUID,由官方定义的(参考《16-bit UUID Numbers Document.pdf》),可以确保 BLE 的软件和硬件能相互理解。当然,你可以自定义 Characteristic,这样的话,就只有你自己的软件和外设能够相互理解。
以上面表格为例:表中是一个Service,Service UUID=0x180F,查《16-bit UUID Numbers Document.pdf》知道这是电池服务。电池服务特性声明是0x2803,Value指出首个特性的UUID是0x2A19。查《16-bit UUID Numbers Document.pdf》知道特性0x2A19是电量计数,Value域中包含了电池的当前电量。
特性描述配置(这里只是简单介绍)的属性类型0x2902(查《16-bit UUID Numbers Document.pdf》),这样客户端在discover时能知道这个特性描述配置是从属于当前特性的,因为两个特性之间的所有属性同属于前一个特性。特性配置描述支持客户端的订阅,并存储客户端的订阅Handle。当特性值发生变化时,通知客户端的订阅者。针对电池服务来说,当电量发生改变时,通知客户端。
实际上,和 BLE 外设打交道,主要是通过 Characteristic。你可以从 Characteristic 读取数据,也可以往 Characteristic 写数据。这样就实现了双向的通信。所以你可以自己实现一个类似串口(UART)的 Sevice,这个 Service 中包含两个 Characteristic,一个被配置只读的通道(RX),另一个配置为只写的通道(TX)。

  1. Configured Broadcast
    对于LE物理链路,在Server广播模式过程中,Client通过Configured Broadcast告知Server应该在advertising data加入Characteristic Value,方法是Client设置指定bit位;广播频率则是Service、Characteristic行为定义的一部分

  2. Summary of GATT Profile Attribute Types
    在这里插入图片描述

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

  4. GATT 通信事务
    ATT 通信的双方是 C/S 关系。外设作为 GATT 服务端(Server),它维持了 ATT 的查找表以及 service 和 characteristic 的定义。中心设备是 GATT 客户端(Client),它向 Server 发起请求。需要注意的是,所有的通信事件,都是由客户端(也叫主设备,Master)发起,并且接收服务端(也叫从设备,Slave)的响应。
    一旦连接建立,外设将会给中心设备建议一个连接间隔(Connection Interval),这样,中心设备就会在每个连接间隔尝试去重新连接,检查是否有新的数据。但是,这个连接间隔只是一个建议,你的中心设备可能并不会严格按照这个间隔来执行,例如你的中心设备正在忙于连接其他的外设,或者中心设备资源太忙。
    下图展示一个外设(GATT 服务端)和中心设备(GATT 客户端)之间的数据交换流程,可以看到的是,每次都是主设备发起请求:
    在这里插入图片描述

功能要求

  1. Overview
    GATT中定义了11项Feature
.  Server Configuration
.  Primary Service Discovery
.  Relationship Discovery
.  Characteristic Discovery
.  Characteristic Descriptor Discovery
.  Reading a Characteristic Value
.  Writing a Characteristic Value
.  Notification of a Characteristic Value
.  Indication of a Characteristic Value
. Reading a Characteristic Descriptor
. Writing a Characteristic Descriptor

每个Feature都有对应的过程和子过程,这些过程描述了如何使用ATT来实现各自的功能。

  1. Feature Support and Procedure Mapping
    本节内容省略,请参阅协议。

  2. Server Configuration
    该过程可被Client用来配置Attribute Protocol的MTU大小
    Exchange MTU
    Client使用该子过程来设置适配双方均支持的最大ATT_MTU,在BR/EDR物理链路中不应该使用该过程,而应该使用L2CAP Channel Configuration Procedures。该过程对应于ATT的MTU Exchange Request/Response,见<Bluetooth ATT介绍 - 4.2 MTU Exchange>

  3. Primary Service Discovery
    Client使用该过程来发现服务端的Primary Services。一旦发现服务存在,可通过其他过程来访问Primary Services的附加信息(关联主服务和次服务),可使用的其他过程包括Characteristic Discovery和Relationship Discovery。
    该过程包括两个子过程:

- Discover All Primary Services
- Discover Primary Services by Service UUID

在BR/EDR物理链路上则使用SDP service discovery来发现服务

  • Discover All Primary Services

Client使用该子过程来发现服务端的所有Primary Services。该子过程使用ATT的Read By Group Type Request,同时设置如下参数

- Starting Handle : 0x0001
- Ending Handle   : 0xFFFF
- Attribute Type  : UUID for <Primary Service>

可能的回应有

- Read By Group Type Response
- Error Response

Read By Group Type Response返回三元组列表,三元组包括

- Attribute Handle : 服务声明的Handle
- End Group Handle : 服务定义中最后一个Attribute的Handle
- Attribute Value  : 服务端支持的服务的Service UUID

当收到Error Response时;则表明该过程已经完成。
当Client找到自己所需要的服务时,可以终止该过程。
Note: 3.1中已指出Service Declaration是可读,并且不需要认证或授权;因此权限相关的错误不会发生

下图是一个实例图
在这里插入图片描述

  • Discover Primary Service by UUID

当Client知道了Service UUID时,可以使用该子过程来发现对应的主服务
该子过程使用ATT的Find By Type Value Request,同时设置参数如下

- Starting Handle : 0x0001
- Ending Handle   : 0xFFFF
- Attribute Value : 16-bit Bluetooth UUID or 128-bit UUID
- Attribute Type  : UUID for <Primary Service>

可能的回应有

- Find By Type Value Response
- Error Response

Find By Type Value Response返回Attribute Handle ranges列表,Attribute Handle range即服务定义的Starting Handle和Ending Handle,如果Attribute Handle range中的End Found Handle不是0xFFFF;那么Client将会再请求一次Req,同时将Starting Handle设置为收到的最后一个Attribute Handle+1
终止规则和权限问题同Discover All Primary Services
下图是一个实例图
在这里插入图片描述

  1. Relationship Discovery
    Client使用该过程来发现和其他服务的服务关系
  • Find Include Services

Client使用该子过程来发现一个服务定义包含的服务申明
该子过程使用ATT的Read By Type Request,同时设置参数如下

- Starting Handle : 所要查找服务的Starting Handle
- Ending Handle   : 所要查找服务的Ending Handle
- Attribute Type  : UUID for <Include>

可能的回应有

- Find By Type Response
- Error Response

Find By Type Response返回[Attribute Handle, Attribute Value]集合对,Attribute Value由所包含服务申明的Attribute Handle和End Group Handle组成,当UUID为16-bit Bluetooth UUID时,那么它也将包含在Rsp中
该Req应该被再次请求,同时设置Starting Handle为为收到的最后一个Attribute Handle+1
当Rsp中包含的服务申明中Attribute Handle等于Req的Ending Handle时,该子过程被认为完成(当然Attribute Not Found-Error Rsp也是)
当Include Service使用128-bit UUID时,使用Read Request来获取Include Service UUID,其中Attribute Handle参数设置为Include Service的Attribute Handle
权限规则同上面
下图是一个实例图
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/671047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GBASE金融信创优秀解决方案鉴赏 · 核心业务系统数据库解决方案

为此&#xff0c;实验室特别开设金融信创优秀解决方案专栏&#xff0c;集中展示优秀成果。现在&#xff0c;让我们一起来领略下GBASE的优秀解决方案吧~可点击阅读原文 →《金融信创优秀解决方案--核心业务系统数据库解决方案》。 核心业务系统数据库解决方案 方案简介 随着技…

Android Qcom USB Driver学习(十三)

该系列文章总目录链接与各部分简介&#xff1a; Android Qcom USB Driver学习(零) Android Qcom USB Driver学习(八) Android Qcom USB Driver学习(九) UCSI USB Type-C Connector System Software Interface Specification DPM Device Policy Manager deals with the USB P…

智安网络|驾驭数字化转型时代:加速业务转型的战略

随着科技的飞速发展和数字化时代的到来&#xff0c;企业面临着前所未有的机遇和挑战。数字化正在改变着商业的方方面面&#xff0c;而那些能够及时适应和把握这些变化的企业将脱颖而出。因此&#xff0c;加速企业转型成为了当务之急。 一、为什么需要加速企业转型 1.全球市场竞…

D. Pairs of Segments(最大不相交区间数量)

Problem - D - Codeforces 给定一个由n个线段组成的数组[[l1,r1],[l2,r2],…,[ln,rn]]&#xff0c;其中每个线段用左右端点表示。如果存在至少一个x满足l1≤x≤r1且l2≤x≤r2&#xff0c;则称线段[l1,r1]和[l2,r2]相交。 如果k为偶数&#xff0c;并且可以将该数组的元素分成k/…

VTK裁剪【3】-vtkClipPolyDatavtkPolyPlane问题

前言&#xff1a;本博文主要记录vtkClipPolyData中采用vtkPolyPlane作为裁剪工具时的出现的问题&#xff0c;供各位小伙伴进行参考&#xff0c;避免踩坑&#xff01; 目录 vtkPolyPlane介绍及作用 vtkClipPolyData原理 实现流程&#xff1a; 问题所在&#xff1a; 需求&…

css绘制网格背景

文章目录 前言效果图说明 前言 本篇文章主要简单扼要的去实现css网格背景&#xff0c;并进一步探求其应用原理 效果图 css代码 body::before, body::after {position: fixed;top: 0;left: 0;right: 0;bottom: 0;content: ;background-repeat: repeat;pointer-events: none;o…

企业特权密码管理

随着企业中特权帐户的激增&#xff0c;必须保护的密码数量也大幅增长。跟踪所有这些密码是一项艰巨的任务&#xff0c;为避免敏感密码管理不善&#xff0c;管理员需要在集中式存储库下清点属于所有部门的密码&#xff0c;并管理对它们的直接控制。 部署PMP的好处 PMP是一个安…

Baumer工业相机堡盟工业相机如何使用新版本NEOAPI SDK控制相机数据流的开启和关闭(C#)

Baumer工业相机堡盟工业相机如何使用新版本NEOAPI SDK控制相机数据流的开启和关闭&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK的技术背景Baumer工业相机使用NEOAPISDK控制相机数据流的方式1.引用合适的类文件2.使用NEOAPISDK控制相机数据流的方式2.使用…

市场模式下光伏用户群的电能共享与需求响应模型(matlab代码)

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现文章《市场模式下光伏用户群的电能共享与需求响应模型》&#xff0c;为了使光伏用户群内各经济主体能实现有序的电能交易&#xff0c;提出了一种基于光伏电能供需比&#xff08;SDR&#xff09;的内…

JavaScript实现伪随机正态分布

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言什么是正态分布&am…

Jenkins+Allure+Pytest的持续集成

一、配置 allure 环境变量 1、下载 allure是一个命令行工具&#xff0c;可以去 github 下载最新版&#xff1a;https://github.com/allure-framework/allure2/releases 如果你想学习Pytest自动化测试&#xff0c;我这边给你推荐一套视频&#xff0c;这个视频可以说是B站播放全…

图扑智慧地下采矿,“像素游戏”智能呈现

在这个像素世界里&#xff0c;我们需要一个智能地下采矿可视化综合管理平台&#xff0c;来帮助我们管理和监控地下采矿全流程。 图扑软件依托自主研发的 HT for Web 产品&#xff0c;结合三维定制化渲染、动态模拟、物理碰撞、5G、物联网、云计算及大数据等先进技术&#xff0c…

vue+leaflet笔记之热力图

vueleaflet笔记之热力图 文章目录 vueleaflet笔记之热力图开发环境代码简介插件简介与安装使用简介 详细源码(Vue3) 本文介绍了Web端使用 Leaflet开发库展示热力图方法 (底图来源:天地图)&#xff0c;结合leaflet.heat插件可以很容易的做出热力图&#xff0c;通过调整其配置参…

旧系统重构遇到的种种问题

首先我将原来springboot版本升级到2.7.9&#xff0c;spring的docker分层和启动受到了影响&#xff0c;这个在docker镜像大小问题已经讲过&#xff0c;不再赘述&#xff0c;因为维护的人变成为一个人&#xff0c;因此我需要将各代码的版本进行统一&#xff0c;方便维护。 5 sun.…

数据治理(数据模型,数据规范,数据安全,数据成本,元数据,数据质量等)

数据治理是什么?为什么要做数据治理?关于数据治理我们需要做什么? 数据治理无论是在数仓建设过程中还是数仓建设完成之后都是及其重要的,是数据部门基础建设的必经之路,是降本提效,形成企业数据资产的关键一环 一 数据质量管理 1.1 数据质量基本概念 ●数据质量管理(Dat…

【Java-SpringBoot+Vue+MySql】Day3.1-SpringBoot Web开发

目录 前期回顾——SpringBoot与Maven 一、web入门 1、知识点密集区 &#xff08;1&#xff09;spring web依赖 &#xff08;2&#xff09;控制器 ​ (3)路由映射 &#xff08;4&#xff09;URL映射 &#xff08;5&#xff09;Method匹配​编辑 &#xff08;6&#xff09…

一种基于FPGA的雷达综合显示模块技术方案

一、项目整 这是我们做过的一个项目&#xff0c;若有需求&#xff0c;请联系我。开放PCB和软件技术。 以FPGA为核心&#xff0c;开发设计具有多路图像/视频采集、处理、传输、显示等功能的嵌入式视频模块。可对多路SerDes接口输入的高速串行视频流数据进行解析&#xff0c;将…

NSSCTF MOBILE [SWPU 2019]easyapp 详细题解

文章目录 一. 前言二. 安装安卓SDK三. 安装安卓模拟器(推荐夜神模拟器)四. 安装frida和objection五. 解题过程六. 总结 一. 前言 题目地址:[SWPU 2019]easyapp大佬题解[SWPU 2019]easyapp pwjcw的WriteUp 大佬的题解很简单,直接hook就可以看到返回值,但是我看了半天没看明白是…

通过源码分析为什么不推荐使用Executors线程池

线程池是 Java 并发编程中不可缺少的一部分。JDK 提供了一个方便快捷的线程池工具类 Executors&#xff0c;提供了多种创建线程池的静态方法&#xff0c;但是在实际使用中&#xff0c;我们不建议直接使用 Executors 提供的线程池工具类。本篇博客将通过分析 Executors 源码&…

【高性能计算】基于K均值的划分聚类实验

【高性能计算】基于K均值的划分聚类实验 实验目的实验内容实验步骤1、k均值聚类算法1.1 k均值聚类算法的基本思想1.2 k均值聚类算法的聚类过程1.3 k均值聚类算法的算法叙述 2、使用Python语言编写k均值聚类算法的源程序代码并分析其分类原理2.1 读取文件数据并进行可视化2.2 利…