9、通过蓝牙GATT服务数据传输
9.1 使用CS和CP数据交换协议
通过蓝牙GATT“IN”和“OUT”控制点特征的数据编码以及序列机制。
9.1.1 FiRa连接器数据包
所有GATT特征被定义为“IN”和“OUT”控制点传输数据均使用相同的数据结构。所有蓝牙应用层数据(top of GATT)由FiRa连接器数据包组成,所有数据包均为可变大小,最大可达到GATT服务根据FiRa连接器能力提供的优化数据包大小(optimized_size)。
FiRa连接器数据包提供拆包与重组机制,这允许传输超过FiRa连接器消息大小的数据包传输。
Chaining Bit用于标识拆包片段,为1,表明是最后一个包,用于重组中标识数据包。
数据包头以特定安全组件ID(SECID)进行区分,其中管理SECID为0b000_0001,是隐藏、不公开的。关于安全组件ID相关,已经在上一篇文章FiRa标准——蓝牙OOB规范(三)中进行了介绍,是FiRa连接器能力中的重要组成部分。
9.1.2 FiRa连接器消息结构
FiRa连接器消息是用于FiRa连接器数据包传输FiRa应用程序数据的更高一层数据结构(数据可能超过optimized_size)。提供了一种在蓝牙GATT层上传输无限制数据串的机制,通过有限的缓冲区大小来实现(连接到GATT服务器与客户端之间商定的ATT_MTU大小)。
9.1.3 FiRa连接器数据分段
FiRa OOB连接器需要负责进行数据分段与重组工作。一个命令/响应数据字符串封装在一个FiRa连接器消息中,并且可以通过一个或多个FiRa连接数据包发送。FiRa连接器数据包的数量及其大小受限于蓝牙GATT层实现时确定的ATT_MTU大小。FiRa连接器数据包包含连续的FiRa连接器消息片段,编码规则如下:
- 在使用蓝牙GATT方法(如写入或处理值通知)发送FiRa连接器数据包,所有的拆分数据均包含Data Packet Header,即Data Packet Header + Body的结构,将FiRa Connector Message拆分开来。
- Data Packet Header中CB字段均设置为0,除最后一个片段置为1。即对于一个完整单独的包,CB置为1,为0表示该包不完整,需要进行拼接。
- 只有第一个片段包含FiRa连接器消息头。
从图中也可以看出,一个消息帧通常会大于每个数据包,数据包受限于Optimized Data Packet size
,而消息可以拆分为多个包,对于最后一包数据,CB需要设置为1。
9.1.4 并行分段会话和FiRa连接器数据包交错
上一节描述的分段/重组机制允许管理并行会话,安全组件一端的每个SECID目标一个会话。但是,此功能为可选的,且依赖于具体实现。每个GATT server和client实现CS,应通过FiRa连接器能力特性中的“最大并发分段会话数量”字段来指示是否支持此功能。在CP端将基于此,确保正在进行的分段会话刷领不超过该并发数量。
以下示例说明了FiRa连接器数据包序列携带了两个交错的分段会话。(Data Packet #1与#3为SECID=X,#2为SECID=Y数据包)
从图中可以看到,要能够允许交错分段数据的处理,非常重要的一点就是SECID应该是不同的,这也是在前面的约定中限制了每个SECID只能有一个会话。
9.1.5 管理协议和管理SECID
管理SECID用于发出与FiRa蓝牙OOB连接器定义的数据传输和协议相关的错误和事件。
管理SECID(0b000_0001)应始终暴露在每个CS实现上,同时标记为静态。
管理SECID用于传输FiRa连接器消息。安全组件协议类型应设置为“FiRa OOB管理协议”(0b0001)。
FiRa OOB管理协议事件定义如下:
FiRa设备根据其角色,发送或处理FiRa OOB管理协议事件行为。
根据图中也可以看到关于管理事件的传输方向: