3. 消息格式
CoAP 基于紧凑 message 的交换, 默认通过 UDP 传输 (即每个 CoAP message 占据一个 UDP datagram 的数据部分). CoAP 也可在 Datagram Transport Layer Security (DTLS) 上使用 (见 Section 9.1). 它还可在 SMS, TCP 或 SCTP 等其他传输上使用, 但这些传输的规范超出本文档范围. (CoAP 不支持 UDP-lite [RFC3828] 和 UDP zero checksum [RFC6936].)
CoAP message 采用简单的二进制格式编码. message format 以固定大小的 4 字节 header 开始. 其后是可变长度 Token 值, 长度可为 0 到 8 字节.
Token 值之后是零个或多个 Type-Length-Value (TLV) 格式的 CoAP Options 序列, 可选地后跟占据 datagram 剩余部分的 payload.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T | TKL | Code | Message ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图 7: 消息格式
header 中的字段定义如下:
Version (Ver): 2-bit unsigned integer. 指示 CoAP version number. 本规范的实现 MUST 将此字段设置为 1 (01 binary). 其他值保留给未来版本. 具有未知 version number 的 message MUST 被静默忽略.
Type (T): 2-bit unsigned integer. 指示该 message 类型是 Confirmable (0), Non-confirmable (1), Acknowledgement (2) 还是 Reset (3). 这些 message type 的语义在 Section 4 中定义.
Token Length (TKL): 4-bit unsigned integer. 指示可变长度 Token 字段的长度 (0-8 bytes). 长度 9-15 保留, MUST NOT 发送, 并且 MUST 作为 message format error 处理.
Code: 8-bit unsigned integer, 拆分为 3-bit class (最高有效位) 和 5-bit detail (最低有效位), 记为 "c.dd", 其中 "c" 是 0 到 7 的数字, 表示 3-bit 子字段, "dd" 是 00 到 31 的两位数字, 表示 5-bit 子字段. class 可表示 request (0), success response (2), client error response (4) 或 server error response (5). (所有其他 class 值保留.) 作为特殊情况, Code 0.00 表示 Empty message. 对于 request, Code 字段指示 Request Method; 对于 response, 则指示 Response Code. 可能值维护在 CoAP Code Registries (Section 12.1) 中. request 和 response 的语义在 Section 5 中定义.
Message ID: 16-bit unsigned integer in network byte order. 用于检测 message 重复, 并将 Acknowledgement/Reset 类型的 message 与 Confirmable/Non-confirmable 类型的 message 匹配. Message ID 的生成规则和 message 匹配规则在 Section 4 中定义.
header 后跟 Token 值, 其长度按 Token Length 字段给出, 可为 0 到 8 字节. Token 值用于关联 request 和 response. Token 的生成规则以及 request 与 response 的关联规则在 Section 5.3.1 中定义.
Header 和 Token 后跟零个或多个 Option (Section 3.1). 一个 Option 后面可以是 message 结束, 另一个 Option, 或 Payload Marker 与 payload.
在 header, token 和 option (如果有) 之后, 是可选 payload. 如果存在且长度非零, 它前面带有固定的一字节 Payload Marker (0xFF), 用来指示 option 结束和 payload 开始. payload data 从 marker 之后一直延伸到 UDP datagram 结束, 即 Payload Length 根据 datagram size 计算. Payload Marker 缺失表示零长度 payload. 存在 marker 且后跟零长度 payload MUST 作为 message format error 处理.
Implementation Note: 字节值 0xFF 也可能出现在 option length 或 value 中, 因此简单地按字节扫描 0xFF 不是查找 payload marker 的可行技术. 只有在另一个 option 可能开始的位置, 字节 0xFF 才具有 payload marker 的含义.
3.1. 选项格式
CoAP 定义了若干可包含在 message 中的 option. message 中的每个 option 实例指定所定义 CoAP option 的 Option Number, Option Value 的长度以及 Option Value 本身.
实例并不直接指定 Option Number, 而是 MUST 按 Option Number 顺序出现, 并在实例之间使用 delta encoding: 每个实例的 Option Number 计算为其 delta 与 message 中前一个实例的 Option Number 之和. 对 message 中第一个实例, 假定前一个 option 实例的 Option Number 为零. 通过使用 delta 为零, 可包含同一 option 的多个实例.
Option Number 维护在 "CoAP Option Numbers" registry (Section 12.2) 中. 本文档定义的 option 语义见 Section 5.4.
0 1 2 3 4 5 6 7
+---------------+---------------+
| | |
| Option Delta | Option Length | 1 byte
| | |
+---------------+---------------+
\ \
/ Option Delta / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ Option Length / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ /
\ \
/ Option Value / 0 or more bytes
\ \
/ /
\ \
+-------------------------------+
图 8: 选项格式
option 中的字段定义如下:
Option Delta: 4-bit unsigned integer. 0 到 12 之间的值表示 Option Delta. 三个值保留用于特殊结构:
13: 初始字节后跟一个 8-bit unsigned integer, 表示 Option Delta minus 13.
14: 初始字节后跟一个 network byte order 的 16-bit unsigned integer, 表示 Option Delta minus 269.
15: 为 Payload Marker 保留. 如果该字段设置为此值但整个字节不是 payload marker, 则 MUST 作为 message format error 处理.
所得 Option Delta 用作此 option 的 Option Number 与前一 option (或第一个 option 时的零) 的 Option Number 之间的差值. 换言之, Option Number 通过简单累加本 option 及其之前所有 option 的 Option Delta 值计算.
Option Length: 4-bit unsigned integer. 0 到 12 之间的值以字节为单位指示 Option Value 的长度. 三个值保留用于特殊结构:
13: Option Value 前有一个 8-bit unsigned integer, 表示 Option Length minus 13.
14: Option Value 前有一个 network byte order 的 16-bit unsigned integer, 表示 Option Length minus 269.
15: 为未来使用保留. 如果该字段设置为此值, 则 MUST 作为 message format error 处理.
Value: 恰好 Option Length 字节的序列. Option Value 的长度和格式取决于相应 option, 该 option MAY 定义可变长度值. 本文档使用的格式见 Section 3.2; 其他文档中定义的 option MAY 使用其他 option value format.
3.2. 选项值格式
本文档定义的 option 使用以下 option value format.
empty: 零长度字节序列.
opaque: 不透明字节序列.
uint: 非负整数, 使用 Option Length 字段给出的字节数按 network byte order 表示.
option 定义可指定允许的字节数范围; 如果有选择, sender SHOULD 用尽可能少的字节表示该整数, 即不带 leading zero byte. 例如, 数字 0 用 empty option value (零长度字节序列) 表示, 数字 1 用数值为 1 的单字节表示 (按最高有效位优先记法为 bit combination 00000001). recipient MUST 准备处理带 leading zero byte 的值.
Implementation Note: 允许 sender 采用的例外行为, 是为高度受限的模板化实现 (例如硬件实现) 设计的, 这些实现会在模板中使用固定大小 option.
string: Unicode string, 使用 UTF-8 [RFC3629] 以 Net-Unicode form [RFC5198] 编码.
注意, 在此处以及 CoAP 协议中所有使用 UTF-8 编码的其他位置, 其意图都是让编码后的 string 可由 CoAP 协议实现直接作为 opaque byte string 使用和比较. CoAP 实现中不期望也不需要执行 normalization (除非从 CoAP 协议之外的来源导入了未知是否已 normalization 的 Unicode string). 还要注意, ASCII string (不使用特殊 control character) 始终是有效的 UTF-8 Net-Unicode string.