01-帧结构:每个字节的预算份额


3.1 帧结构:每个字节的预算份额

本节摘要:LoRaWAN 的帧由帧头、端口、净荷与消息完整性校验(MIC)组成,每一段都有固定的字节开销。本节拆开 PHYPayload,算清"12 字节的应用数据到底要背多少字节的包袱",并给出常用净荷长度对照表。位置:2.3 落了物理层,本节进入 MAC 层的第一笔账:字节开销。

PHYPayload 的四段结构

PHYPayload = MHDR(1) + MACPayload + MIC(4) MACPayload = FHDR(7~22) + FPort(0~1) + FRMPayload(0~N) FHDR = DevAddr(4) + FCtrl(1) + FCnt(2) + FOpts(0~15) ​

各段含义:MHDR 标记消息类型(Join 请求、上行数据、下行数据等);FHDR 是帧头,含设备地址、控制字节、帧计数器与可选 MAC 命令;FPort 区分端口(0 表示帧载荷全是 MAC 命令);FRMPayload 是加密后的应用数据;MIC 是 4 字节的消息完整性校验,防止篡改。

开销账:12 字节数据要背多少包袱

项目 字节数 说明
应用数据(明文) 12 真正的业务载荷
MHDR 1 帧类型
DevAddr 4 短地址
FCtrl 1 确认位、ADR 位、FOpts 长度
FCnt 2 帧计数器(低 16 位)
FPort 1 端口号
MIC 4 完整性校验
合计(不含 FOpts) 25 净荷 12 + 开销 13

也就是说,12 字节的应用数据在空口上要占 25 字节(未算加密膨胀,加密不增加长度)。开销占比超过 100%——这就是为什么"把报文压短"是最有效的优化:省的是整个帧的时间,不只是净荷的时间。

帧长对空中时间的影响

回到 2.2 的量级估算:在 SF12/125kHz 下,20 字节与 40 字节的空中时间差约 0.6s。如果一天上报 24 次,省 20 字节等于每天省约 14 秒空中时间——在 1% 占空比(每小时 36 秒)的预算里,这就是接近 10% 的信道容量。

帧格式的二进制视角

把帧结构落到字节序列上,才能和抓包工具里的 hexdump 对上号。一段上行数据帧的示例:

MHDR = 0x40 (上行未确认数据) DevAddr= 0x26011B6E (设备短地址) FCtrl = 0x10 (ADR=1, ADRACKReq=0, ACK=0, FOptsLen=0) FCnt = 0x0005 (帧计数器低 16 位 = 5) FPort = 0x01 (应用端口) FRMPayload = 8 字节 (AES-128 加密后的应用数据) MIC = 4 字节 (AES-CMAC 截断到 32 位) hexdump: 40 26 01 1B 6E 10 00 05 01 [8字节密文] [4字节MIC] ​

要点一:FCtrl 是一个位域,最高位 ADR、次高位 ADRACKReq、第三位 ACK、低 4 位是 FOptsLen。解析时必须按位拆,不能当整数字节。要点二:FCnt 在帧里只有 16 位,完整 32 位计数器在网络服务器侧维护,靠"最近一次收到的 16 位"与历史值推断高 16 位——这就是 4.3 节帧计数同步要处理回绕的原因。要点三:MIC 覆盖整个 PHYPayload 头部与载荷,接收端先验 MIC 再处理载荷,验不过直接丢弃。

下行帧的差异

下行数据帧的 FHDR 结构与上行几乎相同,但 FCtrl 的位域含义有差异:下行 FCtrl 的 ADR 位是"请求设备上报 ADR 状态",并多了 Class B 的 FPending 位(表示还有更多下行待发)。实现时最容易犯的错是用同一套解析代码处理上下行——位域定义不同,解析结果会错位。

帧长上限与规划

EU868 下,上行未确认帧的 FRMPayload 上限是 51 字节(SF12,因空中时间约束),而 SF7 下可以到 222 字节——净荷上限随速率浮动。规划应用数据时,建议按"最坏速率下的上限"设计报文格式,并做分片或压缩预案。下行帧上限通常更大,但同样受区域规则约束。

易错点补充

  • 把 MIC 当可选项:MIC 是完整性校验不是防重放(重放防的是帧计数,见 4.3),两者都要,缺一不可;
  • 用 strlen 处理二进制载荷:加密后的载荷可能含 0x00,必须按长度字段处理,C 代码里这是经典越界来源;
  • 规划报文时只用净荷上限的一半:留出将来加字段与 MAC 命令的空间,避免"报文满了 ADR 一降速就发不出去"。

易错点清单

  • 把净荷当全帧:规划数据量时按"净荷 + 13 字节固定开销"算,否则信道容量会高估一倍;
  • 混淆 FOpts 与 FPort 载荷:FOpts 里的 MAC 命令不加密、不进 FRMPayload,两者混用会导致解析错位;
  • 忽略 FPort 0 的语义:FPort=0 表示载荷全部是 MAC 命令,应用数据必须用 1–223,端口规划要预先约定。

要点回顾:PHYPayload 由 MHDR、FHDR、FPort、载荷与 MIC 组成;12 字节净荷实际占用约 25 字节空中字节;压短报文是全栈最有效的优化。下一节算另一笔时间账:接收窗口为什么只开那么短、Class A/B/C 怎么切换。

小结与延伸

帧结构这笔账可以一句话收束:12 字节净荷实际要背约 13 字节固定开销,压报文是全局最优解。实现上记住三个"必须":解析前必须校验长度、FCtrl 必须按位解析、MIC 必须最先验证。延伸思考:FPending 位、ADRACKReq 位这类"位级协议"在抓包工具里容易被忽略,调试下行丢包时,先在帧头把每个位拆出来对照状态机,再怀疑射频层——大量"射频玄学"其实是帧头位域解析错误造成的。

延伸:加密对帧长的影响

应用载荷用 AES-128 加密,密文与明文等长,加密不增加字节;但 MIC 的 4 字节是净增开销。理解这一点对规划有意义:报文压缩(如把浮点转整数、字段打包)能直接缩小 FRMPayload,从而缩短空中时间;而"加密"本身不会带来额外空口成本——所以安全与效率不冲突,压缩与安全可以同时做。另一个相关点:FOpts 里的 MAC 命令不加密,抓包工具能看到明文命令,敏感的命令参数(如信道列表)不应放进 FOpts,应放入加密的 FPort=0 载荷。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U