ESP32-WROVER-E蓝牙学习笔记(2)BLE 的server client att

1、客户端 Client

请求数据服务

客户端可以主动搜索并连接附近的服务端

客户端类似蹭网的

2、服务端Server

提供数据服务

服务端不需要进行主动设置,只要开启广播就可以让附近的客户端搜索到,并提供连接

服务端类似被蹭网的wifi

如果想要让ESP处于别人随时可以搜索连接的情况要配置为服务端;如果想让ESP通过扫描连接周围可连接的蓝牙设备,需要把它设置成客户端,正好和WiFi模式的设定相反

Server通过characteristic对数据进行封装,多个characteristic组成一个Service——Server是一个基本的BLE应用,如果某个Service是一个蓝牙联盟定义的标准服务,也可以称其为profile

要具体了解这些内容需要先了解属性协议层ATT

3、ATT简述

https://img2018.cnblogs.com/blog/653161/201912/653161-20191204145156859-489087209.png

属性协议层ATT(Attribute Protocol)是GATT和GAP的基础,它定义了BLE协议栈上层的数据结构和组织方式;在层内,它定义了属性(Attribute)的内容,规定了访问属性的方法和权限

属性是一个数据结构,它包括了数据类型和数据值,可以像C语言的结构体那样构造

属性包括三种类型:服务项、特征值和描述符,三者呈包含关系:服务项包含一个或多个特征值,特征值包含一个或多个描述符,多个服务项组织在一起,构成属性规范(Attribute Profile)

3.1、属性的种类和分组

属性大致可以分为三种类型:服务项Profile、特征值Characteristic和描述符Descriptor

最顶级为Profile, 下面是多个服务项(Service), 服务项下面是多个特征值(Characteristic), 特征值下面是多个描述符(Descriptor)

每个设备都包含以下必要的特征值和服务项:

PROFILE

Generic Access Service(Primary Service)
    Device Name(Characteristic)
    Appearance(Characteristic)
Generic Attribute Service(Primary Service)
    Service Changed(Characteristic)
        CCCD(Descriptor)
 

3.1.1、服务项Service

服务项这种类型本身并不包含数据,仅仅相当于是一个容器,用来容纳特征值

3.1.2、特征值characteristic

特征值用于保存用户数据,但它也有自己的UUID——可以把它看作一个变量,变量里存着数据(用户数据),也有自己的地址信息(UUID)

使用特征值时,也要遵循“先声明再赋值”的步骤——先声明特征值自身,再声明它的项

一个characteristic包含三种条目:

    1、characteristic声明:每个characteristic的分界符,解析时一旦遇到一个声明,就可以认为接下来又是一个新的characteristic;声明还包含了接下来characteristic值的读写属性等
     2、characteristic值:数据的值
     3、characteristic描述符:数据的额外信息
一般BLE的属性体系在系统中以GattDB表示,即属性数据库,gattDB是BLE协议栈在内存中开辟的一段专有区域,会在特定的时候写入Flash进行保存,并在启动时读取出来回写到内存中去,但并非所有的BLE数据通信是操作gattDB

characteristic用Attribute数据结构来实现
 

3.2、属性Attribute的数据结构

Attribute由四部分组成:

    1、属性句柄Attribute handle:可以视为指向属性实体的指针,对端设备通过属性句柄来访问某个属性,大小2字节,起始于0x0001,系统初始化时,各属性的句柄逐步+1,但最大不超过0xFFFF

    2、属性类型Attribute type:用以区分当前属性是服务项或是特征值等,用通用唯一识别码(UUID)标识的16字节十六进制字符串(形如f6257d37-34e5-41dd-8f40-e308210498b4,从网上抄来的示例,如有雷同那就是雷同)表示。一个合法的UUID,一定是随机的、全球唯一的,不应该出现两个相同的UUID。属性类型分类如下:

    首要服务项Primary Service
    次要服务项Secondary Service
    包含服务项Include
    特征值Characteristic

他们与UUID的映射关系如下:

    0x1800 – 0x26FF :服务项类型
    0x2700 – 0x27FF :单位
    0x2800 – 0x28FF :属性类型
    0x2900 – 0x29FF :描述符类型
    0x2A00 – 0x7FFF :特征值类型
