首页天道酬勤mac层的帧不同在哪里,MAC帧传输过程

mac层的帧不同在哪里,MAC帧传输过程

张世龙 05-12 20:17 105次浏览

前言不断翻译《LoRaWAN102》,即LoRaWAN协议规范V1.0.2版(2016年7月定稿)协议的各章。 除了译文外,我们还分析了LoRaWAN协议和源代码,单击此处可以查看帖子LoRa学习笔记_摘要。

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

作者twowinter,转载请参阅作者: http://blog.csdn.net/iotisan/

组织和分析了LoRaWAN第4章,主要论述了MAC帧格式,并介绍了所有相关字段。

千言万语组成一个词,哦,不,组成一个表。

数据标头DevAddrFCtrlFCntFOpts数据帧preamblephdrphdr _ crcmhdrfhdrfportfrmpayloadmiccrcmac层preamblephdrphdr _ crcmhdrmacpaylylac层帧格式是大家可以在手边看到的。 作为IoT名人,惠普ddx很抱歉不能提交稍微深入一点的信息增长。 所以,要分享一些协议设计水平的心得。

特别酷的ADR (速率自适应)机制

本章中最亮的是速率自适应机制,正是为LoRa网络定制的。 启用FCtrl的ADR位后,附近的信号节点会自动下降,而较远的信号节点较弱的节点会自动下降,如果不小心增大速率。 这将尽可能提高传输速率,并有效地提高网络容量。 我已经看到了很多制造商,将该协议的公知特征作为产品的卖点。

可以同时携带数据和命令的MAC帧

一般来说,APP应用程序不仅与数据有关,而且还与管理需要有关。 例如,基站检查节点的状态,或节点请求改变信道。 因此,可以通过在LoRaWAN协议设计中使用FOpts将数据和命令混合到一个MAC帧中来提高交互效率并有效地降低功耗。 这是寸土寸金,不,是寸库仑(电量单位)寸金物品在互联网上应用所必需的设计。

3源代码分析本章的处理基本上在\src\mac\LoRaMac.c上。 然后根据MAC帧格式的字段一次分析一个。

我们在33558www.Sina.com/lorawan的数据API中处理了MHDR。 此字段的内容很少,并且根据需要选择了消息类型是confirm还是unconfirm。

另外,管理API中的连接- req的消息类型。

具体来说,您可以看到两个函数: LoRaMacMcpsRequest (和LoRaMacMlmeRequest )。

3.1 MAC层MHDRMACPayload中的所有组帧都由名为PrepareFrame ()的函数处理,传递macHdr和macPayload中的fCtrl、FPort和FRMPayload

LoRaMacBuffer包含MACPayload的数据。 此变量的组框架和协议字段的定义是一一对应的。 MACPayload的组帧处理,在大的流程中分别处理连接和数据这两种帧,用两种情况进行划分。

为了便于阅读,提取了函数代码框架。

loramacstatus _ tprepareframe (loramacheader _ t * MAC HDR,LoRaMacFrameCtrl_t *fCtrl,uint8_t fPort,void * f bufffefert caseframe _ type _ data _ confirmed _ up : nodeackrequested=true; //intentionalfalltroughcaseframe _ type _ data _ unconfirmed _ up : f ctrl-bits.adrackreq=adrnextdr (f ctrl-) fCtrl-Bits.Ack=1; } loramacbuffer [ pktheaderlen ]=(loramacdevaddr )0xFF; loramacbuffer [ pktheaderlen ]=(loramacdevaddr8)0xFF; loramacbuffer [ pktheaderlen ]=(loramacdevaddr 16 )0xFF; loramacbuffer [ pktheaderlen ]=(loramacdevaddr 24 )0xFF; loramacbuffer [ pktheaderlen ]=f ctrl-value; LoRaMacBuffer[pktHeaderLen ]

= UpLinkCounter & 0xFF;LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;// Copy the MAC commands which must be re-send into the MAC command buffermemcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;if( ( payload != NULL ) && ( payloadSize > 0 ) ){if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) ){fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;// Update FCtrl field with new value of OptionsLengthLoRaMacBuffer[0x05] = fCtrl->Value;for( i = 0; i < MacCommandsBufferIndex; i++ ){LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];}}}else{if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) ){payloadSize = MacCommandsBufferIndex;payload = MacCommandsBuffer;framePort = 0;}}MacCommandsInNextTx = false;// Store MAC commands which must be re-send in case the device does not receive a downlink anymoreMacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );if( MacCommandsBufferToRepeatIndex > 0 ){MacCommandsInNextTx = true;}MacCommandsBufferIndex = 0;if( ( payload != NULL ) && ( payloadSize > 0 ) ){LoRaMacBuffer[pktHeaderLen++] = framePort;if( framePort == 0 ){LoRaMacPayloadEncrypt( (uint8_t* ) payload, payloadSize, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );}else{LoRaMacPayloadEncrypt( (uint8_t* ) payload, payloadSize, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );}memcpy1( LoRaMacBuffer + pktHeaderLen, LoRaMacPayload, payloadSize );}LoRaMacBufferPktLen = pktHeaderLen + payloadSize;LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;LoRaMacBufferPktLen += LORAMAC_MFR_LEN;break;case FRAME_TYPE_PROPRIETARY: ...// 省略break;default:return LORAMAC_STATUS_SERVICE_UNKNOWN;}return LORAMAC_STATUS_OK;}

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

3.2.1 MACPayload中的FHDR

1.FHDR中的DevAddr

LoRaMacBuffer[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中的FCnt

LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;

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

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

4.FHDR中的FOpts

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

// Copy the MAC commands which must be re-send into the MAC command buffermemcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;if( ( payload != NULL ) && ( payloadSize > 0 ) ){if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) ){fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;// Update FCtrl field with new value of OptionsLengthLoRaMacBuffer[0x05] = fCtrl->Value;for( i = 0; i < MacCommandsBufferIndex; i++ ){LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];}}}else{if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) ){payloadSize = MacCommandsBufferIndex;payload = MacCommandsBuffer;framePort = 0;}} 3.2.2 MACPayload中的FPort

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

3.3 MIC解析

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

End

That’s all.

何谓码元速率和信息速率,光合速率等于呼吸速率的含义 信号一般有哪几种分类与描述方法,质量小常识