蓝牙规范系列--属性协议(基础篇)
一、概念
什么是属性协议(ATTRIBUTE PROTOCOL)?属性协议的作用是什么?谁会使用属性协议?
- 用于发现、读取、写入对端设备上的属性
- 定义设备的角色和互操作性
- 定义访问属性的方法、过程以及协议数据包格式
- 由上层来使用,例如GATT层
- 在属性协议下每个BLE设备都有一个属性表,表中的每个属性都有一个唯一的属性句柄和一个类型(通过UUID标识),设备可以通过ATT协议来查询和访问这些属性
二、角色定义
属性协议定义了两种基本角色:
- 客户端
- 访问服务端的属性或者接收服务端属性的通知和指示
- 可以连接多个不同的服务端
- 服务端
- 提供一组属性给客户端访问
- 接收客户端连接请求
- 可以支持多个客户端连接
存在服务端的设备叫做外围设备,例如蓝牙手环;访问服务端的设备叫做中心设备,例如手机; 一个设备可以同时存在两种角色并可同时运行,一边作为客户端去访问其他服务端的资源(属性),一边作为服务端为其他客户端提供服务,这类设备叫做混合设备。
三、属性概念
什么是属性?
- 表示和管理设备间数据交换的基本单元
- 由三部分构成,分别为
- 属性句柄(Handle)
- 16bit无符号数,取值范围0x1 - 0xFFFF,不必连续,升序排序
- 在服务端全局唯一,类似于数据库中的ID
- 同种类型的属性通过句柄区分,类似于类的不同实例
- 属性类型(Type)
- 通过UUID定义,可以用16bit、32bit、128bit标识,通常16bit的UUID通常由蓝牙规范定义,128bit的一般用于自定义
- 服务端可以存在相同类型的属性的多个实例,但属性句柄肯定不同
- 属性值(Value)
- 无长度限制,属性值较长时可以通过多个PDU传送
- 变长或者固定长度,已经明确定义的属性类型的值的长度一般固定
- 上层定义属性值的具体数据长度、内容以及格式
- 属性协议自身不关注属性值的具体内容
- 属性句柄(Handle)
- 属性权限
- 由上层定义,属性协议本身无法访问这些权限
- 包含四个方面的权限
- 访问权限
- 可读
- 可写
- 可读写
- 认证权限
- 加密权限
- 授权权限
- 访问权限
- 特殊属性
- 长属性值
- 长度超过ATT_MTU - 1,最大512字节
- 属性分组
- 上层定义
- 在一系列属性的起始位置放置一个特定属性来实现,例如GATT中的服务定义声明就是一个带有组概念的属性
- 控制点属性
- 不能读,只能被写、通知或者指示
- 长属性值
四、协议方法
4.1 协议框图
属性协议中定义的方法:
- 命令
- 客户端请求服务进行写操作,没有流控
- 请求
- 客户端请求服务端执行指定的操作,服务端必须给出响应(包括错误结果)或者超时后关闭连接,超时时间为30秒
- 一次请求和一次响应构成一次传输事务
- 响应
- 服务端对客户端的请求做出响应,在不能处理或者请求格式非法时返回错误结果
- 指示
- 服务端下发指令给客户端,客户端必须给出确认
- 一次指示和一次确认构成一次传输事务
- 确认
- 对服务端的指示进行确认
- 通知
- 服务端下发指令给客户端,不需要客户端确认
4.2 流控管理
- 客户端发起一次请求必须等待服务端的结果后才能发起下一次请求
- 服务端发起一次指示必须等待客户端的确认后才能发起下一次指示
- 服务端和客户端的流控是各自独立的
- 服务端如果对客户端的请求无法处理需要返回错误响应说明错误原因