为了减少传输的数据量,BLE协议做了一个转换约定,给定一个固定的16字节模板,只设置2个字节为变化量,其他为常量,2字节的UUID在系统内部会被替换,进而转换成标准的16字节UUID;反之,如果一个特征值的UUID是16字节的,在系统内部它的属性类型也可能写成第3、4字节组成的双字节

示例如下:

UUID模板为

0000XXXX-0000-1000-8000-00805F9B34FB


其中从左数第3、4个字节“XXXX”就是变化位,其他为固定位。如:UUID=0x2A00在系统内部会转换成00002A00-0000-1000-8000-00805F9B34FB。

3、属性值Attribute value:真正的数据值,大小为0-512字节。如果该属性是服务项类型或者是特征值声明类型,那么它的属性值就是UUID等信息;如果是普通的特征值,则属性值是用户的数据,属性值需要预留空间以保存用户数据,可以将属性值的预留空间看做I2C的数据空间,操作特征值里的用户数据,就是对那块内存空间进行读写,所以启用蓝牙后会占用额外的内存

4、属性权限Attribute permissions:Attribute的权限属性,主要有四种:

    访问权限(Access Permission):只读或只写或读写
    加密权限(Encryption Permission):加密或不加密
    认证权限(Authentication Permission):需要认证或无需认证。指相互确认对方身份,BLE中所说的“认证”过程就是设备配对
    授权权限(Authorization Permission):需要授权或无需授权。指对授信设备开放权利
    授权的管控等级要高于认证,认证的设备未必被授权,授权的设备一定是认证的——认证是授权的充分不必要条件。认证是设备配对,两边都符合协议规定就行,但是授权取决于Server设备对Client设备的主动许可。

一个没有经过认证的设备,被称为未知设备(Unknown Device);经过了认证,该设备会在绑定信息中被标记为Untrusted,被称为不可信设备(Untrusted Device);经过了认证,并且在绑定信息中被标记为Trusted的设备被称为可信设备(Trusted Device)

具体的权限示例如下所示:

Open(随意读写)
No Access(禁止读写)
Authentication(需要配对才能读写,分成很多子类型用于适配配对的类型)
Authorization(允许应用在回调函数中读写)
Signed(签名后才能随意读写)
 

3.3、属性协议ATT PDU

拥有一组属性的设备称为服务端(Server);读写该属性值的设备称为客户端(Client)

Client和Server之间通过ATT PDU通信

属性协议ATT PDU共有6种,如下表所示:

ATT PDU种类发送方向触发响应说明
CommandClient ->Server客户端发送Command,服务器无需任何返回
RequestClient ->ServerResponse客户端发送Request,服务器需要返回一个Response,表明服务器收到
ResponseServer -> Client  
NotificationServer -> Client服务器发送Notification,户端无需任何返回
IndicationServer -> ClientConfirmation服务器发送Indication,客户端需要返回一个Confirmation,表明客户端收到
ConfirmationClient ->Server  

BLE下,所有命令都是“必达”的,每个命令发送完毕后,发送者会等待ACK信息(类似I2C),如果收到了ACK包,发起方认为命令完成;否则发起方会一直重传该命令直到超时导致BLE连接断开(类似CAN的出错重发机制),可以说只要数据包放到了协议栈射频FIFO中,蓝牙协议栈就能保证该数据包“必达”对方,但是没有回复相对有回复就是“不太可靠”,这时候就需要特殊的“有回复属性”
 

Request后缀
特别地,如果一个命令需要response,那么可以在相应命令后面加上request后缀,这个response包在应用层有回调事件,可以用于触发特殊的功能,这是默认的协议ACK恢复不具有的,采用request/response方式,应用层可以按顺序地发送一些数据包;如果一个命令只需要ACK而不需要response,那么它的后面就不会带request

然而Request/response会大大降低通信的吞吐率,因为request/response必须在不同的连接间隔中出现,这就导致两个连接间隔最多只能发一个数据包,而不带request后缀的ATT命令就没有这个问题——一般情况下,在同一个连接间隔中可以同时发多个数据包,这样将大大提高数据的吞吐率

常用的带request命令:所有read命令,writerequest,indication等

常用的不带request命令:write command,notification等
————————————————
版权声明:本文为CSDN博主「内 鬼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40500005/article/details/113840437

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值