LoRaWAN协议解析 第4章 MAC帧格式

1 前言

我正在陆续对《LoRaWAN102》即LoRaWAN协议规范 V1.0.2 版本(2016年7月定稿)协议的各个章节进行翻译。译文之外还对LoRaWAN协议和源码进行了解析,可点此查看帖子LoRa学习笔记_汇总

欢迎同行朋友们留言交流。

本文作者twowinter,转载请注明作者:http://blog.csdn.net/iotisan/

2 梳理解析

LoRaWAN第4章,主要讲述了MAC帧格式,对所有涉及的字段都做了解释。

千言万语汇成一句话,哦不,汇成一个表。

数据帧头         DevAddr FCtrl FCnt FOpts        
数据帧 Preamble PHDR PHDR_CRC MHDR FHDR FPort FRMPayload MIC CRC
MAC层 Preamble PHDR PHDR_CRC MHDR MACPayload MIC CRC
PHY层 Preamble PHDR PHDR_CRC PHYPayload CRC

好了,帧格式是大家随手都能看到的东西,本尊作为IoT小能手,如果不能提出一些稍有深度的信息增量,就对不起这个称号了。所以,有些协议设计层面的心得要分享下:

  1. 特别酷的ADR(速率自适应)机制
    这个章节中最亮眼的莫过于速率自适应机制,简直是为LoRa网络量身定做的:一旦使能了FCtrl中的ADR位,距离近信号好的节点用高速率,距离远信号弱的节点用低速率,不小心被调高了速率,则自动降下来。这样,尽可能地提高了传输速率,也有效提高了网络容量。我已经见过不少厂家,拿这个协议的公知特点当产品卖点了。
  2. 可同时携带数据和命令的MAC帧
    一般来说,应用除了数据,出于管理需要,肯定还会涉及命令。比如基站要查询节点状态,或者节点要请求变更信道等。所以LoRaWAN协议设计上利用FOpts把数据和命令揉在一个MAC帧里,这样可以提高交互效率,有效地降低功耗。这在寸土寸金,哦不,寸库仑(电量单位)寸金的物联网应用中,是一个很有必要的设计。

3 源码解析

这章的处理基本都在 \src\mac\LoRaMac.c 中,下面按照MAC帧格式的字段逐个解析下。

3.1 MAC层MHDR

在LoRaWAN的数据API中处理了MHDR,这个字段内容比较少,就按需选择了消息类型是confirm还是unconfirm。
另外在管理API中的Join-Req的消息类型。

具体可见 LoRaMacMcpsRequest() 和 LoRaMacMlmeRequest() 这两个函数。

3.2 MACPayload

MACPayload 的组帧都在 PrepareFrame() 这个函数中处理,将macHdr和macPayload的fCtrl、FPort、FRMPayload都传递进去,完成整个MAC层的数据组帧。

LoRaMacBuffer就存放了MACPayload的数据,这个变量的组帧和协议字段定义是一一对应。MACPayload的组帧处理,在大流程上是对join和数据两种类型的帧分别处理,用两个case分开。

为了方便阅览,我把函数代码框架提炼了出来。


Join-request的组帧处理对应协议第6章 6.2.4 Join-request message。
数据帧的组帧处理则稍微复杂些,尤其是FHDR,下面逐个字段讲解下FHDR。

3.2.1 MACPayload中的FHDR

  • 1.FHDR中的DevAddrLoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
    LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
    LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
    LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
  • 2.FHDR中的FCtrl

首先 ADR 位段 是在传入 PrepareFrame() 之前,就做了处理。
fCtrl.Bits.Adr = AdrCtrlOn;

接着 AdrAckReq 位段,在长期失联情况下会发送AdrAckReq确认链路。
fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &LoRaMacParams.ChannelsDatarate );

最后 F0ptsLen 位段,会在下面计算完FOpts之后更新。

  • 3.FHDR中的FCntLoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
    LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;

这个UpLinkCounter会在物理层发送完成后会按照协议进行累加。可以看到这是个32位计数器,按照协议规定,“如果采用32位帧计数,FCnt就对应计数器32位的16个低有效位”。

这是上行的,另外下行的也类似。

  • 4.FHDR中的FOpts

把MAC命令放入F0pts中,并且更新F0ptsLen。MAC命令,要么使用非零的FPort来和数据一起传输,要么使用FPort0来单独传输。


3.2.2 MACPayload中的FPort

这个是在应用层一直传递进去的,协议栈默认是用了端口2。这个是后期大家在应用时要调整的,类似于IP端口,不同的端口对应不同的服务。

3.3 MIC解析

在函数 PrepareFrame()的最后是调用LoRaMacComputeMic() 计算出整个MAC层的校验码。应用层这边基本不用改这边就暂时不细究了。

说明:LPWA物联网应用站(LPWAP.com)通过公开互联网收集、整理并转载有关LPWA物联网应用解决方案,以供广大LPWA应用开发者和爱好者共同学习交流和参考运用到实际生产生活中。本站所有转载的文章、图片、音频、视频等资料的版权归版权所有人所有并衷心感谢您的付出,由于本站采纳的非本站原创文章及图片等内容无法一一联系确认版权者,如果本网所选内容的文章原创作者认为其作品不宜放在本站,请及时通过以下留言功能通知我们采取适当措施,避免给双方造成不必要的经济损失。如果您希望保留文章在本站,但希望文章末尾提供对作者的致谢或者产品、网站交换链接的,也请将需求写入以下留言栏中,谢谢您的支持。让我们共同努力,打造万物互联的未来美好生活!

您的留言或需求: