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

背景

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

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

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

协议介绍

这段协议英文还是比较拗口,中间有一句太长都不好断句,翻出了之前啃过的这段翻译(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。

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,可以禁用掉对帧计数的校验。

正常情况下,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.FCnts.FCntUp = macPL.FHDR.FCnts.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 setmicOK, 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 LSBgap := 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 帧计数机制及典型问题分析相关推荐

  1. x264参数介绍(帧类型和码率控制,分析和视频可用性信息)

    鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置.这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合自己需要,手动设 ...

  2. Linux网络协议栈:NAPI机制与处理流程分析(图解)

    Table of Contents NAPI机制 NAPI缺陷 使用 NAPI 先决条件 非NAPI帧的接收 netif_rx - 将网卡中收到的数据包放到系统中的接收队列中 enqueue_to_b ...

  3. 以太坊POA共识机制Clique源码分析

    以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Clique相关源码做一个解读分析. Clique的 ...

  4. 3D激光SLAM:LeGO-LOAM---两步优化的帧间里程计及代码分析

    3D激光SLAM:LeGO-LOAM---两步优化的帧间里程计及代码分析 前言 利用地面点优化 利用角点优化 代码部分 gazebo测试 前言 LeGO-LOAM的全称是 Lightweight an ...

  5. html+css技巧分享和IE6典型BUG分析(重温一下)

    上个星期六,给公司的一些童鞋,做了一次分享, 分享的主题是HTMl+css开发技巧 为此一个星期都没有怎么做项目,准备了一个3dppt,也就是impress.js插件, 每种类型也做了一个例子,, 讲 ...

  6. 数据泄露典型判例分析报告

    声明 本文是学习数据泄露典型判例分析报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 研究背景 近年来,数据安全已经成为网络安全行业聚焦点最高的一个细分领域.随着" ...

  7. 应急响应典型案例分析

    声明 本文是学习奇安信 2022年上半年网络安全应急响应分析报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 应急响应典型案例分析 2022年上半年奇安信安全服务团队共接到 ...

  8. 交叉分解(Cross decomposition)、典型关联分析(Canonical Correlation Analysis,CCA)、偏最小二乘回归PLS

    交叉分解(Cross decomposition).典型关联分析(Canonical Correlation Analysis,CCA).偏最小二乘回归PLS 目录 交叉分解.典型关联分析(Canon ...

  9. 典型相关分析(cca)原理_CCA典型关联分析原理与Python案例

    文章来源于"脑机接口社区" CCA典型关联分析原理与Python案例​mp.weixin.qq.com Rose今天分享一下CCA的相关原理以及Python应用,CCA在EEG等脑 ...

最新文章

  1. 项目中的技巧经验汇总
  2. mysql 快照读 幻读,InnoDB的MVCC如何解决不可重复读和快照读的幻读,当前读用next-key解决幻读...
  3. unity安装,sdk,jdk问题
  4. 图论讲解(3)——最小生成树(基础)
  5. 如何编写java请求_如何避免将Java请求从Java Web服务器发送到自身?
  6. python3.6+selenium_Testsuits测试套件
  7. Spring Retry 重试机制实现及原理
  8. 一个四维的人在三维世界里到底长什么模样?
  9. lua打开浏览器并加载网页_Lua访问网页
  10. Topcoder SRM 655 DIV1 250 CountryGroupHard
  11. TMS、物流系统、司机运输商、承运商、结算流程、运输流程、运输调度、结构图、在途跟踪、提货单、签收单、回单交接、车辆管理、运力资源、报价管理、发票管理、询价单管理、审批报价、KPI数据、适度配载
  12. [framework] multi learner
  13. 灵魂拷问!软件架构师书籍
  14. python私有成员与公有成员_Python访问限制私有还是公有的介绍(附示例)
  15. 【测试】软件测试之测试用例的设计方法
  16. 从王者荣耀看设计模式(十六.原型模式)
  17. oracle清理磁盘空间
  18. 鸿蒙能用谷歌地图,华为鸿蒙更进一步,牵手世界级应用,谷歌GMS或彻底再见
  19. 正确的握笔姿势,握笔的姿势非常的重要
  20. 台式机鼠标失灵打开计算机,台式电脑鼠标不动怎么办

热门文章

  1. CRNN:文本序列识别
  2. Python常用第三方库
  3. 双18期|CSS揭秘之简写属性
  4. 你学了多久 Python 并能正式工作?
  5. Unity向量投影使用
  6. BIM建模助手上线一周,有哪些BUG被用户找到?
  7. 关于CClientDC与CPAINTDC,以及GetDC与GetWindowDC的用法。
  8. matlab实现正弦内插算法(低通滤波)
  9. 老DOS游戏-殖民计划
  10. Android 点九图 .9图