LoRaWAN 帧计数机制及典型问题分析

这篇笔记对 LoRaWAN 常见的 ABP 设备帧计数问题进行了追踪分析,介绍了帧计数禁用的调试办法,以及一个不大常见却又隐蔽的细节问题。希望帮助 LoRaWAN 初学者系统性地了解 LoRaWAN 的帧计数机制。

背景

最近一周接连遇到了两个朋友关于 LoRaWAN 帧计数的问题咨询,特别是一个问题隐藏地比较深,好不容易排查了出来,因此做了笔记记录下。

一个是朋友A发来的,他的问题很典型,很多初学者都会遇到,就是 LoRaWAN 设备莫名其妙就不上报数据了,提示帧计数异常。

LoRaWAN 帧计数机制及典型问题分析_第1张图片

我们先从这个问题来说起。

协议介绍

LoRaWAN 帧计数机制及典型问题分析_第2张图片

这段协议英文还是比较拗口,中间有一句太长都不好断句,翻出了之前啃过的这段翻译(https://github.com/twowinter/LoRaWAN-Specification_ZH_CN),这段中的 provided 是假如的意思,以前没翻译出来,于是重新整理了下翻译。

终端入网成功后,终端和服务端的上下行帧计数同时置0。 每次发送消息后,发送端与之对应的 FCntUp 或 FCntDown 就会加1。
如果收到的帧计数相比当前计数有增长,同时两者相差小于 MAX_FCNT_GAP(考虑了计数翻转),接收方就按接收的帧计数更新对应值。
如果两者相差大于 MAX_FCNY_GAP 就说明中间丢失了很多数据,这条数据包就被丢掉。

所以我们可以小结下,一个合理的FCnt必须满足两个点:
1.FCnt 必须是增长的;
2.FCnt 的变化值必须小于 MAX_FCNT_GAP;

MAX_FCNT_GAP 是多少呢?在 LoRaWAN 区域参数规范里有介绍,咱们CN470中这个数值是 16384。

LoRaWAN 帧计数机制及典型问题分析_第3张图片

ABP设备帧计数问题分析

回到开头的问题上。

OTAA设备一般很少遇到FCnt的问题,因为每次设备重启可能都会进行Join,这样FCnt直接都置为0了。
而ABP设备没有Join操作,很多设备没做FCnt的保存,一旦重启,设备FCnt归0,而NS还是之前的旧值,那接下来的数据都会被丢弃,一直得等 FCnt 递增超过之前的大小。

同学可能会问,为什么一定要等 FCnt 超过缓存值才能正常通信呢?

因为设备上报的FCnt如果是一个旧的历史值,那说明这是一个收到过的数据,旧的数据就没必要处理了。如果不这样设计的话,那极端情况下,可能会被重放攻击。比如一个水表场景,我可以录下水表过去的一包数据,表明水表的度数,等要交水费重放这一个数据包,这样就不用交水费了。

禁用帧计数校验

那一些朋友可能手头就只有一个不完善的ABP设备,一旦重启设备FCnt重置就无法通信了,那该怎么办?

简单的办法是这样,每次重启了就手动在 NS 后台重置下这个 FCnt,让NS的缓存计数也清零。

这样每次重启都要操作NS,还有更简单的办法吗?

开源协议栈 chirpStack 为了方便开发者调试,提供了一个选项 Disable frame-counter validation,可以禁用掉对帧计数的校验。

LoRaWAN 帧计数机制及典型问题分析_第4张图片

正常情况下,FCnt 正常,那数据传输也正常,比如下面这两种情况,只要FCnt是增加的,且GAP不超过限值,那都OK。
DeviceFCntUp 80 SessionFCntUp 0
DeviceFCntUp 10080 SessionFCntUp 0

禁用了帧计数校验后,就很潇洒了,即使FCnt乱来也都能正常进行数据传输。比如下面的两种情况,一个是设备FCnt重置了,一个是设备FCnt与平台的FCnt差值超过了限值,即使是这样的情况,NS也能正常传输这些设备数据。
DeviceFCntUp 0 SessionFCntUp 249 // FCnt 回滚
DeviceFCntUp 30080 SessionFCntUp 249 // FCnt 超过 MAX_FCNT_GAP

典型问题:禁用帧计数校验也不灵

问题描述

照理来说这个帧计数校验挺好用的,至少小能手使用起来还挺方便。

但最近一个伙伴在进行NS迁移(将一些设备从旧的NS迁到新的NS)时就遇到了一个问题, 明明在新的NS上禁用掉了帧计数校验,设备数据也从网关上报到了NS,但NS却拦截了这个设备的数据,迟迟无法正常传输。

开源 NS 处理逻辑

于是找到了 NS 的代码研究起来,伪代码如下,/internal/storage/device_session.go。

func GetDeviceSessionForPHYPayload() {
    ...
    fullFCnt, ok := ValidateAndGetFullFCntUp(s, macPL.FHDR.FCnt)
    if !ok {
        // If RelaxFCnt is turned on, just trust the uplink FCnt
        // this is insecure, but has been requested by many people for
        // debugging purposes.
        // Note that we do not reset the FCntDown as this would reset the
        // downlink frame-counter on a re-transmit, which is not what we
        // want.
        if s.SkipFCntValidation {
            fullFCnt = macPL.FHDR.FCnt
            s.FCntUp = macPL.FHDR.FCnt
            s.UplinkHistory = []UplinkHistory{}

            // validate if the mic is valid given the FCnt reset
            // note that we can always set the ConfFCnt as the validation
            // function will only use it when the ACK bit is set
            micOK, err := phy.ValidateUplinkDataMIC(s.GetMACVersion(), s.ConfFCnt, uint8(txDR), uint8(txCh), s.FNwkSIntKey, s.SNwkSIntKey)
            if err != nil {
                return DeviceSession{}, errors.Wrap(err, "validate mic error")
            }
        }
    }
    ...
}

func ValidateAndGetFullFCntUp(s DeviceSession, fCntUp uint32) (uint32, bool) {
	// we need to compare the difference of the 16 LSB
	gap := uint32(uint16(fCntUp) - uint16(s.FCntUp%65536))
	if gap < band.Band().GetDefaults().MaxFCntGap {
		return s.FCntUp + gap, true
	}
	return 0, false
}

原因分析

从日志来看,DeviceFCntUp 已经达到了 105007,因此超过了 MAX_FCNT_GAP,代码逻辑进入到了 SkipFCntValidation 的条件处理中,在这里返回了 MIC 校验出错的结果。

小能手于是用模拟器做了一些测试,最终定位到 FCnt 上,在 SessionFCntUp 为 0 的情况下,DeviceFCntUp 如果小于 65535 则没问题,超过 65535 则会 MIC 报错。

DeviceFCntUp 57921 SessionFCntUp 0 // mic OK
DeviceFCntUp 123456 SessionFCntUp 0 // mic err

于是推断出来原因应该是这样,FCnt 在空中(LoRaMAC)只能传输16bit,因此 NS 无法知道设备 FCnt 是否大于65535,只能按照低16bit来处理。

解决办法

所以在这种情况下,FCnt 的同步就成问题了,只能手动告诉 NS 当前 FCnt,这时候 NS 上的 SessionFCntUp 只要低于 DeviceFCntUp,且差值不超 MAX_FCNT_GAP 就可以了。

DeviceFCntUp 是 105007,我在 NS 后台配了个 100007,过一会儿设备便正常上报了。问题解决。

END


IoT小能手的其他精彩文章:

  • 行业围观
    深度报道 第1个从太空发回的LoRa信号(含视频)
    从工信部发文解读政府对LoRa产业的态度

  • 技术分享
    LoRaWAN介绍 - LoRa从业者读这篇就够了
    干货 | LoRaWAN 协议中文版,你要的pdf来了
    无线节点的空中唤醒技术解析

  • 玩玩硬件
    自制一个 LoRa PM2.5 监测器
    语音控制智能家居的抽风小仓鼠
    一些有关电子的好玩东西

  • 心得分享
    文档啊,最重要的还是层次感
    技术管理入门课_先做个不讨厌的人
    你没中过勒索病毒,不知道备份有多重要

LoRaWAN 帧计数机制及典型问题分析_第5张图片

你可能感兴趣的:(联,-,LoRa,lora,物联网,iot,lorawan)