第四章 逻辑帧结构

4.1 帧的组成

Logical_Frame(逻辑帧)是 DTP 的应用层帧结构,由两部分组成:

┌─────────────────────────────────────────┐
│              Logical_Frame               │
├─────────────────────────────────────────┤
│  Header(帧头)                          │
│  ┌─────────────────────────────────────┐│
│  │ protocolVersion   协议版本号         ││
│  │ frameType         帧类型标识         ││
│  │ fragmentId        Fragment 唯一标识  ││
│  │ agreementId       约定 ID(可压缩)  ││
│  │ originTimestamp   原始时间戳         ││
│  │ dagDependencies   DAG 依赖列表      ││
│  │ encryptionMetadata 加密元数据       ││
│  │ sequenceNumber    序列号            ││
│  └─────────────────────────────────────┘│
├─────────────────────────────────────────┤
│  Payload(载荷)                         │
│  ┌─────────────────────────────────────┐│
│  │ 加密后的实际数据内容                  ││
│  └─────────────────────────────────────┘│
└─────────────────────────────────────────┘

关键设计决策:

  • 帧头中的加密元数据本身不加密,以便接收方确定解密方式
  • Logical_Frame 在终端→Fay 和 Fay→终端两个方向使用相同的帧结构定义
  • 物理传输需要分片时,分片操作委托给底层 Transport_Adapter 处理,Logical_Frame 保持完整性

4.2 帧类型

DTP 定义四种帧类型:

帧类型标识用途
数据帧data承载实际的 Fragment 数据
请求帧request发起数据请求或调整传输约定
响应帧response回复数据请求,包含接受、拒绝或协商结果
控制帧control传递错误通知、约定终止等控制信息

4.3 帧头字段详解

协议版本号(protocolVersion)

{ major: number, minor: number }

标识当前帧使用的协议版本。接收方据此判断是否兼容。

帧类型标识(frameType)

标识帧的类型,决定载荷的解析方式。

Fragment 唯一标识符(fragmentId)

全局唯一的 UUID v4 标识符,用于在 DAG 中引用和追踪。

约定 ID(agreementId)

标识该 Fragment 所属的约定。支持压缩传输:当连续的 Fragment 属于同一约定时,仅在该批次的首个 Fragment 头部携带完整的 Agreement_ID,后续 Fragment 可省略(设为 null)。

接收方规则:

  • 收到未携带 Agreement_ID 的 Fragment 时,关联到当前上下文中最近一次声明的 Agreement_ID
  • 收到引用了未知 Agreement_ID 的 Fragment 时,丢弃该 Fragment 并发送"约定不存在"错误通知

原始时间戳(originTimestamp)

数据在源端实际产生的时刻,使用 UTC 时区和毫秒级精度。与传输时间戳分离存储,不受传输延迟影响。

例如:用户在地铁中离线记录了 30 分钟的心率数据,出站后批量上传——每条记录保留的是实际测量时刻的时间戳,而非上传时刻。

DAG 依赖列表(dagDependencies)

声明与其他 Fragment 的依赖关系,每条依赖包含:

  • 目标 Fragment_ID
  • 关系类型(derived_from / annotates / supersedes

支持声明零个或多个依赖关系。

加密元数据(encryptionMetadata)

{ algorithm: string, keyVersion: number }
  • algorithm:加密算法标识(如 "AES-256-GCM")
  • keyVersion:密钥版本号

加密元数据本身不加密,以便接收方确定解密参数。

序列号(sequenceNumber)

传输序列编号,在单次会话内单调递增,用于续传机制。每个传输方向维护独立的序列号空间。

4.4 序列化与反序列化

DTP_Engine 将 Logical_Frame 对象序列化为二进制格式进行传输,接收方将二进制数据反序列化为 Logical_Frame 对象。

核心保证——往返一致性:对于任意有效的 Logical_Frame 对象,序列化后再反序列化应产生与原始对象等价的 Logical_Frame。

DTP_Engine 还提供格式化输出功能(Pretty Printer),将 Logical_Frame 对象转换为人类可读的文本格式,便于调试和日志记录。

4.5 上下文元数据

每个 Fragment 携带结构化的上下文元数据(ContextMetadata),包括:

  • 数据类型标识(dataType):描述数据的类型
  • 数据来源(source):区分硬件来源和软件来源
  • 自定义字段(customFields):可扩展的键值对结构

硬件来源

当数据来源于硬件传感器时,元数据包含:

  • 传感器类型(sensorType)
  • 传感器精度(precision)
  • 采样率(samplingRate,单位 Hz)

软件来源

当数据来源于软件共享时,元数据包含:

  • 来源应用标识(appIdentifier)
  • 共享方式描述(sharingMethod)