4 MAC 帧格式
所有的LoRa 上下行消息都携带PHY负载(Payload),PHY负载以单字节的MAC头(MHDR)开始,紧跟着一个MAC负载(MACPayload),最终以4字节的完整性校验(MIC)结尾。
无线电PHY层:
PHY负载:
MAC负载:
FHDR:
4.1 MAC 层(PHYPayload)
MAC负载字段的最大长度(M)以不同区域不同特性地被定义在第6章节
4.2 MAC头(MHDR字段)
MAC头规定了消息类型(MType),以及根据LoRaWAN规范的主版本号(Major)对该帧进行编码。
更详细的最大负载长度定义在第6章节
对于Join-Accept帧,MIC字段是与负载加密而不是单独的一个字段
4.2.1 消息类型(Mtype 位字段)
LoRaWAN定义了8中不同的MAC消息类型:入网请求(join request),重新入网请求(rejoin request),入网许可(join accept), 非确认上行/下行帧 (unconfirmed data up/down) ,确认上行/下行帧,以及私有协议消息。
4.2.1.1 Join-request和join-accept消息
join-request、rejoin-request和join-accept都用于空中激活流程和漫游,具体详见第6.2章节。
4.2.1.2 Data messages
Data messages 用来传输MAC命令和应用数据,这两种数据也可以合并进一个消息里。确认帧(confirmed-data message)接收者应该应答,而非确认帧(unconfirmed-data message)则不需要应答。私有消息(Proprietary message) 用来处理非标准格式的消息,这不能和标准消息互通,但只能用在使用同一种私有协议的设备间。当终端设备或者网络服务器接收到未知的proprietarry message,应该选择丢弃掉不处理。
4.2.2 数据消息的主版本(Major字段)
ACK应答机制的时序图在第19章节有详细的描述。
4.3 数据消息的MAC Payload(MACPayload)
数据消息的MAC Payload包含:帧头(FHDR)、端口(FPort)、帧负载(FRMPayload),其中端口和帧负载是可选的。
4.3.1 帧头(FHDR)
帧头包含终端设备的短地址(DevAddr)、单字节的帧控制(FCtrl)、双字节的帧计数器(FCnt)和用来传输MAC指令的帧选项(FOpts,最多可以15个字节)。如果FOpts存在,那么这个字段应该使用NwkSEncKey密钥来加密,这在4.3.1.6章节有描述。
下行帧的FCtrl字段内容如下:
上行帧的FCtrl字段内容如下:
4.3.1.1 帧头的自适应数据速率控制(ADR, ADRACKReq in FCtrl)
LoRa网络允许终端设备单独使用所有的数据速率和发射功率。LoRaWAN利用这一特性来调节和优化静态终端设备的数据速率和发射功率。这被称为自适应数据速率(ADR),当这个位使能时,网络会优化使用最快的数据速率。
当无线信道衰减过快或过于频繁,ADR控制不应该使用。当网络服务器不能控制设备的数据速率时,设备的应用层应该控制该字段。在这种情况下推荐使用不同的数据速率。应用层都应该在既有的网络状况下尝试减少总的飞行时间。
当上行的ADR位使能,网络服务器将通过相应的MAC指令来控制终端设备的数据速率和发射功率。当ADR位失能,网络服务器不管收到的信号质量如何,也不会尝试去控制终端设备的数据速率和发射功率。网络服务器仍可以发送指令来修改频道掩码(channel mask)和帧重传次数(frame repetition)等参数。
当下行的ADR位使能,则告知终端设备,网络服务器可以发送ADR命令。这时设备可以使能/失能上行帧的ADR位。
当下行的ADR位失能,则告知终端设备,由于无线信道的快速变化,网络服务器暂时不能预估到最好的数据速率,在这种情况下设备可以:
- 失能上行ADR位,使用自身的上行数据速率策略
- 忽略网络服务器失能的这种情况(让上行ADR位保持使能),在没有下行ADR指令时,使用正常的数据速率递减。一个固定的终端设备应该采用这种典型的策略。
终端设备或网络服务器按实际需求来使能/失能ADR位。不管怎样,ADR机制都应该使用,以便帮助终端延长电池寿命和扩大网络容量。
缺省发射功率就是最大的发射功率,这关乎设备自身的能力以及不同区域管控的限制。设备应该使用这一功率,直到网络服务器通过LinkADRReq 这条MAC指令来要求减少功率。
如果终端设备收到网络优化的数据速率比自身缺省的数据速率高,或发射功率比自身缺省的发射功率低,那么它需要定期检查下网络仍能否收到上行帧。每次上行帧计数器都会增加(这是对于每条新的上行帧,而重传帧不再增加该计数器),设备增加一个ADR_ACK_CNT计数器。当ADR_ACK_LIMIT次上行帧(ADR_ACK_CNT >= ADR_ACK_LIMIT)没有收到下行回复时,将会使能ADR应答请求位(ADRACKReq)。网络服务器必须在下一次的ADR_ACK_DELAY帧之前回复一个下行帧,上行之后收到任何的下行帧都要重置ADR_ACK_CNT计数器。在终端设备的接收间隙收到的下行帧没有使能ACK位,表明网关仍然收到该设备的上行帧。如果在下一次的ADR_ACK_DELAY上行帧之前没有收到回复(换言之,在总的ADR_ACK_LIMIT + ADR_ACK_DELAY时间之前),终端设备必须切换到缺省发射功率(即最大发射功率)、以及可能的话切换到下一个更低的速率使得能够获得更远得传输距离,来重新连接网络。终端设备如果在每次ADR_ACK_DELAY到了之后依旧没收到ACK,那么就需要每次逐步降低数据速率。假如一旦设备到达了最低的速率,那么设备必须重新开启所有缺省的频道。
如果终端使用默认的数据速率和发射功率,那么ADRACKReq不应该设置,因为这种情况无法帮助提高链路距离。
下表提供了数据速率回退的例子,这里假设ADR_ACK_LIMIT和ADR_ACK_DELAY参数均位32。
4.3.1.2 消息应答位和应答流程(ACK in FCtrl)
当收到确认帧时,接收端应该回复一条应答帧(ACK位置位),如果发送端是终端设备,那么网络服务器就使用终端发送操作完成后打开的两个接收窗口的其中一个来进行回复。如果发送端是网关,终端就自行决定是否发送应答(参见下面的注意)。
应答消息只会在收到消息后回复,并且不会重发。
4.3.1.3 重传流程
下行帧:
下行确认或非确认帧不应该使用相同的帧计数器值来重传,在下行确认帧的情况,如果没有收到应答信号,会通知应用服务器来决定是否重新发送一条新的确认帧。
上行帧:
上行确认和非确认帧在没有收到有效的下行帧之前会重传"NbTrans"次(参照5.2章节),网络管理器使用NbTrans参数来控制节点上行的冗余,以此达到给定的服务质量。终端设备应该在重传时也像往常一样使用跳频。终端设备应该在每一个重传后进行等待,直到接收窗口过期。两次重传之间的时间间隔可以由终端设备自行决定,每一个设备都可以不相同。
如果设备收到相应的下行应答帧,那么应该停止再次重传确认上行帧。
不管什么时候,如果设备在RX1接收窗口内收到有效的单播下行帧, Class B和C类型的设备应该停止再次重传非确认上行帧。
不管什么时候,如果设备在RX1或者RX2 接收窗口内收到有效的下行帧, Class A类型的设备应该停止再次重传非确认上行帧。
如果网络服务器收到多于NbTrams次数的相同的上行帧,这有可能是受到了回复攻击,或者是设备端的故障,因此网络服务器不应该处理这些额外的帧。
4.3.1.4 帧挂起位(FPending in Fctrl, 只有下行有效)
帧挂起位(FPending)只在下行传输中使用,表明网络服务器还有挂起数据等待下发,因此要求终端设备尽快发送上行消息来打开另外的接收窗口。
FPending的准确用法在第19.3章节有详细的描述。
4.3.1.5 帧计数器(FCnt)
每个终端设备有三个计数器来跟踪数据帧的个数,一个是发给网络服务器的上行链路计数器(FCntUp),一个是网络服务器发送下行给设备的下行链路计数器(FCntDown)。
在下行方向,有两种不同的帧计数器机制存在;一个是单独计数器机制,即当设备运行在LoRaWAN的协议为1.0时,所有端口都使用相同的下行帧计数器FCntDown。另外一个是双计数器机制,即当设备运行在LoRaWAN的协议为1.1时,一个单独的NFCntDown在端口为0且没有FPort域时用作MAC通讯,另一个AFCntDown用在除了FPort为0以外的其他所有端口上。
在双计数器机制下,NFCntDown是由网络服务器来管理,而AFCntDown是由应用服务器来管理的。
无论何时,OTAA设备成功处理完join-accept消息后,终端设备端的上行帧计数器(FCntup)和相对于该设备的网络服务器端的帧计数器(NFCntDown 和 AFCntDown)都重置为0。
ABP设备在开始阶段就把它的所有帧计数器设置为0。对于ABP设备,帧计数器在设备使用期限应该从不重置。如果终端设备在使用期限因电量低而受到影响(例如更换电池),帧计数器在这种情况应该跟之前一致。
FcntUP随着每个上行帧增加。NFCntDown随着每个Fport为0时或者没有FPort域的下行帧增加。AFCntDown随着每个除了0端口以外的下行帧增加。在接收端,相对应的计数器与接收到的数值保持同步,这会让接收到的数值比当前数值有所增加,并且消息的MIC和使用相应的网络会话密钥算出来的MIC值一致。FCnt在多次重传确认或非确认帧时不会增加(看NbTrans的参数),网络服务器应该抛弃重传帧的应用负载并且只推送一次给应用服务器。
帧计数器为32位,FCnt字段对应于32位帧计数器的低16位(换言之,FCntUp对应的上行帧和AFCntDown/NFCntDown对应的下行帧)。
终端设备应该从不处理重传的相同的下行帧。因此重传应该在处理的时候忽略掉。