本节摘要:设备入网走 OTAA:发 JoinRequest、收 JoinAccept、派生出三把会话密钥。本节把全流程的时序、字节开销与失败重试机制拆开,并回答"为什么要等 5 秒"这类常见疑问。位置:3.3 结了 MAC 层的账,本章起算入网与安全这本账。
JoinRequest = AppEUI(8) + DevEUI(8) + DevNonce(2) + MIC(4) JoinAccept = JoinNonce(3) + NetID(3) + DevAddr(4) + DLSettings(1) + RxDelay(1) + CFList(0/16) + MIC(4)
设备上电 → 构造 JoinRequest(AppEUI+DevEUI+DevNonce),用 AppKey 计算 MIC → 在加入信道上发送(Join 通道组通常与数据信道不同) → 等待 RX1 / RX2(默认 1s / 2s)接收 JoinAccept → 收到后校验 MIC(AppKey),失败则丢弃并等待重试 → 从 JoinAccept 解析 DevAddr 与 DLSettings,派生三把密钥 → 入网完成,进入正常数据通信
时间开销的账:一次 Join 报文约 23 字节(SF7 下约 0.15s 空中时间,SF12 下约 1.5s),加上 RX 等待窗口,一次成功的 OTAA 通常耗时 2–3 秒。如果 Join 失败重试,默认退避策略使失败间隔从几十秒指数增长到几小时——这是为了在信道拥塞时保护网络,也是"设备怎么一直不联网"类问题的常见根因。
入网成功的核心产物是三把 128 位会话密钥(4.2 详述):NwkSKey(网络层完整性,算 MIC、解网络载荷)、AppSKey(应用层加解密)、以及由 DLSettings 决定的上行下行方向参数。派生过程用 AES-128 密钥扩展算法从 AppKey 与 JoinNonce、DevNonce、NetID 计算,对设备侧来说只是几次 AES 运算,但对安全的意义重大:入网后 AppKey 不再参与通信,只有网络侧需要保留。
OTAA 最常见的故障是"设备一直不联网",排错要按因果链从下往上查。第一层:射频——用频谱仪或网关日志确认 JoinRequest 是否真的发出、频率是否在 Join 信道上(Join 信道组与数据信道不同,误配频率是头号原因)。第二层:MIC——用抓包工具离线验证 JoinRequest 的 MIC 是否用正确的 AppKey 算出,AppKey 写错一字节,全网静默。第三层:DevNonce——设备重复使用 DevNonce 会被网络服务器直接丢弃,检查随机源与持久化。第四层:时序——JoinAccept 在 RX1/RX2 窗口下发,设备本地时间偏移超过窗口就会错过,检查 32kHz 时钟校准。
| 现象 | 优先怀疑 | 验证手段 |
|---|---|---|
| 无任何上行 | 射频配置/信道组 | 频谱仪、网关日志 |
| 有上行无 JoinAccept | MIC/AppKey | 离线验 MIC |
| JoinAccept 收到但校验失败 | DevNonce 重复 | 抓包比对 DevNonce |
| 入网偶发失败 | 时钟漂移/窗口 | 长时观测成功率 |
一条经验:入网成功率应当被监控——网络服务器侧统计 JoinRequest 与 JoinAccept 的比值,低于 95% 就要查设备固件版本与信道配置,而不是等现场投诉。
Join 报文虽然短,但在拥塞时是容量杀手:大量设备同时上电(如停电恢复后电网一起上报)会瞬间淹没 Join 信道。网络服务器的 Join 调度要有节流:限制同一时间片的 JoinRequest 处理量、对重复 Join 的同一设备合并处理。设备侧的退避策略(指数增长)在这里是保护机制而不是缺陷——量产时"上电即连"的体验需求,要与"网络不被冲垮"的安全需求做平衡。
要点回顾:OTAA 用 AppKey 保护的 JoinRequest/JoinAccept 建立信任;一次入网 2–3 秒,失败退避指数增长;三把密钥由入网参数派生、AppKey 随之退役。下一节把三把密钥的分工与 AES-CMAC 的实现细节摊开。
小结与速查:OTAA 一次入网 = JoinRequest(23B) → JoinAccept → 派生密钥,成功 2–3 秒;失败按指数退避重试;CFList 必须解析。排错四层:射频 → MIC/AppKey → DevNonce → 时序。记住:入网走 Join 信道、DevNonce 全局唯一、JoinAccept 的 MIC 用 AppKey 验。
