一条 LED 命令,是怎么「包了一层又一层」发出去的?
协调器的应用层写下 2 个字节的开关命令 [01 01],要送到 3 米外的终端。它会依次穿过 应用 → APS → NWK → MAC → PHY 五层:每一层都往上套一个自己的「信封」(帧头),最后由天线把整封信发到空中。接收端再一层层拆开,直到拿到原始命令点亮 LED。本页用 ns-3 真实仿真跑出了这个过程,你看到的所有字节和时序都来自真实运行日志。
想象寄一封国际快递
协议栈分层不是学术刁难,它就是一套「分工寄件」的规矩。每一层只做自己的事,不关心别的层怎么干活。
把终端设备想象成一座写字楼,协调器是另一座楼,要寄一封信过去:
- 应用层——写信的人。只负责写内容:「把灯点亮」。
- APS 层——楼内收发室。写上「寄件人房间 8 号 → 收件人房间 3 号」和「办什么事(开关灯业务)」。
- NWK 层——城市邮局。写上「从 0x0000 寄到 0x7582」、最多经手 10 站、信件的编号。
- MAC 层——快递员 + 信封。贴上本网络名(PAN)、收寄件地址、是否需要回执,最后装箱。
- PHY 层——货车 / 无线电。把整封信调制到 2.4GHz 电磁波里发出去。
接收端收到后,把顺序反过来:货车卸货 → 快递员拆箱 → 城市邮局查地址 → 收发室核对房间号 → 最后把信纸内容交给收件人。
五层各司其职
点击下面的层,查看它负责什么、它在帧头里写了什么、在 ns-3 里对应哪个日志组件。所有帧头字段都是下面真实空中帧里能逐字节对上的。
点「发送一次」,看数据怎么一层层穿下去
协调器应用端点 8 → 终端端点 3。点击按钮后,一个 2 字节命令会从应用层出发,每经过一层就在头上「叠」一个该层的信封,最后变成一个完整的 29 字节空中帧。右下角会实时告诉你这一层做了什么。
这条命令在空中长什么样
下面是 ns-3 真实运行时、PHY 层交给射频发送的完整 29 字节。点击任意一个字节,查看它属于哪一层、代表什么。颜色与协议栈五层一一对应。
收到的是 29 字节,交给应用的是 2 字节
接收端(终端)把过程完全反过来:天线收到比特 → PHY 解调 → MAC 拆掉自己的头 → NWK 查短地址是不是自己的 → APS 按端点号投递 → 应用层拿到最里面的 2 个字节 [01 01]。
怎么自己跑出这些数据
本页所有数据来自示例 zigbee-stack-layers.cc 在 ns-3.48 里的真实运行。它的关键做法就两件事:开日志、挂 trace。
LogComponentEnable("ZigbeeAps", LOG_LEVEL_DEBUG);
LogComponentEnable("ZigbeeNwk", LOG_LEVEL_DEBUG);
LogComponentEnable("LrWpanMac", LOG_LEVEL_DEBUG);
LogComponentEnable("LrWpanPhy", LOG_LEVEL_INFO);日志组件名与协议栈层一一对应:APS 层 = ZigbeeAps,网络层 = ZigbeeNwk,MAC 层 = LrWpanMac(802.15.4 的 MAC),PHY 层 = LrWpanPhy。把它们打开,ns-3 就会在每一层进出时打印日志。
dev->GetPhy()->TraceConnectWithoutContext("PhyTxBegin",
MakeCallback(&OnPhyTxBegin));
dev->GetPhy()->TraceConnectWithoutContext("PhyRxEnd",
MakeCallback(&OnPhyRxEnd));PHY 层有现成的 trace 源:PhyTxBegin 在帧真正发出前触发,PhyRxEnd 在接收端解调完成后触发。回调里把 Ptr<Packet> 逐字节打印出来,就是上面那份 29 字节帧。
ApsdeDataRequestParams req; req.m_srcEndPoint = 8; // 源端点:控制器应用 req.m_dstEndPoint = 3; // 目的端点:LED 执行器 req.m_profileId = 0x0104; // Profile:Home Automation req.m_clusterId = 0x0006; // 簇:On/Off(开关灯) req.m_dstAddr16 = 终端短地址; // 0x7582 Ptr<Packet> p = Create<Packet>(buf, 2); // [01 01] Simulator::ScheduleNow(&ZigbeeAps::ApsdeDataRequest, aps, req, p);
真实运行日志(本页数据来源,摘录):
五层对照速查
| 层 | 一句话职责 | 它在帧头里写了什么 | 本页真实示例 | ns-3 日志组件 |
|---|---|---|---|---|
| 应用层 | 决定「干什么」,用端点区分多个应用 | (不带头)内容即载荷 | 端点 8 发 [01 01] | 无(应用自己) |
| APS | 端点寻址 + 业务(簇/Profile)标识 | 帧控制 · 源/目的端点 · 簇 ID · Profile ID | 端 8→3 · 簇 0x0006 · Profile 0x0104 | ZigbeeAps |
| NWK | 组网、短地址寻址、路由、跳数限制 | 帧控制 · 源/目的短地址 · 半径 · 序列号 | 0x0000→0x7582 · 半径 10 | ZigbeeNwk |
| MAC | 802.15.4 帧格式、PAN、确认、信道访问 | 帧控制 · 帧序号 · PAN ID · 短地址 · FCS | PAN 0x1bb1 · 帧序号 0x30 | LrWpanMac |
| PHY | 调制解调、发送/接收比特流 | (不带头)负责把整帧调制到 2.4GHz | 29 字节帧发射 | LrWpanPhy |