本节摘要:LoRaWAN 的帧由帧头、端口、净荷与消息完整性校验(MIC)组成,每一段都有固定的字节开销。本节拆开 PHYPayload,算清"12 字节的应用数据到底要背多少字节的包袱",并给出常用净荷长度对照表。位置:2.3 落了物理层,本节进入 MAC 层的第一笔账:字节开销。
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 | 真正的业务载荷 |
| 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 字节——净荷上限随速率浮动。规划应用数据时,建议按"最坏速率下的上限"设计报文格式,并做分片或压缩预案。下行帧上限通常更大,但同样受区域规则约束。
要点回顾: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 载荷。